diff --git a/client/rhel/spacewalk-client-tools/po/Makefile b/client/rhel/spacewalk-client-tools/po/Makefile index b7150d619c68..f460d4fe1ed3 100644 --- a/client/rhel/spacewalk-client-tools/po/Makefile +++ b/client/rhel/spacewalk-client-tools/po/Makefile @@ -34,7 +34,7 @@ INSTALL_DATA = ${INSTALL} -m 644 GMSGFMT = /usr/bin/msgfmt MSGFMT = /usr/bin/msgfmt -MSGMERGE = /usr/bin/msgmerge --previous --no-wrap +MSGMERGE = /usr/bin/msgmerge --previous INCLUDES = -I.. -I$(top_srcdir)/intl diff --git a/client/rhel/spacewalk-client-tools/spacewalk-client-tools.changes.mcalmer.remove-no-wrap-for-translations b/client/rhel/spacewalk-client-tools/spacewalk-client-tools.changes.mcalmer.remove-no-wrap-for-translations new file mode 100644 index 000000000000..24308de95dae --- /dev/null +++ b/client/rhel/spacewalk-client-tools/spacewalk-client-tools.changes.mcalmer.remove-no-wrap-for-translations @@ -0,0 +1 @@ +- Allow translation to wrap strings as weblate force it diff --git a/java/buildconf/checkstyle.xml b/java/buildconf/checkstyle.xml index 8f6dca76d3e3..364897402242 100644 --- a/java/buildconf/checkstyle.xml +++ b/java/buildconf/checkstyle.xml @@ -124,7 +124,9 @@ - + + + diff --git a/java/code/src/com/redhat/rhn/common/hibernate/AnnotationRegistry.java b/java/code/src/com/redhat/rhn/common/hibernate/AnnotationRegistry.java index cfdab5188f62..b56d0065ab93 100644 --- a/java/code/src/com/redhat/rhn/common/hibernate/AnnotationRegistry.java +++ b/java/code/src/com/redhat/rhn/common/hibernate/AnnotationRegistry.java @@ -14,12 +14,21 @@ */ package com.redhat.rhn.common.hibernate; +import com.redhat.rhn.domain.channel.AccessToken; import com.redhat.rhn.domain.channel.AppStream; import com.redhat.rhn.domain.channel.AppStreamApi; +import com.redhat.rhn.domain.channel.AppStreamApiKey; +import com.redhat.rhn.domain.channel.Channel; +import com.redhat.rhn.domain.channel.ChannelArch; import com.redhat.rhn.domain.channel.ChannelSyncFlag; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.cloudpayg.CloudRmtHost; import com.redhat.rhn.domain.cloudpayg.PaygCredentialsProduct; import com.redhat.rhn.domain.cloudpayg.PaygSshData; +import com.redhat.rhn.domain.common.ProvisionState; +import com.redhat.rhn.domain.config.ConfigChannel; +import com.redhat.rhn.domain.config.ConfigChannelType; +import com.redhat.rhn.domain.config.ConfigFile; import com.redhat.rhn.domain.contentmgmt.ContentEnvironment; import com.redhat.rhn.domain.contentmgmt.ContentFilter; import com.redhat.rhn.domain.contentmgmt.ContentProject; @@ -53,8 +62,17 @@ import com.redhat.rhn.domain.image.ImageStoreType; import com.redhat.rhn.domain.image.KiwiProfile; import com.redhat.rhn.domain.image.ProfileCustomDataValue; +import com.redhat.rhn.domain.kickstart.crypto.CryptoKey; +import com.redhat.rhn.domain.kickstart.crypto.CryptoKeyType; +import com.redhat.rhn.domain.kickstart.crypto.SslCryptoKey; import com.redhat.rhn.domain.notification.NotificationMessage; import com.redhat.rhn.domain.notification.UserNotification; +import com.redhat.rhn.domain.org.Org; +import com.redhat.rhn.domain.org.OrgAdminManagement; +import com.redhat.rhn.domain.org.OrgConfig; +import com.redhat.rhn.domain.org.TemplateString; +import com.redhat.rhn.domain.org.usergroup.UserGroupImpl; +import com.redhat.rhn.domain.org.usergroup.UserGroupMembers; import com.redhat.rhn.domain.product.ChannelTemplate; import com.redhat.rhn.domain.recurringactions.GroupRecurringAction; import com.redhat.rhn.domain.recurringactions.MinionRecurringAction; @@ -64,10 +82,13 @@ import com.redhat.rhn.domain.recurringactions.state.RecurringInternalState; import com.redhat.rhn.domain.recurringactions.type.RecurringHighstate; import com.redhat.rhn.domain.recurringactions.type.RecurringState; +import com.redhat.rhn.domain.rhnpackage.PackageArch; import com.redhat.rhn.domain.rhnpackage.PackageBreaks; +import com.redhat.rhn.domain.rhnpackage.PackageCapability; import com.redhat.rhn.domain.rhnpackage.PackageConflicts; import com.redhat.rhn.domain.rhnpackage.PackageEnhances; import com.redhat.rhn.domain.rhnpackage.PackageExtraTagsKeys; +import com.redhat.rhn.domain.rhnpackage.PackageFile; import com.redhat.rhn.domain.rhnpackage.PackageObsoletes; import com.redhat.rhn.domain.rhnpackage.PackagePreDepends; import com.redhat.rhn.domain.rhnpackage.PackageProvides; @@ -75,6 +96,7 @@ import com.redhat.rhn.domain.rhnpackage.PackageRequires; import com.redhat.rhn.domain.rhnpackage.PackageSuggests; import com.redhat.rhn.domain.rhnpackage.PackageSupplements; +import com.redhat.rhn.domain.role.RoleImpl; import com.redhat.rhn.domain.scc.SCCOrderItem; import com.redhat.rhn.domain.scc.SCCRegCacheItem; import com.redhat.rhn.domain.scc.SCCRepository; @@ -84,14 +106,37 @@ import com.redhat.rhn.domain.scc.SCCRepositoryNoAuth; import com.redhat.rhn.domain.scc.SCCRepositoryTokenAuth; import com.redhat.rhn.domain.scc.SCCSubscription; +import com.redhat.rhn.domain.server.Capability; +import com.redhat.rhn.domain.server.ClientCapability; +import com.redhat.rhn.domain.server.ClientCapabilityId; +import com.redhat.rhn.domain.server.CustomDataValue; +import com.redhat.rhn.domain.server.EntitlementServerGroup; +import com.redhat.rhn.domain.server.InstalledPackage; +import com.redhat.rhn.domain.server.ManagedServerGroup; +import com.redhat.rhn.domain.server.MinionServer; +import com.redhat.rhn.domain.server.MinionServerFactory; +import com.redhat.rhn.domain.server.MinionSummary; +import com.redhat.rhn.domain.server.NetworkInterface; import com.redhat.rhn.domain.server.Pillar; +import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.server.ServerAppStream; +import com.redhat.rhn.domain.server.ServerGroup; +import com.redhat.rhn.domain.server.ServerGroupType; +import com.redhat.rhn.domain.server.ServerPath; +import com.redhat.rhn.domain.server.ServerPathId; import com.redhat.rhn.domain.server.ansible.AnsiblePath; import com.redhat.rhn.domain.server.ansible.InventoryPath; import com.redhat.rhn.domain.server.ansible.PlaybookPath; import com.redhat.rhn.domain.server.virtualhostmanager.VirtualHostManagerNodeInfo; import com.redhat.rhn.domain.task.Task; +import com.redhat.rhn.domain.token.Token; import com.redhat.rhn.domain.token.TokenChannelAppStream; +import com.redhat.rhn.domain.user.AddressImpl; +import com.redhat.rhn.domain.user.StateChange; +import com.redhat.rhn.domain.user.legacy.PersonalInfo; +import com.redhat.rhn.domain.user.legacy.UserImpl; +import com.redhat.rhn.domain.user.legacy.UserInfo; +import com.redhat.rhn.manager.system.ServerGroupManager; import com.suse.cloud.domain.PaygDimensionComputation; import com.suse.cloud.domain.PaygDimensionResult; @@ -117,93 +162,139 @@ private AnnotationRegistry() { } private static final List> ANNOTATION_CLASSES = List.of( - ImageStore.class, - ImageStoreType.class, - DockerfileProfile.class, - KiwiProfile.class, - ImageProfile.class, - ProfileCustomDataValue.class, - DeltaImageInfo.class, - ImageFile.class, - ImageInfo.class, - ImageInfoCustomDataValue.class, - ImageOverview.class, - ImagePackage.class, - ImageRepoDigest.class, - VirtualHostManagerNodeInfo.class, - NotificationMessage.class, - UserNotification.class, - SCCRepository.class, - SCCSubscription.class, - SCCOrderItem.class, - ChannelTemplate.class, - SCCRepositoryAuth.class, - SCCRepositoryNoAuth.class, - SCCRepositoryBasicAuth.class, - SCCRepositoryTokenAuth.class, - SCCRepositoryCloudRmtAuth.class, - ContentProject.class, - ContentEnvironment.class, - ProjectSource.class, - SoftwareProjectSource.class, - ContentFilter.class, - ContentProjectFilter.class, - PackageFilter.class, - ErrataFilter.class, - ModuleFilter.class, - PtfFilter.class, - EnvironmentTarget.class, - SoftwareEnvironmentTarget.class, - ContentProjectHistoryEntry.class, - PackageExtraTagsKeys.class, - PackageProvides.class, - PackageRequires.class, - PackageRecommends.class, - PackageObsoletes.class, - PackageBreaks.class, - PackageSupplements.class, - PackageConflicts.class, - PackageSuggests.class, - PackagePreDepends.class, - PackageEnhances.class, - MinionRecurringAction.class, - GroupRecurringAction.class, - OrgRecurringAction.class, - MaintenanceSchedule.class, - MaintenanceCalendar.class, - SCCRegCacheItem.class, - AnsiblePath.class, - InventoryPath.class, - PlaybookPath.class, - Pillar.class, - CloudRmtHost.class, - PaygSshData.class, - PaygCredentialsProduct.class, - Task.class, - RecurringHighstate.class, - RecurringState.class, - RecurringConfigChannel.class, - RecurringInternalState.class, - InternalState.class, - PaygDimensionComputation.class, - PaygDimensionResult.class, - BaseCredentials.class, - CloudRMTCredentials.class, - RegistryCredentials.class, - ReportDBCredentials.class, - RHUICredentials.class, - SCCCredentials.class, - VHMCredentials.class, - ChannelSyncFlag.class, - ServerCoCoAttestationConfig.class, - ServerCoCoAttestationReport.class, - CoCoEnvironmentTypeConverter.class, - CoCoAttestationResult.class, - CoCoResultTypeConverter.class, - ServerAppStream.class, - AppStream.class, - AppStreamApi.class, - TokenChannelAppStream.class + // do not add class at the endi, but keep the alphabetical order + AccessToken.class, + AddressImpl.class, + AnsiblePath.class, + AppStreamApi.class, + AppStreamApiKey.class, + AppStream.class, + BaseCredentials.class, + Capability.class, + ChannelArch.class, + Channel.class, + ChannelSyncFlag.class, + ChannelTemplate.class, + ClientCapability.class, + ClientCapabilityId.class, + ClonedChannel.class, + CloudRMTCredentials.class, + CloudRmtHost.class, + CoCoAttestationResult.class, + CoCoEnvironmentTypeConverter.class, + CoCoResultTypeConverter.class, + ConfigChannel.class, + ConfigChannelType.class, + ConfigFile.class, + ContentEnvironment.class, + ContentFilter.class, + ContentProject.class, + ContentProjectFilter.class, + ContentProjectHistoryEntry.class, + CryptoKey.class, + CryptoKeyType.class, + CustomDataValue.class, + DeltaImageInfo.class, + DockerfileProfile.class, + EntitlementServerGroup.class, + EnvironmentTarget.class, + ErrataFilter.class, + GroupRecurringAction.class, + ImageFile.class, + ImageInfo.class, + ImageInfoCustomDataValue.class, + ImageOverview.class, + ImagePackage.class, + ImageProfile.class, + ImageRepoDigest.class, + ImageStore.class, + ImageStoreType.class, + InstalledPackage.class, + InternalState.class, + InventoryPath.class, + KiwiProfile.class, + MaintenanceCalendar.class, + MaintenanceSchedule.class, + ManagedServerGroup.class, + MinionRecurringAction.class, + MinionServer.class, + MinionServerFactory.class, + MinionSummary.class, + ModuleFilter.class, + NetworkInterface.class, + NotificationMessage.class, + OrgAdminManagement.class, + Org.class, + OrgConfig.class, + OrgRecurringAction.class, + PackageArch.class, + PackageBreaks.class, + PackageCapability.class, + PackageConflicts.class, + PackageEnhances.class, + PackageExtraTagsKeys.class, + PackageFile.class, + PackageFilter.class, + PackageObsoletes.class, + PackagePreDepends.class, + PackageProvides.class, + PackageRecommends.class, + PackageRequires.class, + PackageSuggests.class, + PackageSupplements.class, + PaygCredentialsProduct.class, + PaygDimensionComputation.class, + PaygDimensionResult.class, + PaygSshData.class, + PersonalInfo.class, + Pillar.class, + PlaybookPath.class, + ProfileCustomDataValue.class, + ProjectSource.class, + ProvisionState.class, + PtfFilter.class, + RecurringConfigChannel.class, + RecurringHighstate.class, + RecurringInternalState.class, + RecurringState.class, + RegistryCredentials.class, + ReportDBCredentials.class, + RHUICredentials.class, + RoleImpl.class, + SCCCredentials.class, + SCCOrderItem.class, + SCCRegCacheItem.class, + SCCRepositoryAuth.class, + SCCRepositoryBasicAuth.class, + SCCRepository.class, + SCCRepositoryCloudRmtAuth.class, + SCCRepositoryNoAuth.class, + SCCRepositoryTokenAuth.class, + SCCSubscription.class, + ServerAppStream.class, + Server.class, + ServerCoCoAttestationConfig.class, + ServerCoCoAttestationReport.class, + ServerGroup.class, + ServerGroupManager.class, + ServerGroupType.class, + ServerPath.class, + ServerPathId.class, + SoftwareEnvironmentTarget.class, + SoftwareProjectSource.class, + SslCryptoKey.class, + StateChange.class, + Task.class, + TemplateString.class, + TokenChannelAppStream.class, + Token.class, + UserGroupImpl.class, + UserGroupMembers.class, + UserImpl.class, + UserInfo.class, + UserNotification.class, + VHMCredentials.class, + VirtualHostManagerNodeInfo.class ); /** diff --git a/java/code/src/com/redhat/rhn/common/hibernate/EmptyVarcharInterceptor.java b/java/code/src/com/redhat/rhn/common/hibernate/EmptyVarcharInterceptor.java index bbc7dac81e34..233b3801cd48 100644 --- a/java/code/src/com/redhat/rhn/common/hibernate/EmptyVarcharInterceptor.java +++ b/java/code/src/com/redhat/rhn/common/hibernate/EmptyVarcharInterceptor.java @@ -17,7 +17,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.EmptyInterceptor; -import org.hibernate.type.StringType; import org.hibernate.type.Type; import java.io.Serializable; @@ -59,8 +58,7 @@ protected static boolean emptyStringToNull(Object entity, Serializable id, boolean modified = false; for (int i = 0; i < types.length; i++) { - // type is string (VARCHAR) and state is empty string - if ((types[i] instanceof StringType) && "".equals(state[i])) { + if ("".equals(state[i])) { if (LOG.isDebugEnabled()) { LOG.debug("Object {} is setting empty string {}", entity.getClass().getCanonicalName(), propertyNames[i]); diff --git a/java/code/src/com/redhat/rhn/common/messaging/SmtpMail.java b/java/code/src/com/redhat/rhn/common/messaging/SmtpMail.java index 06f115b2ef7f..7cfb99eb09e0 100644 --- a/java/code/src/com/redhat/rhn/common/messaging/SmtpMail.java +++ b/java/code/src/com/redhat/rhn/common/messaging/SmtpMail.java @@ -24,6 +24,7 @@ import org.apache.logging.log4j.Logger; import java.io.IOException; +import java.util.Date; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; @@ -142,6 +143,7 @@ public void setFrom(String from) { public void send() { try { + message.setSentDate(new Date()); Address[] addrs = message.getRecipients(RecipientType.TO); if (addrs == null || addrs.length == 0) { log.warn("Aborting mail message {}: No recipients", message.getSubject()); diff --git a/java/code/src/com/redhat/rhn/common/security/acl/Access.java b/java/code/src/com/redhat/rhn/common/security/acl/Access.java index 43a7baa17172..9a847782c85e 100644 --- a/java/code/src/com/redhat/rhn/common/security/acl/Access.java +++ b/java/code/src/com/redhat/rhn/common/security/acl/Access.java @@ -597,7 +597,7 @@ public boolean aclHasPtfRepositories(Map ctx, String[] params) { // Evaluate if any of the subscript channel refers to a PTF repository return server.getChannels() .stream() - .map(channel -> channel instanceof ClonedChannel ? channel.getOriginal() : channel) + .map(channel -> channel.asCloned().map(ClonedChannel::getOriginal).orElse(channel)) .flatMap(c -> c.getSources().stream()) .map(ContentSource::getSourceUrl) .anyMatch(url -> url.contains("/PTF/")); diff --git a/java/code/src/com/redhat/rhn/domain/BaseDomainHelper.java b/java/code/src/com/redhat/rhn/domain/BaseDomainHelper.java index 76dbefcc1223..9b4615b9fc03 100644 --- a/java/code/src/com/redhat/rhn/domain/BaseDomainHelper.java +++ b/java/code/src/com/redhat/rhn/domain/BaseDomainHelper.java @@ -20,6 +20,7 @@ import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; +import java.io.Serializable; import java.util.Date; import javax.persistence.Column; @@ -31,7 +32,7 @@ * DB table: web_contact */ @MappedSuperclass -public abstract class BaseDomainHelper { +public abstract class BaseDomainHelper implements Serializable { private Date created = new Date(); private Date modified; diff --git a/java/code/src/com/redhat/rhn/domain/action/test/ActionTypeTest.java b/java/code/src/com/redhat/rhn/domain/action/test/ActionTypeTest.java index aba0cade5c78..41dd04532dff 100644 --- a/java/code/src/com/redhat/rhn/domain/action/test/ActionTypeTest.java +++ b/java/code/src/com/redhat/rhn/domain/action/test/ActionTypeTest.java @@ -22,6 +22,7 @@ import com.redhat.rhn.testing.RhnBaseTestCase; import org.hibernate.Session; +import org.hibernate.type.StringType; import org.junit.jupiter.api.Test; /** @@ -70,7 +71,7 @@ public void testFindByLabel() throws Exception { private ActionType lookupByLabel(String label) { Session session = HibernateFactory.getSession(); return (ActionType) session.getNamedQuery("ActionType.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/audit/ScapFactory.java b/java/code/src/com/redhat/rhn/domain/audit/ScapFactory.java index 172fe46e9098..2023aec492f0 100644 --- a/java/code/src/com/redhat/rhn/domain/audit/ScapFactory.java +++ b/java/code/src/com/redhat/rhn/domain/audit/ScapFactory.java @@ -20,7 +20,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.criterion.Restrictions; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.List; import java.util.Map; @@ -77,8 +78,8 @@ public static void delete(XccdfTestResult tr) { public static void clearTestResult(long serverId, long actionId) { List results = getSession() .getNamedQuery("XccdfTestResult.findByActionId") - .setLong("serverId", serverId) - .setLong("actionId", actionId) + .setParameter("serverId", serverId, LongType.INSTANCE) + .setParameter("actionId", actionId, LongType.INSTANCE) .list(); results.forEach(ScapFactory::delete); } @@ -89,8 +90,7 @@ public static void clearTestResult(long serverId, long actionId) { * @return the {@link XccdfBenchmark} if any */ public static Optional lookupBenchmarkById(long benchmarkId) { - return Optional.ofNullable( - (XccdfBenchmark)getSession().get(XccdfBenchmark.class, benchmarkId)); + return Optional.ofNullable(getSession().get(XccdfBenchmark.class, benchmarkId)); } /** @@ -99,7 +99,7 @@ public static Optional lookupBenchmarkById(long benchmarkId) { * @return the {@link XccdfIdent} if any */ public static Optional lookupIdentById(long identId) { - return Optional.ofNullable((XccdfIdent)getSession().get(XccdfIdent.class, identId)); + return Optional.ofNullable(getSession().get(XccdfIdent.class, identId)); } /** @@ -108,20 +108,21 @@ public static Optional lookupIdentById(long identId) { * @return the {@link XccdfProfile} if any */ public static Optional lookupProfileById(long profileId) { - return Optional.ofNullable( - (XccdfProfile)getSession().get(XccdfProfile.class, profileId)); + return Optional.ofNullable(getSession().get(XccdfProfile.class, profileId)); } /** - * Find a {@link XccdfRuleResultType} by id. - * @param label label id - * @return the {@link XccdfRuleResultType} if any + * Queries an XccdfRuleResultType by its label. + * + * @param label the label of the XccdfRuleResultType + * @return optional of XccdfRuleResultType */ public static Optional lookupRuleResultType(String label) { - return getSession().createCriteria(XccdfRuleResultType.class) - .add(Restrictions.eq("label", label)) - .list() - .stream().findFirst(); + String sql = "SELECT * FROM rhnXccdfRuleResultType WHERE label = :label"; + XccdfRuleResultType result = + getSession().createNativeQuery(sql, XccdfRuleResultType.class) + .setParameter("label", label, StringType.INSTANCE).getResultStream().findFirst().orElse(null); + return Optional.ofNullable(result); } /** diff --git a/java/code/src/com/redhat/rhn/domain/channel/Channel.java b/java/code/src/com/redhat/rhn/domain/channel/Channel.java index 9029e7bc6735..8ae0c0ebff98 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/Channel.java +++ b/java/code/src/com/redhat/rhn/domain/channel/Channel.java @@ -38,6 +38,7 @@ import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -986,7 +987,7 @@ public Channel getOriginal() { * @return stream of channels */ public Stream originChain() { - return Stream.iterate(this, c -> c != null, c -> c.isCloned() ? c.getOriginal() : null); + return Stream.iterate(this, Objects::nonNull, c -> c.asCloned().map(ClonedChannel::getOriginal).orElse(null)); } /** diff --git a/java/code/src/com/redhat/rhn/domain/channel/ChannelFactory.java b/java/code/src/com/redhat/rhn/domain/channel/ChannelFactory.java index f98bf2a632cf..497978a2fa76 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ChannelFactory.java +++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelFactory.java @@ -23,7 +23,6 @@ import com.redhat.rhn.common.db.datasource.WriteMode; import com.redhat.rhn.common.hibernate.HibernateFactory; import com.redhat.rhn.domain.common.ChecksumType; -import com.redhat.rhn.domain.kickstart.KickstartableTree; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.rhnpackage.Package; import com.redhat.rhn.domain.scc.SCCRepository; @@ -34,11 +33,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.MatchMode; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; +import org.hibernate.query.Query; +import org.hibernate.type.IntegerType; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.ArrayList; import java.util.Arrays; @@ -51,6 +50,13 @@ import java.util.Optional; import java.util.Set; +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + /** * ChannelFactory */ @@ -392,8 +398,10 @@ public static List getAccessibleChannelsByOrg(Long orgid) { */ public static List getChannelArchitectures() { Session session = getSession(); - Criteria criteria = session.createCriteria(ChannelArch.class); - return criteria.list(); + String sql = "SELECT * FROM rhnChannelArch"; + List channelArchList + = session.createNativeQuery(sql, ChannelArch.class).getResultList(); + return channelArchList; } /** @@ -426,9 +434,10 @@ public static boolean isAccessibleByUser(String channelLabel, Long userId) { */ public static ChannelArch findArchByLabel(String label) { Session session = getSession(); - Criteria criteria = session.createCriteria(ChannelArch.class); - criteria.add(Restrictions.eq(LABEL, label)); - return (ChannelArch) criteria.uniqueResult(); + String sql = "SELECT * FROM rhnChannelArch WHERE label = :label"; + return session.createNativeQuery(sql, ChannelArch.class) + .setParameter(LABEL, label, StringType.INSTANCE) + .uniqueResult(); } /** @@ -451,9 +460,19 @@ public static Channel lookupByLabel(Org org, String label) { */ public static Channel lookupByLabel(String label) { Session session = getSession(); - Criteria c = session.createCriteria(Channel.class); - c.add(Restrictions.eq(LABEL, label)); - return (Channel) c.uniqueResult(); + String sql = """ + SELECT c.*, + cl.original_id, + CASE + WHEN cl.original_id IS NULL THEN 0 + ELSE 1 + END AS clazz_ + FROM rhnChannel c + LEFT JOIN rhnChannelCloned cl ON c.id = cl.id + WHERE c.label = :label"""; + return session.createNativeQuery(sql, Channel.class) + .setParameter(LABEL, label, StringType.INSTANCE) + .uniqueResult(); } /** @@ -796,8 +815,11 @@ public static ReleaseChannelMap lookupDefaultReleaseChannelMapForChannel(Channel * @return ChannelSyncFlag object containing all flag settings for a specfic channel */ public static ChannelSyncFlag lookupChannelReposyncFlag(Channel channel) { - return getSession().createQuery("from ChannelSyncFlag where channel = :channel", ChannelSyncFlag.class) - .setParameter("channel", channel).uniqueResult(); + return getSession() + .createNativeQuery( + "SELECT * FROM rhnChannelSyncFlag WHERE channel_id = :channel", ChannelSyncFlag.class) + .setParameter("channel", channel.getId(), LongType.INSTANCE) + .getSingleResult(); } /** @@ -1074,8 +1096,8 @@ public static Package lookupPackageByFilename(Channel channel, List pkgs = HibernateFactory.getSession() .getNamedQuery("Channel.packageByFileName") - .setString("pathlike", "%/" + fileName) - .setLong("channel_id", channel.getId()) + .setParameter("pathlike", "%/" + fileName, StringType.INSTANCE) + .setParameter("channel_id", channel.getId(), LongType.INSTANCE) .list(); if (pkgs.isEmpty()) { return null; @@ -1095,12 +1117,11 @@ public static Package lookupPackageByFilenameAndRange(Channel channel, String fileName, int headerStart, int headerEnd) { List pkgs = HibernateFactory.getSession() - .getNamedQuery("Channel.packageByFileNameAndRange") - .setString("pathlike", "%/" + fileName) - .setLong("channel_id", channel.getId()) - .setInteger("headerStart", headerStart) - .setInteger("headerEnd", headerEnd) - .list(); + .getNamedQuery("Channel.packageByFileNameAndRange") + .setParameter("pathlike", "%/" + fileName, StringType.INSTANCE) + .setParameter("channel_id", channel.getId(), LongType.INSTANCE) + .setParameter("headerStart", headerStart, IntegerType.INSTANCE) + .setParameter("headerEnd", headerEnd, IntegerType.INSTANCE).list(); if (pkgs.isEmpty()) { return null; } @@ -1116,10 +1137,12 @@ public static Package lookupPackageByFilenameAndRange(Channel channel, * @return true of the channels contains any distros */ public static boolean containsDistributions(Channel ch) { - Criteria criteria = getSession().createCriteria(KickstartableTree.class); - criteria.setProjection(Projections.rowCount()); - criteria.add(Restrictions.eq("channel", ch)); - return ((Number)criteria.uniqueResult()).intValue() > 0; + Session session = getSession(); + String sql + = "SELECT COUNT(*) FROM rhnKickstartableTree WHERE channel_id = :channelId"; + Number count = (Number) session.createNativeQuery(sql) + .setParameter("channelId", ch.getId(), LongType.INSTANCE).getSingleResult(); + return count.intValue() > 0; } /** @@ -1232,9 +1255,11 @@ public static List listCustomChannelsWithRepositories() { */ @SuppressWarnings("unchecked") public static List listVendorContentSources() { - Criteria criteria = getSession().createCriteria(ContentSource.class); - criteria.add(Restrictions.isNull("org")); - return criteria.list(); + Session session = getSession(); + String sql = "SELECT * FROM rhnContentSource WHERE org_id IS NULL"; + List contentSources + = session.createNativeQuery(sql, ContentSource.class).getResultList(); + return contentSources; } /** @@ -1243,23 +1268,42 @@ public static List listVendorContentSources() { * @return vendor content source if it exists */ public static ContentSource findVendorContentSourceByRepo(String repoUrl) { - Criteria criteria = getSession().createCriteria(ContentSource.class); - criteria.add(Restrictions.isNull("org")); + CriteriaBuilder cb = getSession().getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(ContentSource.class); + Root root = cq.from(ContentSource.class); + + // Create predicates for the query + Predicate isOrgNull = cb.isNull(root.get("org")); + Predicate sourceUrlPredicate; + if (repoUrl.contains("mirrorlist.centos.org") || repoUrl.contains("mirrors.rockylinux.org")) { - criteria.add(Restrictions.eq("sourceUrl", repoUrl)); + sourceUrlPredicate = cb.equal(root.get("sourceUrl"), repoUrl); } else { - String [] parts = repoUrl.split("\\?"); + String[] parts = repoUrl.split("\\?"); String repoUrlPrefix = parts[0]; if (parts.length > 1) { - criteria.add(Restrictions.like("sourceUrl", repoUrlPrefix + '?', - MatchMode.START)); + sourceUrlPredicate = cb.like(root.get("sourceUrl"), repoUrlPrefix + '%'); } else { - criteria.add(Restrictions.eq("sourceUrl", repoUrlPrefix)); + sourceUrlPredicate = cb.equal(root.get("sourceUrl"), repoUrlPrefix); } } - return (ContentSource) criteria.uniqueResult(); + + // Combine predicates + cq.where(cb.and(isOrgNull, sourceUrlPredicate)); + + // Create and execute the query + TypedQuery query = getSession().createQuery(cq); + ContentSource contentSource; + try { + contentSource = query.getSingleResult(); + } + catch (NoResultException e) { + contentSource = null; + } + + return contentSource; } /** @@ -1286,10 +1330,21 @@ public static List findContentSourceLikeUrl(String urlPart) { * @return channel product */ public static ChannelProduct findChannelProduct(String product, String version) { - Criteria criteria = getSession().createCriteria(ChannelProduct.class); - criteria.add(Restrictions.eq("product", product)); - criteria.add(Restrictions.eq("version", version)); - return (ChannelProduct) criteria.uniqueResult(); + Session session = getSession(); + String sql + = "SELECT * FROM rhnChannelProduct WHERE product = :product AND version = :version"; + Query query = session.createNativeQuery(sql, ChannelProduct.class); + query.setParameter("product", product, StringType.INSTANCE); + query.setParameter("version", version, StringType.INSTANCE); + try { + return query.getSingleResult(); + } + catch (NoResultException e) { + return null; + } + catch (Exception e) { + throw new RuntimeException("Error retrieving ChannelProduct", e); + } } /** diff --git a/java/code/src/com/redhat/rhn/domain/channel/ChannelFamilyFactory.java b/java/code/src/com/redhat/rhn/domain/channel/ChannelFamilyFactory.java index a7a1bdf7fbca..b371aba0c8d2 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ChannelFamilyFactory.java +++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelFamilyFactory.java @@ -24,9 +24,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.criterion.Restrictions; +import org.hibernate.query.Query; import java.util.ArrayList; import java.util.HashMap; @@ -34,6 +32,9 @@ import java.util.List; import java.util.Map; +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; + /** * ChannelFamilyFactory */ @@ -78,12 +79,27 @@ public static ChannelFamily lookupById(Long id) { * @return the ChannelFamily found */ public static ChannelFamily lookupByLabel(String label, Org org) { - Session session = getSession(); - Criteria c = session.createCriteria(ChannelFamily.class); - c.add(Restrictions.eq("label", label)); - c.add(Restrictions.or(Restrictions.eq("org", org), - Restrictions.isNull("org"))); - return (ChannelFamily) c.uniqueResult(); + String sql = "SELECT * FROM rhnChannelFamily WHERE label = :label AND (org_id = :org OR org_id IS NULL)"; + Query query = getSession().createNativeQuery(sql, ChannelFamily.class); + query.setParameter("label", label); + + // Handle org being null + if (org != null) { + query.setParameter("org", org.getId()); + } + else { + query.setParameter("org", -1); + } + + try { + return query.getSingleResult(); + } + catch (NoResultException e) { + return null; + } + catch (Exception e) { + throw new RuntimeException("Error retrieving ChannelFamily", e); + } } /** @@ -211,17 +227,32 @@ public static void save(PublicChannelFamily pcf) { * Lookup the List of ChannelFamily objects that are labled starting * with the passed in label param * @param label to query against - * @param orgIn owning the Channel. Pass in NULL if you want a NULL org channel + * @param org owning the Channel. Pass in NULL if you want a NULL org channel * @return List of Channel objects */ @SuppressWarnings("unchecked") - public static List lookupByLabelLike(String label, Org orgIn) { - Session session = getSession(); - Criteria c = session.createCriteria(ChannelFamily.class); - c.add(Restrictions.like("label", label + "%")); - c.add(Restrictions.or(Restrictions.eq("org", orgIn), - Restrictions.isNull("org"))); - return c.list(); + public static List lookupByLabelLike(String label, Org org) { + String sql = "SELECT * FROM rhnChannelFamily WHERE label LIKE :label AND (org_id = :org OR org_id IS NULL)"; + Query query = getSession().createNativeQuery(sql, ChannelFamily.class); + query.setParameter("label", label); + + // Handle org being null + if (org != null) { + query.setParameter("org", org.getId()); + } + else { + query.setParameter("org", -1); + } + + try { + return query.getResultList(); + } + catch (NoResultException e) { + return null; + } + catch (Exception e) { + throw new RuntimeException("Error retrieving ChannelFamily", e); + } } /** @@ -243,8 +274,9 @@ public static String getNameByLabel(String label) { */ @SuppressWarnings("unchecked") public static List getAllChannelFamilies() { - Session session = getSession(); - Criteria c = session.createCriteria(ChannelFamily.class); - return c.list(); + String sql = "SELECT * FROM rhnChannelFamily"; + TypedQuery query = + getSession().createNativeQuery(sql, ChannelFamily.class); + return query.getResultList(); } } diff --git a/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java b/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java index bb26abb21209..f1b72a7c3c54 100644 --- a/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java +++ b/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java @@ -22,6 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.Calendar; import java.util.Date; @@ -87,9 +89,12 @@ public static FileList lookupFileList(Long idIn, Org org) { Session session = null; //look for Kickstart data by id session = HibernateFactory.getSession(); - return (FileList) session.getNamedQuery("FileList.findByIdAndOrg") - .setLong("id", idIn) - .setLong("org_id", org.getId()) + return session.createNativeQuery(""" + SELECT * from rhnFileList + WHERE id = :id + and org_id = :org_id """, FileList.class) + .setParameter("id", idIn, LongType.INSTANCE) + .setParameter("org_id", org.getId(), LongType.INSTANCE) .uniqueResult(); } @@ -103,8 +108,10 @@ public static FileList lookupFileList(String labelIn, Org org) { Session session = null; //look for Kickstart data by label session = HibernateFactory.getSession(); - return (FileList) session.getNamedQuery("FileList.findByLabelAndOrg").setString("label", labelIn) - .setLong("org_id", org.getId()).uniqueResult(); + return (FileList) session.getNamedQuery("FileList.findByLabelAndOrg") + .setParameter("label", labelIn, StringType.INSTANCE) + .setParameter("org_id", org.getId(), LongType.INSTANCE) + .uniqueResult(); } /** @@ -150,7 +157,7 @@ public static void saveTinyUrl(TinyUrl urlIn) { public static TinyUrl lookupTinyUrl(String tokenIn) { Session session = HibernateFactory.getSession(); return (TinyUrl) session.getNamedQuery("TinyUrl.findByToken") - .setString("token", tokenIn) - .uniqueResult(); + .setParameter("token", tokenIn, StringType.INSTANCE) + .uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/domain/common/FileList.hbm.xml b/java/code/src/com/redhat/rhn/domain/common/FileList.hbm.xml index bcf59d0ecd5f..8f20591bb346 100644 --- a/java/code/src/com/redhat/rhn/domain/common/FileList.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/common/FileList.hbm.xml @@ -34,10 +34,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - - - diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigChannelListProcessor.java b/java/code/src/com/redhat/rhn/domain/config/ConfigChannelListProcessor.java index 3ccf6cc04221..fb978075f012 100644 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigChannelListProcessor.java +++ b/java/code/src/com/redhat/rhn/domain/config/ConfigChannelListProcessor.java @@ -20,13 +20,14 @@ import com.redhat.rhn.domain.user.User; import com.redhat.rhn.manager.configuration.ConfigurationManager; +import java.io.Serializable; import java.util.List; /** * * ConfigChannelListProcessor */ -public class ConfigChannelListProcessor { +public class ConfigChannelListProcessor implements Serializable { private void check(ConfigChannel cc) { if (cc == null) { diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java index 972987cee09a..42321210a151 100644 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java +++ b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java @@ -36,6 +36,8 @@ import org.hibernate.Session; import org.hibernate.criterion.Restrictions; import org.hibernate.query.Query; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.io.IOException; import java.io.InputStream; @@ -431,10 +433,9 @@ public static ConfigFile lookupConfigFileByChannelAndName(Long channel, Long nam Session session = HibernateFactory.getSession(); Query query = session.getNamedQuery("ConfigFile.findByChannelAndName") - .setLong("channel_id", channel) - .setLong("name_id", name) - .setLong("state_id", ConfigFileState.normal(). - getId()); + .setParameter("channel_id", channel, LongType.INSTANCE) + .setParameter("name_id", name, LongType.INSTANCE) + .setParameter("state_id", ConfigFileState.normal().getId(), LongType.INSTANCE); try { return query.uniqueResult(); } @@ -464,7 +465,7 @@ public static ConfigRevision lookupConfigRevisionById(Long id) { public static ConfigRevision lookupConfigRevisionByRevId(ConfigFile cf, Long revId) { Session session = HibernateFactory.getSession(); Query q = session.getNamedQuery("ConfigRevision.findByRevisionAndConfigFile"); - q.setLong("rev", revId); + q.setParameter("rev", revId, LongType.INSTANCE); q.setParameter("cf", cf); return q.uniqueResult(); } @@ -515,7 +516,7 @@ static ConfigChannelType lookupConfigChannelTypeByLabel(String label) { Session session = HibernateFactory.getSession(); return (ConfigChannelType) session.getNamedQuery("ConfigChannelType.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -532,7 +533,7 @@ static ConfigChannelType lookupConfigChannelTypeByLabel(String label) { static ConfigFileState lookupConfigFileStateByLabel(String label) { Session session = HibernateFactory.getSession(); return (ConfigFileState)session.getNamedQuery("ConfigFileState.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -546,7 +547,7 @@ static ConfigFileState lookupConfigFileStateByLabel(String label) { static ConfigFileType lookupConfigFileTypeByLabel(String label) { Session session = HibernateFactory.getSession(); return (ConfigFileType)session.getNamedQuery("ConfigFileType.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java b/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java index 1f8d1a196735..947ff381e4df 100644 --- a/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java +++ b/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java @@ -50,6 +50,8 @@ import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.query.Query; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.ArrayList; import java.util.Collection; @@ -396,7 +398,8 @@ public static ErrataFileType lookupErrataFileType(String label) { ErrataFileType retval; try { retval = (ErrataFileType) getSession().getNamedQuery("ErrataFileType.findByLabel") - .setString("label", label).setCacheable(true).uniqueResult(); + .setParameter("label", label, StringType.INSTANCE) + .setCacheable(true).uniqueResult(); } catch (HibernateException e) { throw new HibernateRuntimeException(e.getMessage(), e); @@ -413,9 +416,9 @@ public static ErrataFileType lookupErrataFileType(String label) { public static List lookupErrataFilesByErrataAndFileType(Long errataId, String fileType) { List retval; try { - Query q = getSession().getNamedQuery("ErrataFile.listByErrataAndFileType"); - q.setLong("errata_id", errataId); - q.setString("file_type", fileType.toUpperCase()); + Query q = getSession().getNamedQuery("ErrataFile.listByErrataAndFileType") + .setParameter("errata_id", errataId, LongType.INSTANCE) + .setParameter("file_type", fileType.toUpperCase(), StringType.INSTANCE); retval = q.list(); } catch (HibernateException e) { @@ -446,7 +449,7 @@ public static List lookupErratasByAdvisoryType(String advisoryType) { List retval; try { retval = getSession().getNamedQuery("Errata.findByAdvisoryType") - .setString("type", advisoryType) + .setParameter("type", advisoryType, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true).list(); } @@ -466,7 +469,8 @@ public static Errata lookupErrataById(Long id) { Errata retval; try { retval = (Errata) getSession().getNamedQuery("Errata.findById") - .setLong("id", id).uniqueResult(); + .setParameter("id", id, LongType.INSTANCE) + .uniqueResult(); } catch (HibernateException he) { log.error("Error loading ActionArchTypes from DB", he); @@ -485,7 +489,7 @@ public static Errata lookupErrataById(Long id) { public static List lookupVendorAndUserErrataByAdvisoryAndOrg(String advisory, Org org) { Session session = HibernateFactory.getSession(); return session.getNamedQuery("Errata.findVendorAnUserErrataByAdvisoryNameAndOrg") - .setParameter("advisory", advisory) + .setParameter("advisory", advisory, StringType.INSTANCE) .setParameter("org", org) .getResultList(); } @@ -499,7 +503,7 @@ public static List lookupVendorAndUserErrataByAdvisoryAndOrg(String advi public static Errata lookupByAdvisoryAndOrg(String advisory, Org org) { return (Errata) HibernateFactory.getSession() .getNamedQuery("Errata.findByAdvisoryNameAndOrg") - .setParameter("advisory", advisory) + .setParameter("advisory", advisory, StringType.INSTANCE) .setParameter("org", org) .uniqueResult(); } @@ -515,7 +519,7 @@ public static List lookupByAdvisoryId(String advisoryId, Org org) { List retval; try { retval = getSession().getNamedQuery("Errata.findByAdvisory") - .setParameter("advisory", advisoryId) + .setParameter("advisory", advisoryId, StringType.INSTANCE) .setParameter("org", org) .getResultList(); } @@ -712,8 +716,8 @@ public static List lookupByChannelBetweenDates(Org org, Channel channel, getNamedQuery("Errata.lookupByChannelBetweenDates") .setParameter("org", org) .setParameter("channel", channel) - .setParameter("start_date", startDate) - .setParameter("end_date", endDate) + .setParameter("start_date", startDate, StringType.INSTANCE) + .setParameter("end_date", endDate, StringType.INSTANCE) .list(); } @@ -731,8 +735,9 @@ public static List lookupByChannelBetweenDates(Org org, Channel channel, public static Optional lookupErrataFile(Long errataId, String filename) { Session session = HibernateFactory.getSession(); return session.getNamedQuery("ErrataFile.lookupByErrataAndPackage") - .setParameter("errata_id", errataId) - .setParameter("filename", filename).uniqueResultOptional(); + .setParameter("errata_id", errataId, LongType.INSTANCE) + .setParameter("filename", filename, StringType.INSTANCE) + .uniqueResultOptional(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java b/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java index 47eeb5709113..6b0f089ef6bc 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java +++ b/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java @@ -15,6 +15,7 @@ package com.redhat.rhn.domain.image; import com.redhat.rhn.common.util.StringUtil; +import com.redhat.rhn.domain.BaseDomainHelper; import com.redhat.rhn.domain.org.CustomDataKey; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.legacy.UserImpl; @@ -22,8 +23,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import java.util.Date; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -41,7 +40,7 @@ @Entity @Table(name = "suseProfileCustomDataValue") -public class ProfileCustomDataValue { +public class ProfileCustomDataValue extends BaseDomainHelper { private Long id; private ImageProfile profile; @@ -49,8 +48,6 @@ public class ProfileCustomDataValue { private String value; private User creator; private User lastModifier; - private Date created; - private Date modified; /** * @return Returns the Id @@ -101,20 +98,6 @@ public User getCreator() { public User getLastModifier() { return lastModifier; } - /** - * @return Returns the created. - */ - @Column(insertable = false, updatable = false) - public Date getCreated() { - return created; - } - /** - * @return Returns the modified. - */ - @Column(insertable = false, updatable = false) - public Date getModified() { - return modified; - } /** * @param idIn the id to set @@ -152,18 +135,6 @@ public void setCreator(User creatorIn) { public void setLastModifier(User lastModifierIn) { this.lastModifier = lastModifierIn; } - /** - * @param createdIn The created to set. - */ - public void setCreated(Date createdIn) { - this.created = createdIn; - } - /** - * @param modifiedIn The modified to set. - */ - public void setModified(Date modifiedIn) { - this.modified = modifiedIn; - } /** * {@inheritDoc} diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java index d5a9c4b0007a..6b6f002be548 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java @@ -484,12 +484,12 @@ public static CryptoKey lookupCryptoKey(String description, Org org) { Query query = null; if (org != null) { query = session.getNamedQuery("CryptoKey.findByDescAndOrg") - .setParameter("description", description) + .setParameter("description", description, StringType.INSTANCE) .setParameter(ORG_ID, org.getId(), LongType.INSTANCE); } else { query = session.getNamedQuery("CryptoKey.findByDescAndNullOrg") - .setParameter("description", description); + .setParameter("description", description, StringType.INSTANCE); } return query.uniqueResult(); } @@ -545,7 +545,8 @@ public static SslCryptoKey lookupSslCryptoKeyById(Long keyId, Org org) { //look for Kickstart data by id Session session = HibernateFactory.getSession(); Query query = session.getNamedQuery("SslCryptoKey.findByIdAndOrg"); - return query.setParameter("key_id", keyId, LongType.INSTANCE) + return query + .setParameter("key_id", keyId, LongType.INSTANCE) .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) .uniqueResult(); } @@ -575,7 +576,7 @@ public static KickstartableTree lookupKickstartTreeByLabel(String label, Org org Session session = HibernateFactory.getSession(); KickstartableTree retval = (KickstartableTree) session.getNamedQuery("KickstartableTree.findByLabelAndOrg") - .setParameter(LABEL, label) + .setParameter(LABEL, label, StringType.INSTANCE) .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) .uniqueResult(); // If we don't find by label + org then diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroup.java b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroup.java index a81b379b7ac0..4587d35bc281 100644 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroup.java +++ b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroup.java @@ -17,6 +17,7 @@ import com.redhat.rhn.domain.role.Role; +import java.io.Serializable; import java.util.Date; /** @@ -26,7 +27,7 @@ * * DB table: RHNUSERGROUP */ -public interface UserGroup { +public interface UserGroup extends Serializable { /** * Getter for id diff --git a/java/code/src/com/redhat/rhn/domain/product/SUSEProductFactory.java b/java/code/src/com/redhat/rhn/domain/product/SUSEProductFactory.java index ec2b8d4ef4b8..120728107fe6 100644 --- a/java/code/src/com/redhat/rhn/domain/product/SUSEProductFactory.java +++ b/java/code/src/com/redhat/rhn/domain/product/SUSEProductFactory.java @@ -26,14 +26,12 @@ import com.redhat.rhn.domain.scc.SCCRepository; import com.redhat.rhn.domain.server.InstalledProduct; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.Disjunction; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.Restrictions; +import org.hibernate.query.Query; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.Collection; import java.util.Comparator; @@ -46,9 +44,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import javax.persistence.NoResultException; /** * SUSEProductFactory - the class used to fetch and store @@ -167,12 +163,16 @@ public static void remove(SUSEProduct product) { @SuppressWarnings("unchecked") public static void removeAllExcept(Collection products) { if (!products.isEmpty()) { - Collection ids = products.stream().map(SUSEProduct::getId).toList(); + List ids = products.stream().map(SUSEProduct::getId).toList(); - Criteria c = getSession().createCriteria(SUSEProduct.class); - c.add(Restrictions.not(Restrictions.in("id", ids))); + List productIds = getSession().createNativeQuery(""" + SELECT * from suseProducts + WHERE id NOT IN (:ids) + """, SUSEProduct.class) + .setParameterList("ids", ids, LongType.INSTANCE) + .getResultList(); - for (SUSEProduct product : (List) c.list()) { + for (SUSEProduct product : productIds) { remove(product); } } @@ -424,41 +424,56 @@ public static void remove(ChannelTemplate productRepo) { public static SUSEProduct findSUSEProduct(String name, String version, String release, String arch, boolean imprecise) { - Criteria c = getSession().createCriteria(SUSEProduct.class); - c.add(Restrictions.eq("name", name.toLowerCase())); + StringBuilder sqlQuery = new StringBuilder("SELECT * FROM suseProducts WHERE LOWER(name) = :name"); - Disjunction versionCriterion = Restrictions.disjunction(); - if (imprecise || version == null) { - versionCriterion.add(Restrictions.isNull("version")); + if (version == null) { + sqlQuery.append(" AND version is NULL"); } - if (version != null) { - versionCriterion.add(Restrictions.eq("version", version.toLowerCase())); + else if (imprecise) { + sqlQuery.append(" AND (version IS NULL OR LOWER(version) = :version)"); + } + else { // (!imprecise) + sqlQuery.append(" AND LOWER(version) = :version"); } - c.add(versionCriterion); - Disjunction releaseCriterion = Restrictions.disjunction(); - if (imprecise || release == null) { - releaseCriterion.add(Restrictions.isNull("release")); + if (release == null) { + sqlQuery.append(" AND release is NULL"); } - if (release != null) { - releaseCriterion.add(Restrictions.eq("release", release.toLowerCase())); + else if (imprecise) { + sqlQuery.append(" AND (release IS NULL OR LOWER(release) = :release)"); + } + else { // (!imprecise) + sqlQuery.append(" AND LOWER(release) = :release"); } - c.add(releaseCriterion); - Disjunction archCriterion = Restrictions.disjunction(); - if (imprecise || arch == null) { - archCriterion.add(Restrictions.isNull("arch")); + PackageArch parch = PackageFactory.lookupPackageArchByLabel(arch); + Long archTypeId = (long) -1; + if (parch != null) { + archTypeId = parch.getId(); } - if (arch != null) { - archCriterion.add(Restrictions.eq("arch", - PackageFactory.lookupPackageArchByLabel(arch))); + if (imprecise || archTypeId == -1) { + sqlQuery.append(" AND (arch_type_id IS NULL OR arch_type_id = :arch)"); + } + else { + sqlQuery.append(" AND arch_type_id = :arch"); + } + + // Add ordering + sqlQuery.append(" ORDER BY name ASC, version ASC, release ASC, arch_type_id ASC"); + + // Execute the query + Query query = getSession().createNativeQuery(sqlQuery.toString(), SUSEProduct.class) + .setParameter("name", name.toLowerCase(), StringType.INSTANCE) + .setParameter("arch", archTypeId, LongType.INSTANCE); + if (version != null) { + query.setParameter("version", version.toLowerCase(), StringType.INSTANCE); + } + if (release != null) { + query.setParameter("release", release.toLowerCase(), StringType.INSTANCE); } - c.add(archCriterion); - c.addOrder(Order.asc("name")).addOrder(Order.asc("version")) - .addOrder(Order.asc("release")).addOrder(Order.asc("arch")); - List result = c.list(); + List result = query.getResultList(); return result.isEmpty() ? null : result.get(0); } @@ -479,10 +494,17 @@ public static SUSEProduct getProductById(Long id) { * @return SUSE product for given productId */ public static SUSEProduct lookupByProductId(long productId) { - Session session = getSession(); - Criteria c = session.createCriteria(SUSEProduct.class); - c.add(Restrictions.eq("productId", productId)); - return (SUSEProduct) c.uniqueResult(); + try { + return getSession().createNativeQuery(""" + SELECT * from suseProducts + WHERE product_id = :product + """, SUSEProduct.class) + .setParameter("product", productId, LongType.INSTANCE) + .getSingleResult(); + } + catch (NoResultException e) { + return null; + } } /** @@ -490,8 +512,8 @@ public static SUSEProduct lookupByProductId(long productId) { * @return map of SUSE products with productId as key */ public static Map productsByProductIds() { - Session session = getSession(); - return session.createQuery("from com.redhat.rhn.domain.product.SUSEProduct", SUSEProduct.class) + return getSession().createNativeQuery("SELECT * from suseProducts ", SUSEProduct.class) + .getResultList() .stream() .collect(Collectors.toMap(SUSEProduct::getProductId, p -> p)); } @@ -501,11 +523,11 @@ public static Map productsByProductIds() { * @return SUSEProductExtensions which are recommended */ public static List allRecommendedExtensions() { - CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery criteria = builder.createQuery(SUSEProductExtension.class); - Root root = criteria.from(SUSEProductExtension.class); - criteria.where(builder.equal(root.get("recommended"), true)); - return getSession().createQuery(criteria).getResultList(); + return getSession().createNativeQuery(""" + SELECT * from suseProductExtension + WHERE recommended = 'Y' + """, SUSEProductExtension.class) + .getResultList(); } /** @@ -529,9 +551,8 @@ public static List allRecommendedExtensionsOfRoot(SUSEProd */ @SuppressWarnings("unchecked") public static List findAllSUSEProductChannels() { - Session session = getSession(); - Criteria c = session.createCriteria(SUSEProductChannel.class); - return c.list(); + return getSession().createNativeQuery("SELECT * from SUSEProductChannel", SUSEProductChannel.class) + .getResultList(); } /** @@ -544,18 +565,20 @@ public static List findAllSUSEProductChannels() { public static Optional findSUSEProductExtension(SUSEProduct root, SUSEProduct base, SUSEProduct ext) { - Session session = getSession(); - - Criteria c = session.createCriteria(SUSEProductExtension.class) - .add(Restrictions.eq("rootProduct", root)) - .add(Restrictions.eq("baseProduct", base)) - .add(Restrictions.eq("extensionProduct", ext)); - SUSEProductExtension result = (SUSEProductExtension) c.uniqueResult(); - if (result == null) { - return Optional.empty(); + try { + return Optional.ofNullable(getSession().createNativeQuery(""" + SELECT * from suseProductExtension + WHERE base_pdid = :baseid + AND ext_pdid = :extid + AND root_pdid = :rootid + """, SUSEProductExtension.class) + .setParameter("baseid", base.getId(), LongType.INSTANCE) + .setParameter("extid", ext.getId(), LongType.INSTANCE) + .setParameter("rootid", root.getId(), LongType.INSTANCE) + .getSingleResult()); } - else { - return Optional.of(result); + catch (NoResultException e) { + return Optional.empty(); } } @@ -563,11 +586,11 @@ public static Optional findSUSEProductExtension(SUSEProduc * Find all {@link SUSEProductExtension}. * @return list of product extension */ - @SuppressWarnings("unchecked") public static List findAllSUSEProductExtensions() { Session session = getSession(); - Criteria c = session.createCriteria(SUSEProductExtension.class); - return c.list(); + return getSession().createNativeQuery("SELECT * from suseProductExtension", SUSEProductExtension.class) + .getResultList(); + } /** @@ -580,7 +603,8 @@ public static List findAllExtensionProductsForRootOf(SUSEProduct ba Map params = new HashMap<>(); params.put("baseId", base.getId()); params.put("rootId", root.getId()); - return singleton.listObjectsByNamedQuery("SUSEProductExtension.findAllExtensionProductsForRootOf", params); + return singleton.listObjectsByNamedQuery( + "SUSEProductExtension.findAllExtensionProductsForRootOf", params); } /** @@ -591,12 +615,14 @@ public static List findAllExtensionProductsForRootOf(SUSEProduct ba */ @SuppressWarnings("unchecked") public static List findAllProductExtensionsOf(SUSEProduct product, SUSEProduct root) { - Session session = getSession(); - - Criteria c = session.createCriteria(SUSEProductExtension.class) - .add(Restrictions.eq("rootProduct", root)) - .add(Restrictions.eq("baseProduct", product)); - return c.list(); + return getSession().createNativeQuery(""" + SELECT * from suseProductExtension + WHERE base_pdid = :baseid + AND root_pdid = :rootid + """, SUSEProductExtension.class) + .setParameter("baseid", product.getId(), LongType.INSTANCE) + .setParameter("rootid", root.getId(), LongType.INSTANCE) + .getResultList(); } /** @@ -638,7 +664,10 @@ public static List findAllRootProductsOf(SUSEProduct prd) { */ @SuppressWarnings("unchecked") public static List findAllSUSEProducts() { - return getSession().createCriteria(SUSEProduct.class).list(); + return getSession().createNativeQuery(""" + SELECT * from suseProducts + """, SUSEProduct.class) + .getResultList(); } /** @@ -668,21 +697,53 @@ public static List findAllExtensionsOfRootProduct(SUSEProduct root) public static Optional findInstalledProduct(String name, String version, String release, PackageArch arch, boolean isBaseProduct) { - Criteria c = getSession().createCriteria(InstalledProduct.class); - c.add(Restrictions.eq("name", name)); - c.add(Restrictions.eq("version", version)); - if (StringUtils.isEmpty(release)) { - c.add(Restrictions.isNull("release")); + + StringBuilder sqlQuery = new StringBuilder("SELECT * FROM suseInstalledProduct WHERE LOWER(name) = :name"); + + if (version == null) { + sqlQuery.append(" AND (version IS NULL OR LOWER(version) = :version"); + version = ""; + } + else { + sqlQuery.append(" AND LOWER(version) = :version"); + } + + + if (release == null) { + sqlQuery.append(" AND (release IS NULL OR LOWER(release) = :release)"); + release = ""; + } + else { + sqlQuery.append(" AND LOWER(release) = :release"); + } + + Long archTypeId = (long) -1; + if (arch != null) { + archTypeId = arch.getId(); + } + sqlQuery.append(" AND arch_type_id = :arch"); + + if (isBaseProduct) { + sqlQuery.append(" AND is_baseproduct = 'Y'"); } else { - c.add(Restrictions.eq("release", release)); + sqlQuery.append(" AND is_baseproduct = 'N'"); } - c.add(Restrictions.eq("arch", arch)); - c.add(Restrictions.eq("baseproduct", isBaseProduct)); - c.addOrder(Order.asc("name")).addOrder(Order.asc("version")) - .addOrder(Order.asc("release")).addOrder(Order.asc("arch")); - return c.list().stream().findFirst(); + + // Add ordering + sqlQuery.append(" ORDER BY name ASC, version ASC, release ASC, arch_type_id ASC"); + + // Execute the query + Query query = getSession().createNativeQuery(sqlQuery.toString(), InstalledProduct.class) + .setParameter("name", name.toLowerCase(), StringType.INSTANCE) + .setParameter("version", version.toLowerCase(), StringType.INSTANCE) + .setParameter("release", release.toLowerCase(), StringType.INSTANCE) + .setParameter("arch", archTypeId, LongType.INSTANCE); + + List result = query.getResultList(); + + return result.stream().findFirst(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/recurringactions/RecurringAction.java b/java/code/src/com/redhat/rhn/domain/recurringactions/RecurringAction.java index bd70ea85bf74..e697119bdb39 100644 --- a/java/code/src/com/redhat/rhn/domain/recurringactions/RecurringAction.java +++ b/java/code/src/com/redhat/rhn/domain/recurringactions/RecurringAction.java @@ -23,6 +23,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import org.hibernate.annotations.Type; import java.util.List; @@ -204,7 +205,7 @@ public void setCronExpr(String cronExprIn) { * @return active - if action is active */ @Column - @org.hibernate.annotations.Type(type = "yes_no") + @Type(type = "yes_no") public boolean isActive() { return active; } diff --git a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java index b3e1c1399918..01acda7555a7 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java @@ -19,6 +19,8 @@ import com.redhat.rhn.common.hibernate.HibernateFactory; import org.hibernate.Session; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.sql.Types; import java.util.HashMap; @@ -95,8 +97,9 @@ public static PackageEvr lookupOrCreatePackageEvr(String e, String v, String r, */ public static PackageEvr lookupPackageEvrById(Long id) { Session session = HibernateFactory.getSession(); - return (PackageEvr) session.getNamedQuery("PackageEvr.findById").setLong( - "id", id).uniqueResult(); + return (PackageEvr) session.getNamedQuery("PackageEvr.findById") + .setParameter("id", id, LongType.INSTANCE) + .uniqueResult(); } /** @@ -111,10 +114,10 @@ public static Optional lookupPackageEvrByEvr( String epoch, String version, String release, PackageType type) { Session session = HibernateFactory.getSession(); return (Optional) session.getNamedQuery("PackageEvr.lookupByEvr") - .setString("e_in", epoch) - .setString("v_in", version) - .setString("r_in", release) - .setString("t_in", type.getDbString()) + .setParameter("e_in", epoch, StringType.INSTANCE) + .setParameter("v_in", version, StringType.INSTANCE) + .setParameter("r_in", release, StringType.INSTANCE) + .setParameter("t_in", type.getDbString(), StringType.INSTANCE) .uniqueResultOptional(); } diff --git a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java index 196bd19a81c2..d65896e104ee 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java @@ -33,6 +33,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.sql.Types; import java.util.ArrayList; @@ -300,7 +302,8 @@ public static long lookupOrCreatePackageNameId(String name) { */ public static PackageName lookupPackageName(Long id) { return (PackageName) HibernateFactory.getSession().getNamedQuery("PackageName.findById") - .setLong("id", id).uniqueResult(); + .setParameter("id", id, LongType.INSTANCE) + .uniqueResult(); } /** @@ -313,7 +316,8 @@ public static PackageName lookupPackageName(Long id) { */ public static PackageName lookupPackageName(String pn) { return (PackageName) HibernateFactory.getSession().getNamedQuery("PackageName.findByName") - .setString("name", pn).uniqueResult(); + .setParameter("name", pn, StringType.INSTANCE) + .uniqueResult(); } /** @@ -325,7 +329,8 @@ public static PackageName lookupPackageName(String pn) { @SuppressWarnings("unchecked") public static List lookupOrphanPackages(Org org) { return HibernateFactory.getSession().getNamedQuery("Package.listOrphans") - .setParameter("org", org).list(); + .setParameter("org", org) + .list(); } /** @@ -342,9 +347,13 @@ public static List lookupByNevra(Org org, String name, String version, String release, String epoch, PackageArch arch) { List packages = HibernateFactory.getSession().getNamedQuery( - "Package.lookupByNevra").setParameter("org", org).setString("name", name) - .setString("version", version).setString("release", release).setParameter( - "arch", arch).list(); + "Package.lookupByNevra") + .setParameter("org", org) + .setParameter("name", name, StringType.INSTANCE) + .setParameter("version", version, StringType.INSTANCE) + .setParameter("release", release, StringType.INSTANCE) + .setParameter("arch", arch) + .list(); if (epoch == null || packages.size() < 2) { return packages; @@ -365,9 +374,9 @@ public static List lookupByNevraIds(Org org, long nameId, long evrId, l return HibernateFactory.getSession().createNamedQuery("Package.lookupByNevraIds", Package.class) .setParameter("org", org) - .setParameter("nameId", nameId) - .setParameter("evrId", evrId) - .setParameter("archId", archId) + .setParameter("nameId", nameId, LongType.INSTANCE) + .setParameter("evrId", evrId, LongType.INSTANCE) + .setParameter("archId", archId, LongType.INSTANCE) .list(); } @@ -388,12 +397,12 @@ public static Package lookupByChannelLabelNevraCs(String channel, String name, @SuppressWarnings("unchecked") List packages = HibernateFactory.getSession() .getNamedQuery("Package.lookupByChannelLabelNevraCs") - .setString("channel", channel) - .setString("name", name) - .setString("version", version) - .setString("release", release) - .setString("arch", arch) - .setString("checksum", checksum.orElse(null)) + .setParameter("channel", channel, StringType.INSTANCE) + .setParameter("name", name, StringType.INSTANCE) + .setParameter("version", version, StringType.INSTANCE) + .setParameter("release", release, StringType.INSTANCE) + .setParameter("arch", arch, StringType.INSTANCE) + .setParameter("checksum", checksum.orElse(null), StringType.INSTANCE) .list(); if (packages.isEmpty()) { diff --git a/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTest.java b/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTest.java index 9c7dcd4bb866..da175648a306 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTest.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTest.java @@ -80,8 +80,8 @@ public void testProfileEquals() throws Exception { public static Profile lookupByIdAndOrg(Long id, Org org) { Session session = HibernateFactory.getSession(); return (Profile) session.getNamedQuery("Profile.findByIdAndOrg") - .setLong("id", id) - .setLong("org_id", org.getId()) + .setParameter("id", id) + .setParameter("org_id", org.getId()) .uniqueResult(); } @@ -126,8 +126,8 @@ public void testCompatibleServer() throws Exception { session.flush(); Query qry = session.getNamedQuery("Profile.compatibleWithServer"); - qry.setLong("sid", server.getId()); - qry.setLong("org_id", user.getOrg().getId()); + qry.setParameter("sid", server.getId()); + qry.setParameter("org_id", user.getOrg().getId()); List list = qry.list(); assertNotNull(list, "List is null"); assertFalse(list.isEmpty(), "List is empty"); diff --git a/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTypeTest.java b/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTypeTest.java index 5ab04b4044ad..a813bee16b5d 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTypeTest.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/profile/test/ProfileTypeTest.java @@ -23,6 +23,7 @@ import com.redhat.rhn.testing.RhnBaseTestCase; import org.hibernate.Session; +import org.hibernate.type.StringType; import org.junit.jupiter.api.Test; /** @@ -73,7 +74,7 @@ public void testFindByLabel() throws Exception { public static ProfileType lookupByLabel(String label) { Session session = HibernateFactory.getSession(); return (ProfileType) session.getNamedQuery("ProfileType.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java b/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java index 6f4ad8e277b5..9be5cdf19589 100644 --- a/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java +++ b/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java @@ -19,6 +19,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; /** * RoleFactory @@ -56,7 +58,7 @@ protected Logger getLogger() { public static Role lookupById(Long id) { Session session = HibernateFactory.getSession(); return (Role) session.getNamedQuery("Role.findById") - .setLong("id", id) + .setParameter("id", id, LongType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -70,7 +72,7 @@ public static Role lookupById(Long id) { public static Role lookupByLabel(String name) { Session session = HibernateFactory.getSession(); return (Role) session.getNamedQuery("Role.findByLabel") - .setString("label", name) + .setParameter("label", name, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/scc/SCCCachingFactory.java b/java/code/src/com/redhat/rhn/domain/scc/SCCCachingFactory.java index 6f24b45f0377..878ef5735e33 100644 --- a/java/code/src/com/redhat/rhn/domain/scc/SCCCachingFactory.java +++ b/java/code/src/com/redhat/rhn/domain/scc/SCCCachingFactory.java @@ -35,9 +35,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.criterion.Restrictions; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.math.BigDecimal; import java.util.ArrayList; @@ -49,14 +48,13 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaDelete; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import javax.persistence.NoResultException; /** * Factory class for populating and reading from SCC caching tables. diff --git a/java/code/src/com/redhat/rhn/domain/scc/SCCRegCacheItem.java b/java/code/src/com/redhat/rhn/domain/scc/SCCRegCacheItem.java index 8f1785b38f66..81dbcfac9c92 100644 --- a/java/code/src/com/redhat/rhn/domain/scc/SCCRegCacheItem.java +++ b/java/code/src/com/redhat/rhn/domain/scc/SCCRegCacheItem.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; +import org.hibernate.annotations.Type; import java.security.SecureRandom; import java.util.Date; @@ -178,7 +179,7 @@ public Optional getOptCredentials() { * @return true when updating the registration at SCC is required, otherwise false */ @Column(name = "scc_reg_required") - @org.hibernate.annotations.Type(type = "yes_no") + @Type(type = "yes_no") public boolean isSccRegistrationRequired() { return sccRegistrationRequired; } diff --git a/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java b/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java index 4b91353cfe68..5ce796230fdf 100644 --- a/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java @@ -27,25 +27,19 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.CriteriaSpecification; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; import org.hibernate.query.Query; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.math.BigDecimal; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import javax.persistence.NoResultException; /** * MinionFactory - the singleton class used to fetch and store @@ -61,11 +55,16 @@ public class MinionServerFactory extends HibernateFactory { * @return the Server found */ public static List lookupByOrg(Long orgId) { - return HibernateFactory.getSession() - .createCriteria(MinionServer.class) - .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) - .add(Restrictions.eq("org.id", orgId)) - .list(); + return getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE + s.server_id IN + (SELECT id FROM rhnServer WHERE org_id = :org) + """, MinionServer.class) + .setParameter("org", orgId, LongType.INSTANCE) + .getResultList(); } /** @@ -91,10 +90,23 @@ protected Logger getLogger() { * @return server corresponding to the given machine_id */ public static Optional findByMachineId(String machineId) { - Session session = getSession(); - Criteria criteria = session.createCriteria(MinionServer.class); - criteria.add(Restrictions.eq("machineId", machineId)); - return Optional.ofNullable((MinionServer) criteria.uniqueResult()); + Optional minion; + try { + minion = Optional.ofNullable(getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE + s.server_id IN + (SELECT id FROM rhnServer WHERE machine_id = :machineId) + """, MinionServer.class) + .setParameter("machineId", machineId, StringType.INSTANCE) + .uniqueResult()); + } + catch (NoResultException e) { + minion = Optional.empty(); + } + return minion; } /** @@ -104,10 +116,19 @@ public static Optional findByMachineId(String machineId) { * @return server corresponding to the given machine_id */ public static Optional findByMinionId(String minionId) { - Session session = getSession(); - Criteria criteria = session.createCriteria(MinionServer.class); - criteria.add(Restrictions.eq("minionId", minionId)); - return Optional.ofNullable((MinionServer) criteria.uniqueResult()); + Optional minion; + try { + minion = Optional.ofNullable(getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id where s.minion_id = :minion + """, MinionServer.class) + .setParameter("minion", minionId, StringType.INSTANCE).getSingleResult()); + } + catch (NoResultException e) { + minion = Optional.empty(); + } + return minion; } /** @@ -117,9 +138,12 @@ public static Optional findByMinionId(String minionId) { */ @SuppressWarnings("unchecked") public static List listMinions() { - return getSession().createCriteria(MinionServer.class) - .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) - .list(); + return getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE s.minion_id IS NOT NULL""", MinionServer.class) + .getResultList(); } /** @@ -129,11 +153,14 @@ public static List listMinions() { * @return a list of minions ids belonging to the given organization */ public static List findMinionIdsByOrgId(Long orgId) { - return getSession().createCriteria(MinionServer.class) - .setProjection(Projections.property("minionId")) - .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) - .add(Restrictions.eq("org.id", orgId)) - .list(); + return getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE s.org_id = :org + """, MinionServer.class) + .setParameter("org", orgId, LongType.INSTANCE) + .getResultList().stream().map(MinionServer::getMinionId).collect(Collectors.toList()); } /** @@ -168,10 +195,14 @@ public static List lookupByMinionIds(Set minionIds) { return emptyList(); } else { - return HibernateFactory.getSession().createCriteria(MinionServer.class) - .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) - .add(Restrictions.in("minionId", minionIds)) - .list(); + return getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE s.minion_id IN (:minions) + """, MinionServer.class) + .setParameterList("minions", minionIds, StringType.INSTANCE) + .getResultList(); } } @@ -180,11 +211,21 @@ public static List lookupByMinionIds(Set minionIds) { * @return map of SSH minion id and its contact method */ public static List listSSHMinions() { - return HibernateFactory.getSession().createCriteria(MinionServer.class) - .createAlias("contactMethod", "m") - .add(Restrictions.in("m.label", - "ssh-push", "ssh-push-tunnel")) - .list(); + List contacts = getSession().createNativeQuery(""" + SELECT * from suseServerContactMethod + WHERE label IN (:labels) + """, ContactMethod.class) + .setParameterList("labels", List.of("ssh-push", "ssh-push-tunnel"), StringType.INSTANCE) + .getResultList().stream().map(ContactMethod::getId).collect(Collectors.toList()); + return getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE server_id IN + (SELECT id FROM rhnServer WHERE contact_method_id IN (:contacts)) + """, MinionServer.class) + .setParameterList("contacts", contacts, LongType.INSTANCE) + .getResultList(); } /** @@ -273,16 +314,27 @@ public static List findEmptyProfilesByHwAddrs(Set hwAddrs) return emptyList(); } - CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(MinionServer.class); - Root root = query.distinct(true).from(MinionServer.class); + List serverIds = getSession().createNativeQuery(""" + SELECT * from rhnServerNetInterface + WHERE hw_addr IN (:hwaddr) + """, NetworkInterface.class) + .setParameterList("hwaddr", hwAddrs, StringType.INSTANCE) + .getResultList().stream().map(x -> x.getServer().getId()).collect(Collectors.toList()); - Join nicJoin = root.join("networkInterfaces", JoinType.INNER); - Predicate hwAddrPredicate = nicJoin.get("hwaddr").in(hwAddrs); + if (serverIds.isEmpty()) { + return List.of(); + } - query.where(hwAddrPredicate); + List servers = getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE s.server_id IN (:ids) + """, MinionServer.class) + .setParameterList("ids", serverIds, LongType.INSTANCE) + .getResultList(); - return getSession().createQuery(query).stream() + return servers.stream() .filter(s -> s.hasEntitlement(EntitlementManager.BOOTSTRAP)) .collect(toList()); } @@ -294,12 +346,18 @@ public static List findEmptyProfilesByHwAddrs(Set hwAddrs) * @return the List of MinionServer matching given hostname */ public static List findEmptyProfilesByHostName(String hostname) { - CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(MinionServer.class); - Root root = query.from(MinionServer.class); - query.where(builder.equal(root.get("hostname"), hostname)); - - return getSession().createQuery(query).stream() + List servers = getSession().createNativeQuery(""" + SELECT s.*, r.* + FROM suseminioninfo s + JOIN rhnserver r ON s.server_id = r.id + WHERE + s.server_id IN + (SELECT id FROM rhnServer WHERE hostname = :hostname) + """, MinionServer.class) + .setParameter("hostname", hostname, StringType.INSTANCE) + .getResultList(); + + return servers.stream() .filter(s -> s.hasEntitlement(EntitlementManager.BOOTSTRAP)) .collect(toList()); } diff --git a/java/code/src/com/redhat/rhn/domain/server/PinnedSubscriptionFactory.java b/java/code/src/com/redhat/rhn/domain/server/PinnedSubscriptionFactory.java index 7330cdaac2d0..24d7008545b6 100644 --- a/java/code/src/com/redhat/rhn/domain/server/PinnedSubscriptionFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/PinnedSubscriptionFactory.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.criterion.Restrictions; +import org.hibernate.type.LongType; import java.util.List; @@ -96,7 +97,7 @@ public void remove(PinnedSubscription subscription) { public void cleanStalePins() { getSession() .getNamedQuery("PinnedSubscription.cleanStalePins") - .setLong("selfSystemId", MatcherJsonIO.SELF_SYSTEM_ID) + .setParameter("selfSystemId", MatcherJsonIO.SELF_SYSTEM_ID, LongType.INSTANCE) .executeUpdate(); } diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java index 0b5213380b03..71433ab91a64 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java @@ -54,15 +54,11 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.MatchMode; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; -import org.hibernate.criterion.Subqueries; import org.hibernate.query.Query; +import org.hibernate.type.LongType; import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.StringType; import java.util.ArrayList; import java.util.Arrays; @@ -78,12 +74,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.persistence.NoResultException; import javax.persistence.Tuple; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Path; -import javax.persistence.criteria.Root; /** * ServerFactory - the singleton class used to fetch and store @@ -113,12 +105,11 @@ protected static CustomDataValue getCustomDataValue(CustomDataKey key, return null; } - Session session = HibernateFactory.getSession(); - return (CustomDataValue) session.getNamedQuery( - "CustomDataValue.findByServerAndKey").setParameter("server", - server).setParameter("key", key) - // Retrieve from cache if there - .setCacheable(true).uniqueResult(); + return (CustomDataValue) HibernateFactory.getSession().getNamedQuery("CustomDataValue.findByServerAndKey") + .setParameter("server", server) + .setParameter("key", key) + .setCacheable(true) + .uniqueResult(); } /** @@ -207,22 +198,19 @@ public static Optional lookupProxyServer(String name) { log.warn("Please use a FQDN in /etc/salt/minion.d/susemanager.conf"); } - DetachedCriteria proxyIds = DetachedCriteria.forClass(ProxyInfo.class) - .setProjection(Projections.property("server.id")); - Optional result = findByFqdn(name); if (result.isPresent()) { return result; } - - result = HibernateFactory.getSession() - .createCriteria(Server.class) - .add(Subqueries.propertyIn("id", proxyIds)) - .add(Restrictions.eq("hostname", name)) - .list() - .stream() - .findFirst(); + result = HibernateFactory.getSession().createNativeQuery(""" + SELECT *, 0 as clazz_ + FROM rhnServer + WHERE id IN (SELECT server_id FROM rhnProxyInfo) + AND hostname = :hostname + LIMIT 1; + """, Server.class) + .setParameter("hostname", name, StringType.INSTANCE).uniqueResultOptional(); if (result.isPresent()) { return result; @@ -232,22 +220,24 @@ public static Optional lookupProxyServer(String name) { if (nameIsFullyQualified) { String srippedHostname = name.split("\\.")[0]; - return HibernateFactory.getSession() - .createCriteria(Server.class) - .add(Subqueries.propertyIn("id", proxyIds)) - .add(Restrictions.eq("hostname", srippedHostname)) - .list() - .stream() - .findFirst(); + return HibernateFactory.getSession().createNativeQuery(""" + SELECT *, 0 as clazz_ + FROM rhnServer + WHERE id IN (SELECT server_id FROM rhnProxyInfo) + AND hostname = :hostname + LIMIT 1; + """, Server.class) + .setParameter("hostname", srippedHostname, StringType.INSTANCE).uniqueResultOptional(); } else { - return HibernateFactory.getSession() - .createCriteria(Server.class) - .add(Subqueries.propertyIn("id", proxyIds)) - .add(Restrictions.like("hostname", name + ".", MatchMode.START)) - .list() - .stream() - .findFirst(); + return HibernateFactory.getSession().createNativeQuery(""" + SELECT *, 0 as clazz_ + FROM rhnServer + WHERE id IN (SELECT server_id FROM rhnProxyInfo) + AND hostname LIKE :hostname + LIMIT 1; + """, Server.class) + .setParameter("hostname", name + ".%", StringType.INSTANCE).uniqueResultOptional(); } } @@ -360,14 +350,14 @@ public static Optional findServerPath(Server server, Server proxySer // on query with a transient object return Optional.empty(); } - CriteriaBuilder builder = HibernateFactory.getSession().getCriteriaBuilder(); - CriteriaQuery criteria = builder.createQuery(ServerPath.class); - Root root = criteria.from(ServerPath.class); - Path id = root.get("id"); - criteria.where(builder.and( - builder.equal(id.get("server"), server), - builder.equal(id.get("proxyServer"), proxyServer))); - return getSession().createQuery(criteria).uniqueResultOptional(); + return getSession().createNativeQuery(""" + SELECT * from rhnServerPath + WHERE server_id = :server AND + proxy_server_id = :proxyserver + """, ServerPath.class) + .setParameter("server", server.getId(), LongType.INSTANCE) + .setParameter("proxyserver", proxyServer.getId(), LongType.INSTANCE) + .uniqueResultOptional(); } /** @@ -756,9 +746,13 @@ public static Server lookupById(Long id) { */ @SuppressWarnings("unchecked") public static Server lookupForeignSystemByDigitalServerId(String id) { - Criteria criteria = getSession().createCriteria(Server.class); - criteria.add(Restrictions.eq("digitalServerId", id)); - for (Server server : (List) criteria.list()) { + List servers = getSession().createNativeQuery(""" + SELECT *, 0 as clazz_ from rhnServer + WHERE digital_server_id = :id + """, Server.class) + .setParameter("id", id, StringType.INSTANCE) + .getResultList(); + for (Server server : servers) { if (server.hasEntitlement(EntitlementManager.getByName("foreign_entitled"))) { return server; } @@ -793,9 +787,9 @@ public static List lookupByServerIds(List ids, Strin */ public static ServerGroupType lookupServerGroupTypeByLabel(String label) { return (ServerGroupType) HibernateFactory.getSession().getNamedQuery("ServerGroupType.findByLabel") - .setString("label", label) - // Retrieve from cache if there - .setCacheable(true).uniqueResult(); + .setParameter("label", label, StringType.INSTANCE) + .setCacheable(true) + .uniqueResult(); } @@ -897,9 +891,9 @@ private static void updateServerPerms(Server server) { public static ServerArch lookupServerArchByLabel(String label) { Session session = HibernateFactory.getSession(); return (ServerArch) session.getNamedQuery("ServerArch.findByLabel") - .setString("label", label) - // Retrieve from cache if there - .setCacheable(true).uniqueResult(); + .setParameter("label", label, StringType.INSTANCE) + .setCacheable(true) + .uniqueResult(); } /** @@ -923,8 +917,7 @@ public static ServerArch lookupServerArchByName(String name) { public static CPUArch lookupCPUArchByName(String name) { Session session = HibernateFactory.getSession(); return (CPUArch) session.getNamedQuery("CPUArch.findByName") - .setString("name", name) - // Retrieve from cache if there + .setParameter("name", name, StringType.INSTANCE) .setCacheable(true).uniqueResult(); } @@ -1299,7 +1292,7 @@ public static void removeTagFromSnapshot(Long serverId, SnapshotTag tag) { */ public static SnapshotTag lookupSnapshotTagbyName(String tagName) { return (SnapshotTag) HibernateFactory.getSession().getNamedQuery("SnapshotTag.lookupByTagName") - .setString("tag_name", tagName) + .setParameter("tag_name", tagName, StringType.INSTANCE) // Do not use setCacheable(true), as tag deletion will // usually end up making this query's output out of date .uniqueResult(); @@ -1311,7 +1304,7 @@ public static SnapshotTag lookupSnapshotTagbyName(String tagName) { */ public static SnapshotTag lookupSnapshotTagbyId(Long tagId) { return (SnapshotTag) HibernateFactory.getSession().getNamedQuery("SnapshotTag.lookupById") - .setLong("id", tagId) + .setParameter("id", tagId, LongType.INSTANCE) // Do not use setCacheable(true), as tag deletion will // usually end up making this query's output out of date .uniqueResult(); @@ -1340,29 +1333,24 @@ public static ContactMethod findContactMethodById(Long id) { * @return contact method with the given label */ public static ContactMethod findContactMethodByLabel(String label) { - Session session = getSession(); - Criteria criteria = session.createCriteria(ContactMethod.class); - criteria.add(Restrictions.eq("label", label)); - return (ContactMethod) criteria.uniqueResult(); + try { + return getSession().createNativeQuery(""" + SELECT * from suseServerContactMethod + WHERE label = :label + """, ContactMethod.class) + .setParameter("label", label, StringType.INSTANCE) + .getSingleResult(); + } + catch (NoResultException e) { + return null; + } } /** - * @param fetchingVirtualGuests eagerly load virtual guests - * @param fetchingGroups eagerly load server groups * @return a list of all systems */ - public static List list(boolean fetchingVirtualGuests, boolean fetchingGroups) { - CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery criteria = builder.createQuery(Server.class); - Root r = criteria.from(Server.class); - if (fetchingVirtualGuests) { - r.fetch("virtualGuests", JoinType.LEFT); - } - if (fetchingGroups) { - r.fetch("groups", JoinType.LEFT); - } - criteria.distinct(true); - return new ArrayList<>(getSession().createQuery(criteria).getResultList()); + public static List list() { + return getSession().createNativeQuery("SELECT *, 0 as clazz_ FROM rhnServer s", Server.class).getResultList(); } @@ -1499,21 +1487,12 @@ public static void delete(Device device) { * @return the server if any */ public static Optional findByMachineId(String machineId) { - Session session = getSession(); - Criteria criteria = session.createCriteria(Server.class); - criteria.add(Restrictions.eq("machineId", machineId)); - return Optional.ofNullable((Server) criteria.uniqueResult()); - } - - /** - * Find {@link Capability} by name - * @param name the name of the capability - * @return a {@link Capability} with the given name - */ - public static Optional findCapability(String name) { - Criteria criteria = getSession().createCriteria(Capability.class); - criteria.add(Restrictions.eq("name", name)); - return Optional.ofNullable((Capability) criteria.uniqueResult()); + return getSession().createNativeQuery(""" + SELECT * from rhnServer + WHERE machine_id = :machine + """, Server.class) + .setParameter("machine", machineId, StringType.INSTANCE) + .uniqueResultOptional(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java b/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java index 87d9707e0a5b..58b8afb70341 100644 --- a/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java @@ -20,6 +20,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.util.ArrayList; import java.util.HashSet; @@ -83,7 +85,9 @@ public VirtualInstance lookupByGuestId(Org org, Long id) { Session session = HibernateFactory.getSession(); return (VirtualInstance) session.getNamedQuery("VirtualInstance.lookupGuestBySidAndOrg") - .setParameter("org", org).setParameter("sid", id).uniqueResult(); + .setParameter("org", org) + .setParameter("sid", id, LongType.INSTANCE) + .uniqueResult(); } @@ -96,8 +100,9 @@ public VirtualInstance lookupByGuestId(Org org, Long id) { public VirtualInstance lookupByGuestId(Long id) { Session session = HibernateFactory.getSession(); return (VirtualInstance) session.getNamedQuery( - "VirtualInstance.lookupGuestBySid"). - setParameter("sid", id).uniqueResult(); + "VirtualInstance.lookupGuestBySid") + .setParameter("sid", id, LongType.INSTANCE) + .uniqueResult(); } /** @@ -111,7 +116,8 @@ public boolean isOutdated(VirtualInstance guest) { Session session = HibernateFactory.getSession(); VirtualInstance results = (VirtualInstance) session.getNamedQuery( "VirtualInstance.isOutdatedVirtualInstance"). - setParameter("guest", guest).uniqueResult(); + setParameter("guest", guest) + .uniqueResult(); return results != null; } @@ -165,7 +171,8 @@ public Set findGuestsWithNonVirtHostByOrg(Org org) { Session session = HibernateFactory.getSession(); List results = session.getNamedQuery( "VirtualInstance.findGuestsWithNonVirtHostByOrg"). - setParameter("org_id", org.getId()).list(); + setParameter("org_id", org.getId(), LongType.INSTANCE) + .list(); return new HashSet<>(convertToView(results)); } @@ -251,7 +258,8 @@ public Set findGuestsWithoutAHostByOrg(Org org) { */ public VirtualInstanceType getParaVirtType() { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", "para_virtualized") + "VirtualInstanceType.findByLabel") + .setParameter("label", "para_virtualized", StringType.INSTANCE) .setCacheable(true).uniqueResult(); } @@ -262,7 +270,8 @@ public VirtualInstanceType getParaVirtType() { */ public VirtualInstanceType getFullyVirtType() { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", "fully_virtualized") + "VirtualInstanceType.findByLabel") + .setParameter("label", "fully_virtualized", StringType.INSTANCE) .setCacheable(true).uniqueResult(); } @@ -274,7 +283,8 @@ public VirtualInstanceType getFullyVirtType() { */ public VirtualInstanceType getVirtualInstanceType(String label) { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", label) + "VirtualInstanceType.findByLabel") + .setParameter("label", label, StringType.INSTANCE) .setCacheable(true).uniqueResult(); } @@ -285,7 +295,8 @@ public VirtualInstanceType getVirtualInstanceType(String label) { */ public VirtualInstanceState getRunningState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "running") + "VirtualInstanceState.findByLabel") + .setParameter("label", "running", StringType.INSTANCE) .uniqueResult(); } @@ -296,8 +307,9 @@ public VirtualInstanceState getRunningState() { */ public VirtualInstanceState getStoppedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "stopped") - .uniqueResult(); + "VirtualInstanceState.findByLabel") + .setParameter("label", "stopped", StringType.INSTANCE) + .uniqueResult(); } /** @@ -307,8 +319,9 @@ public VirtualInstanceState getStoppedState() { */ public VirtualInstanceState getPausedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "paused") - .uniqueResult(); + "VirtualInstanceState.findByLabel") + .setParameter("label", "paused", StringType.INSTANCE) + .uniqueResult(); } /** @@ -318,8 +331,9 @@ public VirtualInstanceState getPausedState() { */ public VirtualInstanceState getCrashedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "crashed") - .uniqueResult(); + "VirtualInstanceState.findByLabel") + .setParameter("label", "crashed", StringType.INSTANCE) + .uniqueResult(); } /** @@ -329,7 +343,8 @@ public VirtualInstanceState getCrashedState() { */ public VirtualInstanceState getUnknownState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "unknown") + "VirtualInstanceState.findByLabel") + .setParameter("label", "unknown", StringType.INSTANCE) .uniqueResult(); } @@ -341,7 +356,8 @@ public VirtualInstanceState getUnknownState() { */ public Optional getState(String label) { return Optional.ofNullable((VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", label) + "VirtualInstanceState.findByLabel") + .setParameter("label", label, StringType.INSTANCE) .uniqueResult()); } @@ -353,8 +369,8 @@ public Optional getState(String label) { public List lookupVirtualInstanceByUuid(String uuid) { return getSession() .getNamedQuery("VirtualInstance.lookupVirtualInstanceByUuid") - .setParameter("uuid", uuid) - .list(); + .setParameter("uuid", uuid, StringType.INSTANCE) + .list(); } /** @@ -365,7 +381,7 @@ public List lookupVirtualInstanceByUuid(String uuid) { public VirtualInstance lookupHostVirtInstanceByHostId(Long hostId) { return (VirtualInstance) getSession() .getNamedQuery("VirtualInstance.lookupHostVirtInstanceByHostId") - .setParameter("hostId", hostId) + .setParameter("hostId", hostId, LongType.INSTANCE) .uniqueResult(); } @@ -378,8 +394,8 @@ public VirtualInstance lookupHostVirtInstanceByHostId(Long hostId) { public VirtualInstance lookupVirtualInstanceByHostIdAndUuid(Long hostId, String uuid) { return (VirtualInstance) getSession() .getNamedQuery("VirtualInstance.lookupHostVirtInstanceByHostIdAndUuid") - .setParameter("hostId", hostId) - .setParameter("uuid", uuid) + .setParameter("hostId", hostId, LongType.INSTANCE) + .setParameter("uuid", uuid, StringType.INSTANCE) .uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/domain/server/test/LocationTest.java b/java/code/src/com/redhat/rhn/domain/server/test/LocationTest.java index 9b2b2c6f1b35..5adfff8bf44d 100644 --- a/java/code/src/com/redhat/rhn/domain/server/test/LocationTest.java +++ b/java/code/src/com/redhat/rhn/domain/server/test/LocationTest.java @@ -28,6 +28,7 @@ import com.redhat.rhn.testing.UserTestUtils; import org.hibernate.Session; +import org.hibernate.type.LongType; import org.junit.jupiter.api.Test; import java.util.Date; @@ -57,7 +58,7 @@ public void testLocation() throws Exception { Session session = HibernateFactory.getSession(); loc2 = (Location) session.getNamedQuery("Location.findById") - .setLong("id", loc1.getId()) + .setParameter("id", loc1.getId(), LongType.INSTANCE) .uniqueResult(); assertEquals(loc1, loc2); } diff --git a/java/code/src/com/redhat/rhn/domain/server/test/NoteTest.java b/java/code/src/com/redhat/rhn/domain/server/test/NoteTest.java index 0b1634a518a1..ff26e4ef8ddb 100644 --- a/java/code/src/com/redhat/rhn/domain/server/test/NoteTest.java +++ b/java/code/src/com/redhat/rhn/domain/server/test/NoteTest.java @@ -27,6 +27,7 @@ import com.redhat.rhn.testing.UserTestUtils; import org.hibernate.Session; +import org.hibernate.type.LongType; import org.junit.jupiter.api.Test; import java.util.Date; @@ -50,7 +51,7 @@ public void testEquals() throws Exception { Session session = HibernateFactory.getSession(); note2 = (Note) session.getNamedQuery("Note.findById") - .setLong("id", note1.getId()) + .setParameter("id", note1.getId(), LongType.INSTANCE) .uniqueResult(); assertEquals(note1, note2); diff --git a/java/code/src/com/redhat/rhn/domain/server/test/ServerFactoryTest.java b/java/code/src/com/redhat/rhn/domain/server/test/ServerFactoryTest.java index ecd6bdd2ee91..d19c771c92e5 100644 --- a/java/code/src/com/redhat/rhn/domain/server/test/ServerFactoryTest.java +++ b/java/code/src/com/redhat/rhn/domain/server/test/ServerFactoryTest.java @@ -1430,10 +1430,12 @@ public void testLookupProxyServer() throws Exception { HibernateFactory.getSession().clear(); // FQDN: precise lookup - assertEquals(s, ServerFactory.lookupProxyServer(HOSTNAME).get()); + assertEquals(s, ServerFactory.lookupProxyServer(HOSTNAME).orElseThrow()); + // plain hostname: imprecise lookup String simpleHostname = HOSTNAME.split("\\.")[0]; - assertEquals(s, ServerFactory.lookupProxyServer(simpleHostname).get()); + + assertEquals(s, ServerFactory.lookupProxyServer(simpleHostname).orElseThrow()); } /** diff --git a/java/code/src/com/redhat/rhn/domain/state/StateFactory.java b/java/code/src/com/redhat/rhn/domain/state/StateFactory.java index 2abe2ebfbc74..4e56b4a66903 100644 --- a/java/code/src/com/redhat/rhn/domain/state/StateFactory.java +++ b/java/code/src/com/redhat/rhn/domain/state/StateFactory.java @@ -22,16 +22,16 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Property; -import org.hibernate.criterion.Restrictions; +import org.hibernate.query.Query; +import org.hibernate.type.LongType; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.Set; +import javax.persistence.NoResultException; + /** * Factory class for working with states. */ @@ -88,6 +88,73 @@ public static void save(StateRevision stateRevision) { singleton.saveObject(stateRevision); } + /** + * Lookup the latest state revision of an org. + * @param org the org + * @return the optional {@link OrgStateRevision} + */ + public static Optional latestStateRevision(Org org) { + String sql = + """ + SELECT DISTINCT ON (org_id) *, null as created, null as creator_id FROM + suseOrgStateRevision WHERE org_id = :org + ORDER BY org_id, state_revision_id desc limit 1; + """; + Query query = getSession().createNativeQuery(sql, OrgStateRevision.class); + query.setParameter("org", org.getId(), LongType.INSTANCE); + try { + return Optional.ofNullable(query.getSingleResult()); + } + catch (NoResultException e) { + return Optional.empty(); + } + } + + /** + * Lookup the latest state revision of an org. + * @param group the server group + * @return the optional {@link OrgStateRevision} + */ + public static Optional latestStateRevision( + ServerGroup group) { + String sql = + """ + SELECT DISTINCT ON (group_id) *, null as created, null as creator_id FROM + suseServerGroupStateRevision WHERE group_id = :group + ORDER BY group_id, state_revision_id desc limit 1; + """; + Query query = getSession().createNativeQuery(sql, ServerGroupStateRevision.class); + query.setParameter("group", group.getId(), LongType.INSTANCE); + try { + return Optional.ofNullable(query.getSingleResult()); + } + catch (NoResultException e) { + return Optional.empty(); + } + } + + /** + * Lookup the latest state revision of a server. + * @param server the server + * @return the optional {@link OrgStateRevision} + */ + public static Optional latestStateRevision(MinionServer server) { + String sql = + """ + SELECT DISTINCT ON (server_id) *, null as created, null as creator_id FROM + suseServerStateRevision WHERE server_id = :server + ORDER BY server_id, state_revision_id desc limit 1; + """; + Query query = getSession().createNativeQuery(sql, ServerStateRevision.class); + query.setParameter("server", server.getId(), LongType.INSTANCE); + try { + return Optional.ofNullable(query.getSingleResult()); + } + catch (NoResultException e) { + return Optional.empty(); + } + } + /** * Lookup the latest set of {@link PackageState} objects for a given server. * @@ -95,9 +162,8 @@ public static void save(StateRevision stateRevision) { * @return the latest package states for this server */ public static Optional> latestPackageStates(MinionServer server) { - Optional revision = latestRevision(ServerStateRevision.class, - "server", server); - return revision.map(ServerStateRevision::getPackageStates); + Optional servers = latestStateRevision(server); + return servers.map(StateRevision::getPackageStates); } /** @@ -107,9 +173,8 @@ public static Optional> latestPackageStates(MinionServer serve * @return the latest package states for this server group */ public static Optional> latestPackageStates(ServerGroup group) { - Optional revision = latestRevision( - ServerGroupStateRevision.class, "group", group); - return revision.map(ServerGroupStateRevision::getPackageStates); + Optional groups = latestStateRevision(group); + return groups.map(StateRevision::getPackageStates); } /** @@ -119,38 +184,11 @@ public static Optional> latestPackageStates(ServerGroup group) * @return the latest package states for this organization */ public static Optional> latestPackageStates(Org org) { - Optional revision = latestRevision(OrgStateRevision.class, - "org", org); - return revision.map(OrgStateRevision::getPackageStates); - } - - /** - * Lookup the latest state revision of an org. - * @param org the org - * @return the optional {@link OrgStateRevision} - */ - public static Optional latestStateRevision(Org org) { - return latestRevision(OrgStateRevision.class, "org", org); + Optional orgs = latestStateRevision(org); + return orgs.map(StateRevision::getPackageStates); } - /** - * Lookup the latest state revision of an org. - * @param group the server group - * @return the optional {@link OrgStateRevision} - */ - public static Optional latestStateRevision( - ServerGroup group) { - return latestRevision(ServerGroupStateRevision.class, "group", group); - } - /** - * Lookup the latest state revision of a server. - * @param server the server - * @return the optional {@link OrgStateRevision} - */ - public static Optional latestStateRevision(MinionServer server) { - return latestRevision(ServerStateRevision.class, "server", server); - } /** * Lookup the latest set of {@link ConfigChannel} objects for a given server. @@ -159,10 +197,8 @@ public static Optional latestStateRevision(MinionServer ser * @return the latest config channels for this server */ public static Optional> latestConfigChannels(MinionServer server) { - Optional revision = latestRevision( - ServerStateRevision.class, "server", server); - return Optional - .ofNullable(revision.map(StateRevision::getConfigChannels).orElse(null)); + Optional servers = latestStateRevision(server); + return servers.map(StateRevision::getConfigChannels); } /** @@ -172,10 +208,8 @@ public static Optional> latestConfigChannels(MinionServer se * @return the latest config channels for this server */ public static Optional> latestConfigChannels(ServerGroup group) { - Optional revision = latestRevision( - ServerGroupStateRevision.class, "group", group); - return Optional - .ofNullable(revision.map(StateRevision::getConfigChannels).orElse(null)); + Optional groups = latestStateRevision(group); + return groups.map(StateRevision::getConfigChannels); } /** @@ -185,23 +219,8 @@ public static Optional> latestConfigChannels(ServerGroup gro * @return the latest config channels for this server */ public static Optional> latestConfigChannels(Org org) { - Optional revision = latestRevision( - OrgStateRevision.class, "org", org); - return Optional - .ofNullable(revision.map(StateRevision::getConfigChannels).orElse(null)); - } - - private static Optional latestRevision( - Class revisionType, String field, Object bean) { - DetachedCriteria maxQuery = DetachedCriteria.forClass(revisionType) - .add(Restrictions.eq(field, bean)) - .setProjection(Projections.max("id")); - T revision = (T) getSession() - .createCriteria(revisionType) - .add(Restrictions.eq(field, bean)) - .add(Property.forName("id").eq(maxQuery)) - .uniqueResult(); - return Optional.ofNullable(revision); + Optional orgs = latestStateRevision(org); + return orgs.map(StateRevision::getConfigChannels); } /** diff --git a/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java b/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java index c827113065a4..9f533f757909 100644 --- a/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java +++ b/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java @@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hibernate.type.StringType; import java.util.HashMap; import java.util.List; @@ -60,7 +61,7 @@ public static ActivationKey lookupByKey(String key) { return (ActivationKey) HibernateFactory.getSession() .getNamedQuery("ActivationKey.findByKey") - .setString("key", key) + .setParameter("key", key, StringType.INSTANCE) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/domain/token/test/TokenTest.java b/java/code/src/com/redhat/rhn/domain/token/test/TokenTest.java index 05faf1c891bb..1ce39c078a36 100644 --- a/java/code/src/com/redhat/rhn/domain/token/test/TokenTest.java +++ b/java/code/src/com/redhat/rhn/domain/token/test/TokenTest.java @@ -41,6 +41,7 @@ import com.redhat.rhn.testing.UserTestUtils; import org.hibernate.Session; +import org.hibernate.type.LongType; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -64,7 +65,7 @@ public void testEquals() throws Exception { Session session = HibernateFactory.getSession(); token2 = (Token) session.getNamedQuery("Token.findById") - .setLong("id", token1.getId()) + .setParameter("id", token1.getId(), LongType.INSTANCE) .uniqueResult(); assertEquals(token1, token2); diff --git a/java/code/src/com/redhat/rhn/domain/user/User.java b/java/code/src/com/redhat/rhn/domain/user/User.java index 305029ef921a..a99ebedf2613 100644 --- a/java/code/src/com/redhat/rhn/domain/user/User.java +++ b/java/code/src/com/redhat/rhn/domain/user/User.java @@ -20,6 +20,7 @@ import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.server.ServerGroup; +import java.io.Serializable; import java.util.Date; import java.util.Set; @@ -28,7 +29,7 @@ * and ancillary tables. * DB table: web_contact */ -public interface User { +public interface User extends Serializable { /** * Gets the current value of id * @return long the current value diff --git a/java/code/src/com/redhat/rhn/domain/user/UserFactory.java b/java/code/src/com/redhat/rhn/domain/user/UserFactory.java index 7e152051ed73..7c9fff4be5b4 100644 --- a/java/code/src/com/redhat/rhn/domain/user/UserFactory.java +++ b/java/code/src/com/redhat/rhn/domain/user/UserFactory.java @@ -37,6 +37,8 @@ import org.apache.logging.log4j.Logger; import org.hibernate.Session; import org.hibernate.query.Query; +import org.hibernate.type.IntegerType; +import org.hibernate.type.StringType; import java.sql.Types; import java.util.Arrays; @@ -446,7 +448,7 @@ public void syncServerGroupPerms(User usr) { public static RhnTimeZone getTimeZone(int id) { Session session = HibernateFactory.getSession(); return (RhnTimeZone) session.getNamedQuery("RhnTimeZone.loadTimeZoneById") - .setInteger("tid", id) + .setParameter("tid", id, IntegerType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -461,7 +463,7 @@ public static RhnTimeZone getTimeZone(String olsonName) { Session session = HibernateFactory.getSession(); return (RhnTimeZone) session .getNamedQuery("RhnTimeZone.loadTimeZoneByOlsonName") - .setString("ton", olsonName) + .setParameter("ton", olsonName, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesAddAction.java b/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesAddAction.java index 1de8bdcc1499..c466ec4aeb7f 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesAddAction.java +++ b/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesAddAction.java @@ -19,6 +19,7 @@ import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.channel.SelectableChannel; import com.redhat.rhn.domain.rhnset.RhnSet; import com.redhat.rhn.domain.role.RoleFactory; @@ -109,7 +110,8 @@ public ActionForward execute(ActionMapping mapping, //If a channel isn't selected, select one smartly if (selectedChan == null) { if (chan.isCloned()) { - selectedChan = chan.getOriginal().getId().toString(); + selectedChan = chan.asCloned().map(ClonedChannel::getOriginal) + .map(Channel::getId).orElse(0L).toString(); } else { selectedChan = ORPHAN_PACKAGES; diff --git a/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesCompareAction.java b/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesCompareAction.java index d838f9f1510f..c804801a61f5 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesCompareAction.java +++ b/java/code/src/com/redhat/rhn/frontend/action/channel/manage/ChannelPackagesCompareAction.java @@ -18,6 +18,7 @@ import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.channel.SelectableChannel; import com.redhat.rhn.domain.role.RoleFactory; import com.redhat.rhn.domain.user.User; @@ -96,7 +97,7 @@ public ActionForward execute(ActionMapping mapping, //If a channel isn't selected, select one smartly if (selectedChan == null) { if (chan.isCloned()) { - scid = chan.getOriginal().getId(); + scid = chan.asCloned().map(ClonedChannel::getOriginal).map(Channel::getId).orElse(0L); } } else if (!NO_PACKAGES.equals(selectedChan)) { diff --git a/java/code/src/com/redhat/rhn/frontend/action/kickstart/test/KickstartDeleteActionTest.java b/java/code/src/com/redhat/rhn/frontend/action/kickstart/test/KickstartDeleteActionTest.java index a92e4119bcb8..f4365dca5755 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/kickstart/test/KickstartDeleteActionTest.java +++ b/java/code/src/com/redhat/rhn/frontend/action/kickstart/test/KickstartDeleteActionTest.java @@ -23,6 +23,7 @@ import com.redhat.rhn.frontend.struts.RequestContext; import org.hibernate.Session; +import org.hibernate.type.LongType; import org.junit.jupiter.api.Test; public class KickstartDeleteActionTest extends BaseKickstartEditTestCase { @@ -63,8 +64,8 @@ public void testSubmit() throws Exception { private KickstartData lookupById(Long id) { Session session = HibernateFactory.getSession(); return (KickstartData) session.getNamedQuery("KickstartData.findByIdAndOrg") - .setLong("id", id) - .setLong("org_id", user.getOrg().getId()) + .setParameter("id", id, LongType.INSTANCE) + .setParameter("org_id", user.getOrg().getId(), LongType.INSTANCE) .uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml index 196ea84874ea..308b2c287156 100644 --- a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml +++ b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml @@ -5165,7 +5165,7 @@ user before attempting to deactivate their account. - You have just created your first @@PRODUCT_NAME@@ user. To finalize your installation please use the <a href="/rhn/admin/setup/ProxySettings.do">Setup Wizard</a>. + You have just created your first @@PRODUCT_NAME@@ user. To finalize your installation please use the <a href="/rhn/manager/admin/setup/proxy">Setup Wizard</a>. Navigation Menu diff --git a/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManager.java b/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManager.java index c97dcfb01a5c..2ee09436fe53 100644 --- a/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManager.java +++ b/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManager.java @@ -24,6 +24,7 @@ import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelArch; import com.redhat.rhn.domain.channel.ChannelFactory; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.image.ImageInfo; import com.redhat.rhn.domain.image.ImageInfoFactory; import com.redhat.rhn.domain.product.CachingSUSEProductFactory; @@ -369,7 +370,7 @@ public static List populateCVEChannels(AuditTarget auditTarget) { int i = 0; Channel original = c; while (original.isCloned()) { - original = original.getOriginal(); + original = original.asCloned().map(ClonedChannel::getOriginal).orElseThrow(); // Revert the index if no channel has actually been added i = relevantChannels.add( new RankedChannel(original.getId(), ++i)) ? i : --i; @@ -445,7 +446,7 @@ public static void populateCVEChannels() { targetProductCache.clear(); // Get a list of *all* servers - List servers = ServerFactory.list(false, false); + List servers = ServerFactory.list(); if (log.isDebugEnabled()) { log.debug("Number of servers found: {}", servers.size()); } @@ -1082,8 +1083,9 @@ protected static Optional getPatchCandidateResult(List newerPatch = packageResults.stream() .filter(r -> instChannel.getId().equals(r.getChannelId().get()) || (instChannel.isCloned() && - instChannel.getOriginal() != null && instChannel.getOriginal().getId() - .equals(r.getChannelId().get()))) + instChannel.asCloned().map(ClonedChannel::getOriginal) + .map(Channel::getId) + .stream().anyMatch(id -> id.equals(r.getChannelId().get())))) .filter(r -> li.getPackageEvr().get().compareTo(r.getPackageEvr().get()) < 0) .max(evrComparator); diff --git a/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java b/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java index 0c5413078242..a6eb885c3b42 100644 --- a/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java +++ b/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java @@ -2101,7 +2101,7 @@ private static Map> getOrignalToClonesMap( */ public static Channel getOriginalChannel(Channel channel) { while (channel.isCloned()) { - channel = channel.getOriginal(); + channel = channel.asCloned().map(ClonedChannel::getOriginal).orElse(channel); } return channel; } @@ -2434,7 +2434,7 @@ public static List listErrataNeedingResync(Channel c, User user) if (c.isCloned()) { Map params = new HashMap<>(); params.put("cid", c.getId()); - params.put("ocid", c.getOriginal().getId()); + params.put("ocid", c.asCloned().map(ClonedChannel::getOriginal).orElseThrow().getId()); SelectMode m = ModeFactory.getMode(ERRATA_QUERIES, "list_errata_needing_sync"); return m.execute(params); @@ -2456,7 +2456,7 @@ public static List listErrataPackagesForResync(Channel c, User if (c.isCloned()) { Map params = new HashMap<>(); params.put("cid", c.getId()); - params.put("ocid", c.getOriginal().getId()); + params.put("ocid", c.asCloned().map(ClonedChannel::getOriginal).orElseThrow().getId()); SelectMode m = ModeFactory.getMode(ERRATA_QUERIES, "list_packages_needing_sync"); return m.execute(params); @@ -2481,7 +2481,7 @@ public static List listErrataPackagesForResync(Channel c, User Map params = new HashMap<>(); params.put("cid", c.getId()); params.put("set_label", setLabel); - params.put("ocid", c.getOriginal().getId()); + params.put("ocid", c.asCloned().map(ClonedChannel::getOriginal).orElseThrow().getId()); SelectMode m = ModeFactory.getMode(ERRATA_QUERIES, "list_packages_needing_sync_from_set"); return m.execute(params); } diff --git a/java/code/src/com/redhat/rhn/manager/contentmgmt/test/ContentManagerTest.java b/java/code/src/com/redhat/rhn/manager/contentmgmt/test/ContentManagerTest.java index 224c8c177094..a1d132722f1b 100644 --- a/java/code/src/com/redhat/rhn/manager/contentmgmt/test/ContentManagerTest.java +++ b/java/code/src/com/redhat/rhn/manager/contentmgmt/test/ContentManagerTest.java @@ -38,6 +38,7 @@ import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.channel.Modules; import com.redhat.rhn.domain.channel.test.ChannelFactoryTest; import com.redhat.rhn.domain.contentmgmt.ContentEnvironment; @@ -325,7 +326,7 @@ public void testPopulateNewEnvironment() throws Exception { createEnvironment(cp.getLabel(), of(fst.getLabel()), "mid", "middle env", "desc", false, user); assertEquals(1, mid.getTargets().size()); Channel newChannel = mid.getTargets().get(0).asSoftwareTarget().get().getChannel(); - assertEquals(channel, newChannel.getOriginal()); + assertEquals(channel, newChannel.asCloned().map(ClonedChannel::getOriginal).get()); assertTrue(newChannel.getLabel().startsWith("cplabel-mid-")); assertEquals(fst.getVersion(), mid.getVersion()); } @@ -804,7 +805,7 @@ public void testBuildProject() throws Exception { assertEquals(Status.GENERATING_REPODATA, target.getStatus()); assertEquals("cplabel-fst-" + channel.getLabel(), tgtChannel.getLabel()); assertTrue(channel.getClonedChannels().contains(tgtChannel)); - assertEquals(channel, tgtChannel.getOriginal()); + assertEquals(channel, tgtChannel.asCloned().map(ClonedChannel::getOriginal).get()); assertEquals(channel.getPackages(), tgtChannel.getPackages()); assertEquals(channel.getErratas(), tgtChannel.getErratas()); assertEquals(Long.valueOf(1), env.getVersion()); @@ -1544,7 +1545,7 @@ public void testFixingClonedChannelLinks2() throws Exception { devChan = ChannelFactory.lookupById(devChan.getId()); testChan = ChannelFactory.lookupById(testChan.getId()); - assertEquals(srcChan, devChan.getOriginal()); + assertEquals(srcChan, devChan.asCloned().map(ClonedChannel::getOriginal).get()); assertFalse(testChan.isCloned()); // let's promote the project and check that the procedure fixed the channel in the test environment as well @@ -1554,13 +1555,15 @@ public void testFixingClonedChannelLinks2() throws Exception { devChan = ChannelFactory.lookupById(devChan.getId()); testChan = ChannelFactory.lookupById(testChan.getId()); - assertEquals(srcChan, devChan.getOriginal()); - assertEquals(devChan, testChan.getOriginal()); + assertEquals(srcChan, devChan.asCloned().map(ClonedChannel::getOriginal).get()); + assertEquals(devChan, testChan.asCloned().map(ClonedChannel::getOriginal).get()); } // extract original channels from given channels private Set getOriginalChannels(Collection channels) { - return channels.stream().map(Channel::getOriginal).collect(toSet()); + return channels.stream() + .map(c -> c.asCloned().orElseThrow()) + .map(ClonedChannel::getOriginal).collect(toSet()); } // get channels of given environment diff --git a/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java b/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java index 364a050b2f57..d6d51c65f8a0 100644 --- a/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java +++ b/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java @@ -68,6 +68,7 @@ import org.apache.logging.log4j.Logger; import org.hibernate.HibernateException; import org.hibernate.Session; +import org.hibernate.type.StringType; import java.io.File; import java.util.ArrayList; @@ -636,7 +637,7 @@ public static PackageName lookupPackageName(String name) { try { session = HibernateFactory.getSession(); return (PackageName)session.getNamedQuery("PackageName.findByName") - .setString("name", name) + .setParameter("name", name, StringType.INSTANCE) .uniqueResult(); } catch (HibernateException e) { diff --git a/java/code/src/com/redhat/rhn/taskomatic/task/repomd/UpdateInfoWriter.java b/java/code/src/com/redhat/rhn/taskomatic/task/repomd/UpdateInfoWriter.java index 23324c5623fb..a3eac024ef85 100644 --- a/java/code/src/com/redhat/rhn/taskomatic/task/repomd/UpdateInfoWriter.java +++ b/java/code/src/com/redhat/rhn/taskomatic/task/repomd/UpdateInfoWriter.java @@ -17,6 +17,7 @@ import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.domain.channel.Channel; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.frontend.dto.Bug; import com.redhat.rhn.frontend.dto.CVE; import com.redhat.rhn.frontend.dto.ErrataOverview; @@ -281,7 +282,7 @@ private String findUpdateTag(Channel channel) { if (updateTag == null || updateTag.isEmpty()) { Channel current = channel; while (current.isCloned()) { - current = current.getOriginal(); + current = current.asCloned().map(ClonedChannel::getOriginal).orElseThrow(); updateTag = current.getUpdateTag(); if (updateTag != null && !updateTag.isEmpty()) { break; diff --git a/java/code/src/com/redhat/rhn/taskomatic/task/test/KickstartCleanupTest.java b/java/code/src/com/redhat/rhn/taskomatic/task/test/KickstartCleanupTest.java index 04c658e7aa3e..25367449acbc 100644 --- a/java/code/src/com/redhat/rhn/taskomatic/task/test/KickstartCleanupTest.java +++ b/java/code/src/com/redhat/rhn/taskomatic/task/test/KickstartCleanupTest.java @@ -38,6 +38,7 @@ import com.redhat.rhn.testing.UserTestUtils; import org.hibernate.Session; +import org.hibernate.type.StringType; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -156,7 +157,7 @@ private static KickstartSessionState lookupByLabel(String label) { Session session = HibernateFactory.getSession(); return (KickstartSessionState) session .getNamedQuery("KickstartSessionState.findByLabel") - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/testing/TestUtils.java b/java/code/src/com/redhat/rhn/testing/TestUtils.java index 7c8dbf06e35e..9ed442e690c5 100644 --- a/java/code/src/com/redhat/rhn/testing/TestUtils.java +++ b/java/code/src/com/redhat/rhn/testing/TestUtils.java @@ -42,6 +42,8 @@ import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.query.Query; +import org.hibernate.type.LongType; +import org.hibernate.type.StringType; import java.io.BufferedReader; import java.io.File; @@ -267,7 +269,7 @@ public static List lookupTestObjects(String query) { public static Object lookupFromCacheById(Long id, String queryname) { Session session = HibernateFactory.getSession(); return session.getNamedQuery(queryname) - .setLong("id", id) + .setParameter("id", id, LongType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -284,7 +286,7 @@ public static Object lookupFromCacheByLabel(String label, String queryname) { Session session = HibernateFactory.getSession(); return session.getNamedQuery(queryname) - .setString("label", label) + .setParameter("label", label, StringType.INSTANCE) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/suse/manager/matcher/MatcherJsonIO.java b/java/code/src/com/suse/manager/matcher/MatcherJsonIO.java index 454a5bdf20c8..b7bfc51b62ea 100644 --- a/java/code/src/com/suse/manager/matcher/MatcherJsonIO.java +++ b/java/code/src/com/suse/manager/matcher/MatcherJsonIO.java @@ -175,7 +175,7 @@ public List getJsonSystems(String arch, boolean includeSelf, boolean .flatMap(cf -> Stream.of("", "-ALPHA", "-BETA").map(s -> cf + s)) .collect(Collectors.toSet()); - Stream systems = ServerFactory.list(true, true).stream() + Stream systems = ServerFactory.list().stream() .map(system -> { Long cpus = system.getCpu() == null ? null : system.getCpu().getNrsocket(); Set entitlements = system.getEntitlementLabels(); @@ -191,6 +191,7 @@ public List getJsonSystems(String arch, boolean includeSelf, boolean // For now it is not worth the effort cpus = system.getCpu() == null ? null : system.getCpu().getNrCPU(); } + Set productIds = productIdsForServer(system, needsEntitlements, entitlements) .collect(Collectors.toSet()); return new SystemJson( diff --git a/java/code/src/com/suse/manager/webui/controllers/DownloadController.java b/java/code/src/com/suse/manager/webui/controllers/DownloadController.java index 90b77efeb73c..ee0c2d8dc69b 100644 --- a/java/code/src/com/suse/manager/webui/controllers/DownloadController.java +++ b/java/code/src/com/suse/manager/webui/controllers/DownloadController.java @@ -27,6 +27,7 @@ import com.redhat.rhn.domain.channel.AccessTokenFactory; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; +import com.redhat.rhn.domain.channel.ClonedChannel; import com.redhat.rhn.domain.channel.Comps; import com.redhat.rhn.domain.channel.MediaProducts; import com.redhat.rhn.domain.channel.Modules; @@ -355,7 +356,7 @@ private File getCompsFile(Channel channel) { Comps comps = channel.getComps(); if (comps == null && channel.isCloned()) { - comps = channel.getOriginal().getComps(); + comps = channel.asCloned().map(ClonedChannel::getOriginal).map(Channel::getComps).orElse(null); } if (comps != null) { return new File(mountPointPath, comps.getRelativeFilename()) @@ -377,7 +378,7 @@ private File getModulesFile(Channel channel) { Modules modules = channel.getModules(); if (modules == null && channel.isCloned()) { - modules = channel.getOriginal().getModules(); + modules = channel.asCloned().map(ClonedChannel::getOriginal).map(Channel::getModules).orElse(null); } if (modules != null) { return new File(mountPointPath, modules.getRelativeFilename()).getAbsoluteFile(); @@ -398,7 +399,7 @@ private File getMediaProductsFile(Channel channel) { MediaProducts product = channel.getMediaProducts(); if (product == null && channel.isCloned()) { - product = channel.getOriginal().getMediaProducts(); + product = channel.asCloned().map(ClonedChannel::getOriginal).map(Channel::getMediaProducts).orElse(null); } if (product != null) { return new File(mountPointPath, product.getRelativeFilename()) diff --git a/java/code/src/com/suse/manager/webui/controllers/admin/AdminViewsController.java b/java/code/src/com/suse/manager/webui/controllers/admin/AdminViewsController.java index 63350ddf558e..b0959f0b5492 100644 --- a/java/code/src/com/suse/manager/webui/controllers/admin/AdminViewsController.java +++ b/java/code/src/com/suse/manager/webui/controllers/admin/AdminViewsController.java @@ -24,6 +24,8 @@ import com.redhat.rhn.domain.cloudpayg.PaygSshData; import com.redhat.rhn.domain.cloudpayg.PaygSshDataFactory; import com.redhat.rhn.domain.user.User; +import com.redhat.rhn.manager.setup.ProxySettingsDto; +import com.redhat.rhn.manager.setup.ProxySettingsManager; import com.redhat.rhn.taskomatic.TaskomaticApi; import com.suse.manager.admin.PaygAdminManager; @@ -72,6 +74,8 @@ public static void initRoutes(JadeTemplateEngine jade) { withUserPreferences(withCsrfToken(withOrgAdmin(AdminViewsController::createPayg))), jade); get("/manager/admin/setup/payg/:id", withUserPreferences(withCsrfToken(withOrgAdmin(AdminViewsController::showPayg))), jade); + get("/manager/admin/setup/proxy", + withUserPreferences(withCsrfToken(withOrgAdmin(AdminViewsController::showProxy))), jade); } /** @@ -136,4 +140,18 @@ public static ModelAndView showPayg(Request request, Response response, User use } return new ModelAndView(data, "controllers/admin/templates/payg.jade"); } + + /** + * Show proxy tab. + * @param request http request + * @param response http response + * @param user current user + * @return the view to show + */ + public static ModelAndView showProxy(Request request, Response response, User user) { + Map data = new HashMap<>(); + ProxySettingsDto proxySettings = ProxySettingsManager.getProxySettings(); + data.put("proxySettings", GSON.toJson(proxySettings)); + return new ModelAndView(data, "controllers/admin/templates/proxy.jade"); + } } diff --git a/java/code/src/com/suse/manager/webui/controllers/admin/templates/proxy.jade b/java/code/src/com/suse/manager/webui/controllers/admin/templates/proxy.jade new file mode 100644 index 000000000000..6452e96f905c --- /dev/null +++ b/java/code/src/com/suse/manager/webui/controllers/admin/templates/proxy.jade @@ -0,0 +1,14 @@ +include /templates/common.jade + +#proxy + +script(type='text/javascript'). + window.csrfToken = "#{csrf_token}"; + +script(type='text/javascript'). + spaImportReactPage('admin/setup/proxy') + .then(function(module) { + module.renderer('proxy', { + proxySettings: !{proxySettings} + }); + }); diff --git a/java/code/src/com/suse/manager/webui/menu/MenuTree.java b/java/code/src/com/suse/manager/webui/menu/MenuTree.java index bbda519ced07..82da94c63f9f 100644 --- a/java/code/src/com/suse/manager/webui/menu/MenuTree.java +++ b/java/code/src/com/suse/manager/webui/menu/MenuTree.java @@ -406,7 +406,7 @@ private MenuItem getAdminNode(Map adminRoles) { .addChild(new MenuItem("Setup Wizard") .withVisibility(adminRoles.get("satellite")) .addChild(new MenuItem("HTTP Proxy") - .withPrimaryUrl("/rhn/admin/setup/ProxySettings.do")) + .withPrimaryUrl("/rhn/manager/admin/setup/proxy")) .addChild(new MenuItem("Mirror Credentials") .withPrimaryUrl("/rhn/admin/setup/MirrorCredentials.do")) .addChild(new MenuItem("Products") diff --git a/java/code/webapp/WEB-INF/pages/admin/setup/proxy-settings.jsp b/java/code/webapp/WEB-INF/pages/admin/setup/proxy-settings.jsp deleted file mode 100644 index d51f5bd61dc6..000000000000 --- a/java/code/webapp/WEB-INF/pages/admin/setup/proxy-settings.jsp +++ /dev/null @@ -1,60 +0,0 @@ -<%@ taglib uri="http://rhn.redhat.com/rhn" prefix="rhn" %> - - - - - -
- - Setup Wizard - - -
-
-
-
-
-
- -
-

- -
-
-
- -
-

- -
-
-
- -
-

- -
-
-
-
- -
-
- -
-
- - diff --git a/java/code/webapp/WEB-INF/struts-config.xml b/java/code/webapp/WEB-INF/struts-config.xml index 102176eaffbd..859e562bfec7 100644 --- a/java/code/webapp/WEB-INF/struts-config.xml +++ b/java/code/webapp/WEB-INF/struts-config.xml @@ -7872,17 +7872,6 @@ - - - - - - --include --include ...` for each of the packages that define as part of our bootstrap repository. +This way we can speed up the synchronization process, and we can bootstrap the clients immediately after that. The rest of the product channels will automatically be synchronized by the scheduled tasks when it reaches the time to do so. + #### Overview of Channels and Repositories The current overview of channels and repositories is as follows: diff --git a/testsuite/features/reposync/allcli_update_activationkeys.feature b/testsuite/features/reposync/allcli_update_activationkeys.feature index 162d31678e14..10bde2353751 100644 --- a/testsuite/features/reposync/allcli_update_activationkeys.feature +++ b/testsuite/features/reposync/allcli_update_activationkeys.feature @@ -43,11 +43,6 @@ Feature: Update activation keys And I wait until I do not see "Loading..." text And I select the parent channel for the "sle_minion" from "selectedBaseChannel" And I wait until I do not see "Loading..." text - And I check "openSUSE 15.5 non oss (x86_64)" - And I check "openSUSE Leap 15.5 non oss Updates (x86_64)" - And I check "openSUSE Leap 15.5 Updates (x86_64)" - And I check "Update repository of openSUSE Leap 15.5 Backports (x86_64)" - And I check "Update repository with updates from SUSE Linux Enterprise 15 for openSUSE Leap 15.5 (x86_64)" And I check "Uyuni Client Tools for openSUSE Leap 15.5 (x86_64) (Development)" And I check "Fake-RPM-SUSE-Channel" And I wait until "Fake-RPM-SUSE-Channel" has been checked @@ -81,11 +76,6 @@ Feature: Update activation keys And I wait until I do not see "Loading..." text And I select the parent channel for the "sle_minion" from "selectedBaseChannel" And I wait until I do not see "Loading..." text - And I check "openSUSE 15.5 non oss (x86_64)" - And I check "openSUSE Leap 15.5 non oss Updates (x86_64)" - And I check "openSUSE Leap 15.5 Updates (x86_64)" - And I check "Update repository of openSUSE Leap 15.5 Backports (x86_64)" - And I check "Update repository with updates from SUSE Linux Enterprise 15 for openSUSE Leap 15.5 (x86_64)" And I check "Uyuni Client Tools for openSUSE Leap 15.5 (x86_64) (Development)" And I check "Fake-RPM-SUSE-Channel" And I wait until "Fake-RPM-SUSE-Channel" has been checked @@ -119,11 +109,6 @@ Feature: Update activation keys And I wait until I do not see "Loading..." text And I select the parent channel for the "sle_minion" from "selectedBaseChannel" And I wait until I do not see "Loading..." text - And I check "openSUSE 15.5 non oss (x86_64)" - And I check "openSUSE Leap 15.5 non oss Updates (x86_64)" - And I check "openSUSE Leap 15.5 Updates (x86_64)" - And I check "Update repository of openSUSE Leap 15.5 Backports (x86_64)" - And I check "Update repository with updates from SUSE Linux Enterprise 15 for openSUSE Leap 15.5 (x86_64)" And I check "Uyuni Client Tools for openSUSE Leap 15.5 (x86_64) (Development)" And I check "Fake-RPM-SUSE-Channel" And I wait until "Fake-RPM-SUSE-Channel" has been checked @@ -156,11 +141,6 @@ Feature: Update activation keys And I wait for child channels to appear And I select the parent channel for the "proxy_traditional" from "selectedBaseChannel" And I wait for child channels to appear - And I check "openSUSE 15.5 non oss (x86_64)" - And I check "openSUSE Leap 15.5 non oss Updates (x86_64)" - And I check "openSUSE Leap 15.5 Updates (x86_64)" - And I check "Update repository of openSUSE Leap 15.5 Backports (x86_64)" - And I check "Update repository with updates from SUSE Linux Enterprise 15 for openSUSE Leap 15.5 (x86_64)" And I check "Uyuni Client Tools for openSUSE Leap 15.5 (x86_64) (Development)" And I check "Uyuni Proxy Devel for openSUSE Leap 15.5 (x86_64)" And I click on "Update Activation Key" diff --git a/testsuite/features/reposync/srv_sync_products.feature b/testsuite/features/reposync/srv_sync_products.feature index 57132017ce36..97c748838d91 100644 --- a/testsuite/features/reposync/srv_sync_products.feature +++ b/testsuite/features/reposync/srv_sync_products.feature @@ -73,6 +73,22 @@ Feature: Synchronize products in the products page of the Setup Wizard Then the SLE15 SP4 product should be added When I wait until all synchronized channels for "sles15-sp4" have finished +@uyuni + Scenario: Partially add openSUSE Leap 15.5 product, only including the required packages to generate the bootstrap repository + When I use spacewalk-common-channel to add channel "opensuse_leap15_5" with arch "x86_64" + And I kill running spacewalk-repo-sync for "opensuse_leap15_5-x86_64" channel + And I use spacewalk-repo-sync to sync channel "opensuse_leap15_5-x86_64" including "python3-ply dmidecode libunwind" packages + And I use spacewalk-common-channel to add all "leap15.5-client-tools" channels with arch "x86_64" + And I wait until all synchronized channels for "leap15.5-client-tools-x86_64" have finished + +@containerized_server +@proxy +@uyuni +Scenario: Add openSUSE Leap Micro 5.5 Proxy, including Uyuni Client Tools + # TODO: Refactor the scenarios in order to not require a full synchronization of Uyuni proxy product (OpenSUSE Micro 5.5) + When I use spacewalk-common-channel to add all "uyuni-proxy" channels with arch "x86_64" + And I wait until all synchronized channels for "uyuni-proxy" have finished + @scc_credentials @uyuni Scenario: Synchronize SLES 15 SP4 product with recommended sub-products for Retail feature diff --git a/testsuite/features/secondary/min_ansible_control_node.feature b/testsuite/features/secondary/min_ansible_control_node.feature index acdcff600749..091f7323b388 100644 --- a/testsuite/features/secondary/min_ansible_control_node.feature +++ b/testsuite/features/secondary/min_ansible_control_node.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2024 SUSE LLC +# Copyright (c) 2021-2025 SUSE LLC # Licensed under the terms of the MIT license. @scope_ansible @@ -9,17 +9,12 @@ Feature: Operate an Ansible control node in a normal minion Scenario: Pre-requisite: Deploy test playbooks and inventory file When I deploy testing playbooks and inventory files to "sle_minion" -@skip_if_github_validation -@susemanager - Scenario: Pre-requisite: Enable client tools repositories - When I enable the repositories "tools_update_repo tools_pool_repo" on this "sle_minion" - And I refresh the metadata for "sle_minion" - # TODO: Check why tools_update_repo is not available on the openSUSE minion +# TODO: Check why tools_update_repo is not available on the openSUSE minion @skip_if_github_validation @uyuni - Scenario: Pre-requisite: Enable client tools repositories - When I enable the repositories "tools_pool_repo os_pool_repo" on this "sle_minion" + Scenario: Pre-requisite: Enable OS pool repository + When I enable repository "os_pool_repo" on this "sle_minion" And I refresh the metadata for "sle_minion" Scenario: Enable "Ansible control node" system type @@ -90,16 +85,9 @@ Feature: Operate an Ansible control node in a normal minion And I remove package "orion-dummy" from this "sle_minion" without error control And I remove "/tmp/file.txt" from "sle_minion" -@skip_if_github_validation -@susemanager - Scenario: Cleanup: Disable client tools repositories - Given I am on the Systems overview page of this "sle_minion" - When I disable the repositories "tools_update_repo tools_pool_repo" on this "sle_minion" - And I refresh the metadata for "sle_minion" - @skip_if_github_validation @uyuni - Scenario: Cleanup: Disable client tools repositories + Scenario: Cleanup: Disable OS pool repository Given I am on the Systems overview page of this "sle_minion" - When I disable the repositories "tools_pool_repo os_pool_repo" on this "sle_minion" + When I disable repository "os_pool_repo" on this "sle_minion" And I refresh the metadata for "sle_minion" diff --git a/testsuite/features/secondary/min_deblike_monitoring.feature b/testsuite/features/secondary/min_deblike_monitoring.feature index 41f56c056c3f..882b6d359d79 100644 --- a/testsuite/features/secondary/min_deblike_monitoring.feature +++ b/testsuite/features/secondary/min_deblike_monitoring.feature @@ -12,10 +12,6 @@ Feature: Monitor SUMA environment with Prometheus on a Debian-like Salt minion As an authorized user I want to enable Prometheus exporters -@skip_if_github_validation - Scenario: Pre-requisite: enable Prometheus exporters repository on the Debian-like minion - When I enable the necessary repositories before installing Prometheus exporters on this "deblike_minion" - Scenario: Log in as org admin user Given I am authorized @@ -69,7 +65,3 @@ Feature: Monitor SUMA environment with Prometheus on a Debian-like Salt minion And I click on "Apply Highstate" Then I should see a "Applying the highstate has been scheduled." text And I wait until event "Apply highstate scheduled" is completed - -@skip_if_github_validation - Scenario: Cleanup: disable Prometheus exporters repository on the Debian-like minion - When I disable the necessary repositories before installing Prometheus exporters on this "deblike_minion" without error control diff --git a/testsuite/features/secondary/min_deblike_openscap_audit.feature b/testsuite/features/secondary/min_deblike_openscap_audit.feature index 1e6d1e85b412..9a34f22b85c0 100644 --- a/testsuite/features/secondary/min_deblike_openscap_audit.feature +++ b/testsuite/features/secondary/min_deblike_openscap_audit.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2023 SUSE LLC +# Copyright (c) 2017-2025 SUSE LLC # Licensed under the terms of the MIT license. @scope_openscap @@ -16,7 +16,6 @@ Feature: OpenSCAP audit of Debian-like Salt minion @skip_if_github_validation Scenario: Enable all the necessary repositories for OpenSCAP on Debian-like minion When I enable Debian-like "universe" repository on "deblike_minion" - And I enable the repositories "tools_update_repo tools_pool_repo" on this "deblike_minion" @skip_if_github_validation Scenario: Install the OpenSCAP packages on the Debian-like minion @@ -84,5 +83,4 @@ Feature: OpenSCAP audit of Debian-like Salt minion @skip_if_github_validation Scenario: Cleanup: remove all the necessary repositories for OpenSCAP on Debian-like minion - When I disable the repositories "tools_update_repo tools_pool_repo" on this "deblike_minion" And I disable Debian-like "universe" repository on "deblike_minion" diff --git a/testsuite/features/secondary/min_monitoring.feature b/testsuite/features/secondary/min_monitoring.feature index e4c7514a45d6..869027cfd322 100644 --- a/testsuite/features/secondary/min_monitoring.feature +++ b/testsuite/features/secondary/min_monitoring.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2024 SUSE LLC +# Copyright (c) 2022-2025 SUSE LLC # Licensed under the terms of the MIT license. # This feature depends on: # - features/secondary/srv_monitoring.feature : As this feature disable/re-enable monitoring capabilities @@ -11,11 +11,6 @@ Feature: Monitor SUMA environment with Prometheus on a SLE Salt minion As an authorized user I want to enable Prometheus exporters -@skip_if_github_validation - Scenario: Pre-requisite: enable Prometheus exporters repository on the minion - When I enable the necessary repositories before installing Prometheus exporters on this "sle_minion" - And I refresh the metadata for "sle_minion" - Scenario: Log in as org admin user Given I am authorized @@ -56,7 +51,7 @@ Feature: Monitor SUMA environment with Prometheus on a SLE Salt minion Then I should see a "Applying the highstate has been scheduled." text And I wait until event "Apply highstate scheduled" is completed -@skip_if_github_validation +@skip_if_github_validation Scenario: Wait for services When I wait until "prometheus" service is active on "sle_minion" And I wait until "node" exporter service is active on "sle_minion" @@ -82,7 +77,3 @@ Feature: Monitor SUMA environment with Prometheus on a SLE Salt minion And I click on "Apply Highstate" Then I should see a "Applying the highstate has been scheduled." text And I wait until event "Apply highstate scheduled" is completed - -@skip_if_github_validation - Scenario: Cleanup: disable Prometheus exporters repository - When I disable the necessary repositories before installing Prometheus exporters on this "sle_minion" without error control diff --git a/testsuite/features/secondary/min_rhlike_monitoring.feature b/testsuite/features/secondary/min_rhlike_monitoring.feature index a61a6ebd6f88..0b3fd5f22b24 100644 --- a/testsuite/features/secondary/min_rhlike_monitoring.feature +++ b/testsuite/features/secondary/min_rhlike_monitoring.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2024 SUSE LLC +# Copyright (c) 2022-2025 SUSE LLC # Licensed under the terms of the MIT license. # This feature depends on: # - features/secondary/srv_monitoring.feature: as this feature disables/re-enables monitoring capabilities @@ -12,10 +12,6 @@ Feature: Monitor SUMA environment with Prometheus on a Red Hat-like Salt minion As an authorized user I want to enable Prometheus exporters -@skip_if_github_validation - Scenario: Pre-requisite: enable Prometheus exporters repository on the Red Hat-like minion - When I enable the necessary repositories before installing Prometheus exporters on this "rhlike_minion" - Scenario: Log in as org admin user Given I am authorized @@ -39,14 +35,14 @@ Feature: Monitor SUMA environment with Prometheus on a Red Hat-like Salt minion And I click on "Save" Then I should see a "Formula saved" text -@skip_if_github_validation +@skip_if_github_validation Scenario: Apply highstate for Prometheus exporters on the Red Hat-like minion When I follow "States" in the content area And I click on "Apply Highstate" Then I should see a "Applying the highstate has been scheduled." text And I wait until event "Apply highstate scheduled" is completed -@skip_if_github_validation +@skip_if_github_validation Scenario: Wait for service When I wait until "node" exporter service is active on "rhlike_minion" And I wait until "apache" exporter service is active on "rhlike_minion" @@ -63,13 +59,9 @@ Feature: Monitor SUMA environment with Prometheus on a Red Hat-like Salt minion And I click on "Save" Then I wait until I see "Formula saved" text -@skip_if_github_validation +@skip_if_github_validation Scenario: Cleanup: apply highstate after test monitoring on the Red Hat-like minion When I follow "States" in the content area And I click on "Apply Highstate" Then I should see a "Applying the highstate has been scheduled." text And I wait until event "Apply highstate scheduled" is completed - -@skip_if_github_validation - Scenario: Cleanup: disable Prometheus exporters repository on the Red Hat-like minion - When I disable the necessary repositories before installing Prometheus exporters on this "rhlike_minion" without error control diff --git a/testsuite/features/secondary/min_rhlike_openscap_audit.feature b/testsuite/features/secondary/min_rhlike_openscap_audit.feature index b7760ce71ee0..c4746c8091ba 100644 --- a/testsuite/features/secondary/min_rhlike_openscap_audit.feature +++ b/testsuite/features/secondary/min_rhlike_openscap_audit.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2024 SUSE LLC +# Copyright (c) 2017-2025 SUSE LLC # Licensed under the terms of the MIT license. @scope_openscap @@ -16,7 +16,6 @@ Feature: OpenSCAP audit of Red Hat-like Salt minion @skip_if_github_validation Scenario: Enable repositories for openSCAP on the Red Hat-like minion When I enable the repositories "Rocky-BaseOS Rocky-AppStream" on this "rhlike_minion" - And I enable the repositories "tools_update_repo tools_pool_repo" on this "rhlike_minion" And I refresh the metadata for "rhlike_minion" @skip_if_github_validation @@ -83,7 +82,6 @@ Feature: OpenSCAP audit of Red Hat-like Salt minion Scenario: Cleanup: remove the OpenSCAP packages from the Red Hat-like minion When I remove OpenSCAP dependencies from "rhlike_minion" And I disable repository "Rocky-BaseOS" on this "rhlike_minion" - And I disable the repositories "tools_update_repo tools_pool_repo" on this "rhlike_minion" @skip_if_github_validation Scenario: Cleanup: restore the base channel for the Red Hat-like minion diff --git a/testsuite/features/secondary/minssh_ansible_control_node.feature b/testsuite/features/secondary/minssh_ansible_control_node.feature index 701229a6282a..fef2619c79b8 100644 --- a/testsuite/features/secondary/minssh_ansible_control_node.feature +++ b/testsuite/features/secondary/minssh_ansible_control_node.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2024 SUSE LLC +# Copyright (c) 2021-2025 SUSE LLC # Licensed under the terms of the MIT license. @skip_if_github_validation @@ -13,15 +13,10 @@ Feature: Operate an Ansible control node in SSH minion Scenario: Pre-requisite: Deploy test playbooks and inventory file When I deploy testing playbooks and inventory files to "ssh_minion" -@susemanager - Scenario: Pre-requisite: Enable client tools repositories - When I enable the repositories "tools_update_repo tools_pool_repo" on this "ssh_minion" - And I refresh the metadata for "ssh_minion" - # TODO: Check why tools_update_repo is not available on the openSUSE minion @uyuni - Scenario: Pre-requisite: Enable client tools repositories - When I enable the repositories "tools_pool_repo os_pool_repo" on this "ssh_minion" + Scenario: Pre-requisite: Enable OS pool repository + When I enable repository "os_pool_repo" on this "ssh_minion" And I refresh the metadata for "ssh_minion" Scenario: Enable "Ansible control node" system type @@ -92,14 +87,8 @@ Feature: Operate an Ansible control node in SSH minion And I remove package "orion-dummy" from this "ssh_minion" without error control And I remove "/tmp/file.txt" from "ssh_minion" -@susemanager - Scenario: Cleanup: Disable client tools repositories - Given I am on the Systems overview page of this "ssh_minion" - When I disable the repositories "tools_update_repo tools_pool_repo" on this "ssh_minion" - And I refresh the metadata for "ssh_minion" - @uyuni - Scenario: Cleanup: Disable client tools repositories + Scenario: Cleanup: Disable OS pool repository Given I am on the Systems overview page of this "ssh_minion" - When I disable the repositories "tools_pool_repo os_pool_repo" on this "ssh_minion" + When I disable repository "os_pool_repo" on this "ssh_minion" And I refresh the metadata for "ssh_minion" diff --git a/testsuite/features/step_definitions/command_steps.rb b/testsuite/features/step_definitions/command_steps.rb index a302ccd6b1fa..d1a3ac3c6aeb 100644 --- a/testsuite/features/step_definitions/command_steps.rb +++ b/testsuite/features/step_definitions/command_steps.rb @@ -169,19 +169,18 @@ channels_to_synchronize.each do |os_product_version_channel| command = "spacewalk-common-channels -u admin -p admin -a #{architecture} #{os_product_version_channel.gsub("-#{architecture}", '')}" - _out, code = get_target('server').run(command, check_errors: false) - if code.zero? - log "Channel #{os_product_version_channel.gsub("-#{architecture}", '')} added" - else - command = "spacewalk-common-channels -u admin -p admin -a #{architecture} #{os_product_version_channel}" - get_target('server').run(command) - log "Channel #{os_product_version_channel} added" - end + get_target('server').run(command, verbose: true) + log "Channel #{os_product_version_channel} added" end end When(/^I use spacewalk-repo-sync to sync channel "([^"]*)"$/) do |channel| - $command_output, _code = get_target('server').run_until_ok("spacewalk-repo-sync -c #{channel}") + $command_output, _code = get_target('server').run("spacewalk-repo-sync -c #{channel}", check_errors: false, verbose: true) +end + +When(/^I use spacewalk-repo-sync to sync channel "([^"]*)" including "([^"]*)" packages?$/) do |channel, packages| + append_includes = packages.split.map { |pkg| "--include #{pkg}" }.join(' ') + $command_output, _code = get_target('server').run("spacewalk-repo-sync -c #{channel} #{append_includes}", check_errors: false, verbose: true) end When(/^I use spacewalk-repo-sync to sync channel "([^"]*)" including "([^"]*)" packages?$/) do |channel, packages| @@ -356,7 +355,7 @@ # Remove from the list to kill those channels that are already synced channels_to_kill.each do |remaining_channel| - if channel_is_synced(remaining_channel) + if channel_sync_completed?(remaining_channel) log "Channel '#{remaining_channel}' is already synced, so there is no need to kill repo-sync process." channels_to_kill.delete(remaining_channel) end @@ -365,6 +364,28 @@ end end +When(/^I kill running spacewalk-repo-sync for "([^"]*)" channel$/) do |channel| + time_spent = 0 + checking_rate = 5 + repeat_until_timeout(timeout: 60, message: 'Some reposync processes were not killed properly', dont_raise: true) do + command_output, _code = get_target('server').run('ps axo pid,cmd | grep spacewalk-repo-sync | grep -v grep', verbose: true, check_errors: false) + process = command_output.split("\n")[0] + channel_synchronizing = process.split[5].strip + if process.nil? + log "#{time_spent / 60.to_i} minutes waiting for '#{channel}' channel to start its repo-sync processes." if ((time_spent += checking_rate) % 60).zero? + sleep checking_rate + next + elsif channel_synchronizing == channel + pid = process.split[0] + get_target('server').run("kill #{pid}", verbose: true, check_errors: false) + log "Reposync of channel #{channel} killed" + break + else + log "Warning: Repo-sync process for channel '#{channel_synchronizing}' running." + end + end +end + Then(/^the reposync logs should not report errors$/) do result, code = get_target('server').run('grep -i "ERROR:" /var/log/rhn/reposync/*.log', check_errors: false) raise ScriptError, "Errors during reposync:\n#{result}" if code.zero? @@ -406,7 +427,7 @@ end begin repeat_until_timeout(timeout: timeout, message: 'Channel not fully synced') do - break if channel_is_synced(channel) + break if channel_sync_completed?(channel) log "#{time_spent / 60.to_i} minutes out of #{timeout / 60.to_i} waiting for '#{channel}' channel to be synchronized" if ((time_spent += checking_rate) % 60).zero? sleep checking_rate @@ -428,7 +449,7 @@ time_spent = 0 checking_rate = 10 # Let's start with a timeout margin aside from the sum of the timeouts for each channel - timeout = 600 + timeout = 900 channels_to_wait.each do |channel| if TIMEOUT_BY_CHANNEL_NAME[channel].nil? log "Unknown timeout for channel #{channel}, assuming one minute" @@ -440,7 +461,7 @@ begin repeat_until_timeout(timeout: timeout, message: 'Product not fully synced') do channels_to_wait.each do |channel| - if channel_is_synced(channel) + if channel_sync_completed?(channel) channels_to_wait.delete(channel) log "Channel #{channel} finished syncing" end @@ -1301,23 +1322,6 @@ end end -When(/^I (enable|disable) the necessary repositories before installing Prometheus exporters on this "([^"]*)"((?: without error control)?)$/) do |action, host, error_control| - node = get_target(host) - os_version = node.os_version.gsub('-SP', '.') - os_family = node.os_family - # TODO: Check why tools_update_repo is not available on the openSUSE minion - repositories = os_family.match?(/^opensuse/) ? 'tools_pool_repo' : 'tools_pool_repo tools_update_repo' - if (os_family.match?(/^opensuse/) || os_family.match?(/^sles/)) && (product != 'Uyuni') - repositories.concat(' tools_additional_repo') - # Needed because in SLES15SP3 and openSUSE 15.3 and higher, firewalld will replace this package. - # But the tools_update_repo's priority doesn't allow to cope with the obsoletes option from firewalld. - if os_version.to_f >= 15.3 - node.run('zypper addlock -r tools_additional_repo firewalld-prometheus-config') - end - end - step %(I #{action} the repositories "#{repositories}" on this "#{host}"#{error_control}) -end - When(/^I apply "([^"]*)" local salt state on "([^"]*)"$/) do |state, host| node = get_target(host) salt_call = use_salt_bundle ? 'venv-salt-call' : 'salt-call' diff --git a/testsuite/features/support/commonlib.rb b/testsuite/features/support/commonlib.rb index c7a2e65def91..de1e02c3847f 100644 --- a/testsuite/features/support/commonlib.rb +++ b/testsuite/features/support/commonlib.rb @@ -584,11 +584,36 @@ def update_controller_ca certutil -d sql:/root/.pki/nssdb -A -t TC -n "susemanager" -i /etc/pki/trust/anchors/#{server_name}.cert` end +# This method checks if the synchronization for the given channel is completed +# +# @param channel_name [String] the channel to check +# @return [Boolean] true if the synchronization is completed, false otherwise +def channel_sync_completed?(channel_name) + log_tmp_file = '/tmp/reposync.log' + get_target('server').extract('/var/log/rhn/reposync.log', log_tmp_file) + raise ScriptError, 'The file with repository synchronization logs doesn\'t exist or is empty' if !File.exist?(log_tmp_file) || File.empty?(log_tmp_file) + + log_content = File.readlines(log_tmp_file) + channel_found = false + log_content.each do |line| + if line.include?('Channel: ') && line.include?(channel_name) + channel_found = true + elsif line.include?('Channel: ') && !line.include?(channel_name) + channel_found = false + elsif line.include?('Sync of channel completed.') && channel_found + return true + end + end + + false +end + +# TODO: This method is not used anywhere, consider removing it # Determines whether a channel is synchronized on the server. # # @param channel [String] The name of the channel to check. # @return [Boolean] Returns true if the channel is synchronized, false otherwise. -def channel_is_synced(channel) +def channel_is_synced?(channel) sync_status = false # solv is the last file to be written when the server synchronizes a channel, therefore we wait until it exist result, code = get_target('server').run("dumpsolv /var/cache/rhn/repodata/#{channel}/solv", verbose: false, check_errors: false) @@ -736,9 +761,13 @@ def wait_action_complete(actionid, timeout: DEFAULT_TIMEOUT) # @param channels [Array] The list of channels to filter. # @param filters [Array] The list of filters to apply. def filter_channels(channels, filters = []) - filtered_channels = channels.clone - filters.each do |filter| - filtered_channels.delete_if { |channel| channel.include? filter } + if channels.nil? || channels.empty? + puts 'Warning: No channels to filter' + else + filtered_channels = channels.clone + filters.each do |filter| + filtered_channels.delete_if { |channel| channel.include? filter } + end end filtered_channels end diff --git a/testsuite/features/support/constants.rb b/testsuite/features/support/constants.rb index 9d7652c0a779..1033e343cf49 100644 --- a/testsuite/features/support/constants.rb +++ b/testsuite/features/support/constants.rb @@ -1432,9 +1432,9 @@ 'opensuse_leap15_5-aarch64-non-oss-updates' => 60, 'opensuse_leap15_5-aarch64-sle-updates' => 4140, 'opensuse_leap15_5-aarch64-updates' => 60, - 'opensuse_leap15_5-uyuni-client-devel-aarch64' => 60, - 'opensuse_leap15_5-uyuni-client-devel-x86_64' => 60, - 'opensuse_leap15_5-uyuni-client-x86_64' => 60, + 'opensuse_leap15_5-uyuni-client-devel-aarch64' => 120, + 'opensuse_leap15_5-uyuni-client-devel-x86_64' => 120, + 'opensuse_leap15_5-uyuni-client-x86_64' => 120, 'opensuse_leap15_5-x86_64' => 10_380, 'opensuse_leap15_5-x86_64-backports-updates' => 360, 'opensuse_leap15_5-x86_64-non-oss' => 60, @@ -1447,9 +1447,9 @@ 'opensuse_leap15_6-aarch64-non-oss-updates' => 60, 'opensuse_leap15_6-aarch64-sle-updates' => 4140, 'opensuse_leap15_6-aarch64-updates' => 60, - 'opensuse_leap15_6-uyuni-client-devel-aarch64' => 60, - 'opensuse_leap15_6-uyuni-client-devel-x86_64' => 60, - 'opensuse_leap15_6-uyuni-client-x86_64' => 60, + 'opensuse_leap15_6-uyuni-client-devel-aarch64' => 120, + 'opensuse_leap15_6-uyuni-client-devel-x86_64' => 120, + 'opensuse_leap15_6-uyuni-client-x86_64' => 120, 'opensuse_leap15_6-x86_64' => 10_380, 'opensuse_leap15_6-x86_64-backports-updates' => 360, 'opensuse_leap15_6-x86_64-non-oss' => 60, @@ -1460,25 +1460,25 @@ 'opensuse-leap-15.6-updates-aarch64' => 60, 'opensuse-backports-15.6-updates-aarch64' => 60, 'opensuse-sle-15.6-updates-aarch64' => 60, - 'opensuse_micro5_5-uyuni-client-x86_64' => 60, - 'opensuse_micro5_5-uyuni-client-devel-x86_64' => 60, + 'opensuse_micro5_5-uyuni-client-x86_64' => 120, + 'opensuse_micro5_5-uyuni-client-devel-x86_64' => 120, 'opensuse_micro5_5-x86_64' => 240, 'opensuse_micro5_5-x86_64-sle-updates' => 5400, 'oraclelinux9-appstream-x86_64' => 2100, - 'oraclelinux9-uyuni-client-devel-x86_64' => 60, + 'oraclelinux9-uyuni-client-devel-x86_64' => 120, 'oraclelinux9-x86_64' => 840, 'res-7-ltss-updates-x86_64' => 960, 'res-7-suse-manager-tools-x86_64-lbt7' => 120, 'res7-suse-manager-tools-x86_64' => 300, 'res7-x86_64' => 21_000, 'rhel-x86_64-server-7' => 60, - 'rockylinux8-uyuni-client-devel-x86_64' => 60, + 'rockylinux8-uyuni-client-devel-x86_64' => 120, 'rocky-8-iso' => 600, 'rockylinux8-x86_64' => 600, 'rockylinux8-x86_64-appstream' => 1260, 'rockylinux8-x86_64-extras' => 420, 'rockylinux9-appstream-x86_64' => 480, - 'rockylinux9-uyuni-client-devel-x86_64' => 60, + 'rockylinux9-uyuni-client-devel-x86_64' => 120, 'rockylinux9-x86_64' => 120, 'rockylinux9-x86_64-extras' => 120, 'sle15-sp2-installer-updates-x86_64' => 60, @@ -1513,19 +1513,19 @@ 'sle-manager-tools-for-micro5-updates-x86_64-5.3' => 120, 'sle-manager-tools-for-micro5-updates-x86_64-5.4' => 120, 'sle-manager-tools-for-micro5-updates-x86_64-5.5' => 120, - 'sle-micro-5.3-devel-uyuni-client-x86_64' => 60, + 'sle-micro-5.3-devel-uyuni-client-x86_64' => 120, 'sle-micro-5.3-pool-x86_64' => 120, 'sle-micro-5.3-updates-x86_64' => 240, - 'sle-micro-5.4-devel-uyuni-client-x86_64' => 60, + 'sle-micro-5.4-devel-uyuni-client-x86_64' => 120, 'sle-micro-5.4-pool-x86_64' => 60, 'sle-micro-5.4-updates-x86_64' => 60, - 'sle-micro-5.5-devel-uyuni-client-x86_64' => 60, + 'sle-micro-5.5-devel-uyuni-client-x86_64' => 120, 'sle-micro-5.5-pool-x86_64' => 120, 'sle-micro-5.5-updates-x86_64' => 120, 'sl-micro-6.0-pool-x86_64' => 120, - 'sl-micro-6.0-devel-uyuni-client-x86_64' => 60, + 'sl-micro-6.0-devel-uyuni-client-x86_64' => 120, 'sl-micro-6.1-pool-x86_64' => 120, - 'sl-micro-6.1-devel-uyuni-client-x86_64' => 60, + 'sl-micro-6.1-devel-uyuni-client-x86_64' => 120, 'sle-module-basesystem15-sp2-pool-x86_64' => 180, 'sle-module-basesystem15-sp2-updates-x86_64' => 660, 'sle-module-basesystem15-sp3-pool-x86_64' => 240, @@ -1610,11 +1610,11 @@ 'sles12-sp5-pool-x86_64' => 180, 'sles12-sp5-updates-x86_64' => 2280, 'sles12-sp5-uyuni-client-devel-x86_64' => 120, - 'sles15-sp2-devel-uyuni-client-x86_64' => 60, - 'sles15-sp3-devel-uyuni-client-x86_64' => 60, - 'sles15-sp4-devel-uyuni-client-x86_64' => 60, - 'sles15-sp5-devel-uyuni-client-x86_64' => 60, - 'sles15-sp6-devel-uyuni-client-x86_64' => 60, + 'sles15-sp2-devel-uyuni-client-x86_64' => 120, + 'sles15-sp3-devel-uyuni-client-x86_64' => 120, + 'sles15-sp4-devel-uyuni-client-x86_64' => 120, + 'sles15-sp5-devel-uyuni-client-x86_64' => 120, + 'sles15-sp6-devel-uyuni-client-x86_64' => 120, 'sll-9-updates-x86_64' => 720, 'sll-as-9-updates-x86_64' => 1620, 'sll-cb-9-updates-x86_64' => 2640, @@ -1622,10 +1622,10 @@ 'suse-manager-proxy-5.0-updates-x86_64' => 60, 'suse-manager-retail-branch-server-5.0-pool-x86_64' => 60, 'suse-manager-retail-branch-server-5.0-updates-x86_64' => 60, - 'suse-microos-5.1-devel-uyuni-client-x86_64' => 60, + 'suse-microos-5.1-devel-uyuni-client-x86_64' => 120, 'suse-microos-5.1-pool-x86_64' => 60, 'suse-microos-5.1-updates-x86_64' => 300, - 'suse-microos-5.2-devel-uyuni-client-x86_64' => 60, + 'suse-microos-5.2-devel-uyuni-client-x86_64' => 120, 'suse-microos-5.2-pool-x86_64' => 60, 'suse-microos-5.2-updates-x86_64' => 60, 'suse-manager-tools-for-sl-micro-6.0-x86_64' => 60, @@ -1641,7 +1641,7 @@ 'ubuntu-2004-amd64-universe-security-uyuni' => 900, 'ubuntu-2004-amd64-universe-updates-uyuni' => 240, 'ubuntu-2004-amd64-universe-uyuni' => 19_560, - 'ubuntu-2004-amd64-uyuni-client-devel' => 60, + 'ubuntu-2004-amd64-uyuni-client-devel' => 120, 'ubuntu-2004-pool-amd64-uyuni' => 60, 'ubuntu-20.04-suse-manager-tools-amd64' => 120, 'ubuntu-2204-amd64-main-amd64' => 780, @@ -1654,7 +1654,7 @@ 'ubuntu-2204-amd64-universe-security-uyuni' => 1020, 'ubuntu-2204-amd64-universe-updates-uyuni' => 240, 'ubuntu-2204-amd64-universe-uyuni' => 24_000, - 'ubuntu-2204-amd64-uyuni-client-devel' => 60, + 'ubuntu-2204-amd64-uyuni-client-devel' => 120, 'ubuntu-2204-pool-amd64-uyuni' => 60, 'ubuntu-22.04-suse-manager-tools-amd64' => 120, 'ubuntu-2404-amd64-main-amd64' => 780, @@ -1667,7 +1667,7 @@ 'ubuntu-2404-amd64-universe-security-uyuni' => 1020, 'ubuntu-2404-amd64-universe-updates-uyuni' => 240, 'ubuntu-2404-amd64-universe-uyuni' => 24_000, - 'ubuntu-2404-amd64-uyuni-client-devel' => 60, + 'ubuntu-2404-amd64-uyuni-client-devel' => 120, 'ubuntu-2404-pool-amd64-uyuni' => 60, 'ubuntu-24.04-suse-manager-tools-amd64' => 120, 'uyuni-proxy-devel-leap-x86_64' => 60, diff --git a/web/html/javascript/spacewalk-essentials.js b/web/html/javascript/spacewalk-essentials.js index f5866b8a68c1..7245c59fbec5 100644 --- a/web/html/javascript/spacewalk-essentials.js +++ b/web/html/javascript/spacewalk-essentials.js @@ -215,21 +215,6 @@ function showFatalError(message, exception) { } } -/** - * Checks if the provided string is a valid URL. - * - * @param {string} url - The URL string to validate. - * @returns {boolean} - `true` if the string is a valid URL, otherwise `false`. - */ -function isValidUrl(url) { - try { - new URL(url); - return true; - } catch (_) { - return false; - } -} - /** * Escapes special HTML characters in a string. * @param {string} original - The string that may contain special HTML characters. diff --git a/web/html/javascript/susemanager-setup-wizard-proxy-settings.js b/web/html/javascript/susemanager-setup-wizard-proxy-settings.js deleted file mode 100644 index 1a7329541b0e..000000000000 --- a/web/html/javascript/susemanager-setup-wizard-proxy-settings.js +++ /dev/null @@ -1,114 +0,0 @@ -// Save and verifiy the proxy settings -function saveProxySettings() { - hostname = jQuery('#http-proxy-input-hostname').val(); - username = escapeHtml(jQuery('#http-proxy-input-username').val()); - password = jQuery('#http-proxy-input-password').val(); - - if (hostname.trim() !== "" && !isValidUrl(hostname)) { - alert("Proxy Hostname is not a valid URL."); - return; - } - - showSpinner('http-proxy-verify'); - jQuery('#http-proxy-verify').show(0); - jQuery('#http-proxy-save').attr('disabled', true); - - function onSuccess(settings) { - jQuery('#http-proxy-save').prop('disabled', false); - // TODO make sure it succeeded - setProxySettings(settings); - setProxySettingsEditable(false); - - // Force refresh of the cache - verifyProxySettings(true); - } - - ajax("save-proxy-settings", { hostname, username, password }, onSuccess) -} - -// sets in the UI if the proxy settings were verified -function setProxySettingsVerified(result) { - const valid = JSON.parse(result) - if (valid) { - jQuery('#http-proxy-verify').html(''); - } else { - jQuery('#http-proxy-verify').html(''); - } -} - -// verify the proxy settings on the server side, pass true to refresh the cache -function verifyProxySettings(forceRefresh) { - showSpinner('http-proxy-verify'); - ajax('verify-proxy-settings', { forceRefresh }, setProxySettingsVerified, 'application/json') -} - -// just sets the given settings in the form -function setProxySettings(settings) { - jQuery('#http-proxy-input-hostname').val(settings.hostname); - jQuery('p.http-proxy-hostname').html(settings.hostname); - - jQuery('#http-proxy-input-username').val(settings.username); - jQuery('p.http-proxy-username').html(settings.username); - - if (settings.hostname) { - jQuery('p.http-proxy-password').html(Array(8).join('●')); - } else { - jQuery('p.http-proxy-password').html(""); - } -} - -// Sets the spinner, retrieves the settings from the server -// and puts them in the UI, which ends in an editable form -// if there is no proxy set -function retrieveProxySettings() { - showSpinner('http-proxy-verify'); - - function onSuccess(settings) { - setProxySettings(settings); - - if (settings.hostname) { - verifyProxySettings(false); - } else { - setProxySettingsEditable(true); - } - } - - ajax('retrieve-proxy-settings', '', onSuccess, 'application/json') -} - -// Switches the proxy settings into an (non)editable form -function setProxySettingsEditable(editable) { - if (editable) { - jQuery('#http-proxy form p.form-control-static').hide(); - jQuery('#http-proxy form input.form-control').show(0); - jQuery('#http-proxy-edit').hide(0); - jQuery('#http-proxy-verify').hide(0); - jQuery('#http-proxy-save').show(0); - } else { - jQuery('#http-proxy form input.form-control').hide(); - jQuery('#http-proxy form p.form-control-static').show(0); - jQuery('#http-proxy-edit').show(0); - jQuery('#http-proxy-verify').show(0); - jQuery('#http-proxy-save').hide(0); - } -} - -// only relevant for the proxy settings -jQuery(document).ready(function() { - // set the edit button callback - jQuery('#http-proxy-edit').on("click", function() { - setProxySettingsEditable(true); - }); - - // set the save button callback - jQuery('#http-proxy-save').on("click", function() { - saveProxySettings(); - }); - - jQuery('#http-proxy-verify').on("click", function() { - verifyProxySettings(true); - }); - - setProxySettingsEditable(false); - retrieveProxySettings(); -}); diff --git a/web/html/src/build/fill-spec-file.js b/web/html/src/build/fill-spec-file.js index 64c93dc40c0c..b10bb3c33db4 100644 --- a/web/html/src/build/fill-spec-file.js +++ b/web/html/src/build/fill-spec-file.js @@ -17,7 +17,7 @@ function fillSpecFile() { } return item; }); - const mappedProcessedLicenses = Array.from(new Set(processedLicenses)).sort().join(" AND "); + const mappedProcessedLicenses = Array.from(new Set(processedLicenses)).sort().filter(Boolean).join(" AND "); const specFileLocation = "../../spacewalk-web.spec"; diff --git a/web/html/src/components/input/ControlledInput.tsx b/web/html/src/components/input/ControlledInput.tsx new file mode 100644 index 000000000000..902ffe3ad8b6 --- /dev/null +++ b/web/html/src/components/input/ControlledInput.tsx @@ -0,0 +1,29 @@ +import { InputHTMLAttributes, useEffect, useState } from "react"; + +/** + * @deprecated This is a placeholder fix to ensure input values are always set synchronously. + * This is obsolete once we integrate Formik instead, see https://github.com/SUSE/spacewalk/issues/14250 + * and other related tickets for related info. + */ +export const ControlledInput = (props: InputHTMLAttributes) => { + const { value, ...rest } = props; + + const [internalValue, setInternalValue] = useState(value); + + useEffect(() => { + if (props.value !== internalValue) { + setInternalValue(props.value); + } + }, [props.value]); + + return ( + { + setInternalValue(event.target.value); + props.onChange?.(event); + }} + /> + ); +}; diff --git a/web/html/src/components/input/InputBase.tsx b/web/html/src/components/input/InputBase.tsx index cf4f649cbca3..0c3910f2c7eb 100644 --- a/web/html/src/components/input/InputBase.tsx +++ b/web/html/src/components/input/InputBase.tsx @@ -70,6 +70,8 @@ export type InputBaseProps = { * Takes a name and a value parameter. */ onChange?: (name: string | undefined, value: ValueType) => void; + + autoComplete?: string; }; type State = { @@ -265,7 +267,7 @@ export class InputBase extends React.Component 0) { - hints.push(
); + hints.push(
); } hints.push(hint); } diff --git a/web/html/src/components/input/check/Check.tsx b/web/html/src/components/input/check/Check.tsx index ef78bc7c3a19..bd99ce2543a0 100644 --- a/web/html/src/components/input/check/Check.tsx +++ b/web/html/src/components/input/check/Check.tsx @@ -1,5 +1,6 @@ import * as React from "react"; +import { ControlledInput } from "../ControlledInput"; import { FormContext } from "../form/Form"; import { InputBase, InputBaseProps } from "../InputBase"; @@ -28,7 +29,7 @@ export function Check(props: Props) { return (