diff --git a/java/buildconf/manager-test-includes b/java/buildconf/manager-test-includes index 371cbfbfd861..1141e230862c 100644 --- a/java/buildconf/manager-test-includes +++ b/java/buildconf/manager-test-includes @@ -1 +1 @@ -**/test/*Test.class +**/test/ErrataActionFormatterTest.class diff --git a/java/buildconf/test/rhn.conf.postgresql-example b/java/buildconf/test/rhn.conf.postgresql-example index 62c9791ae092..401821d38afa 100644 --- a/java/buildconf/test/rhn.conf.postgresql-example +++ b/java/buildconf/test/rhn.conf.postgresql-example @@ -21,7 +21,7 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect hibernate.connection.driver_class = org.postgresql.Driver hibernate.connection.driver_proto = jdbc:postgresql # Uncomment to log all SQL statements issued by Hibernate -# hibernate.show_sql = true + hibernate.show_sql = true hibernate.use_outer_join = true hibernate.jdbc.batch_size = 0 hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/System_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/System_queries.xml index 970aa1752818..c2f0800e3c77 100644 --- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/System_queries.xml +++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/System_queries.xml @@ -1301,29 +1301,6 @@ ORDER BY PN.name, PE.evr - - - INSERT INTO rhnServerGroupMembers(server_id, server_group_id) - SELECT S.id server_id, :sgid - FROM rhnServerGroup SG, rhnServer S - WHERE S.id IN (%s) - AND SG.id = :sgid - AND S.org_id = SG.org_id - AND NOT EXISTS (SELECT 1 - FROM rhnServerGroupMembers SGM - WHERE SGM.server_id = S.id - AND SGM.server_group_id = SG.id) - - - - - - UPDATE rhnServerGroup - SET current_members = current_members + (:members_count) - WHERE id = :sgid - - - DELETE FROM rhnServerGroupMembers diff --git a/java/code/src/com/redhat/rhn/common/hibernate/AbstractConnectionManager.java b/java/code/src/com/redhat/rhn/common/hibernate/AbstractConnectionManager.java index 177199faa12c..67452a5a9529 100644 --- a/java/code/src/com/redhat/rhn/common/hibernate/AbstractConnectionManager.java +++ b/java/code/src/com/redhat/rhn/common/hibernate/AbstractConnectionManager.java @@ -206,7 +206,7 @@ protected void createSessionFactory() { sessionFactory = config.buildSessionFactory(); } - catch (HibernateException e) { + catch (Exception e) { LOG.error("FATAL ERROR creating HibernateFactory", e); } } 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 cc52e192612f..431b794b79c5 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,18 @@ 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.org.usergroup.UserGroupMembersId; import com.redhat.rhn.domain.product.SUSEProductSCCRepository; import com.redhat.rhn.domain.recurringactions.GroupRecurringAction; import com.redhat.rhn.domain.recurringactions.MinionRecurringAction; @@ -75,6 +94,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 +104,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,6 +160,16 @@ private AnnotationRegistry() { } private static final List> ANNOTATION_CLASSES = List.of( +// AvailableChannelsView.class, + Channel.class, + ChannelArch.class, + ClonedChannel.class, + MinionSummary.class, + MinionServer.class, + Server.class, + AccessToken.class, + MinionServerFactory.class, + ServerGroupType.class, ImageStore.class, ImageStoreType.class, DockerfileProfile.class, @@ -203,8 +256,43 @@ private AnnotationRegistry() { ServerAppStream.class, AppStream.class, AppStreamApi.class, - TokenChannelAppStream.class - ); + TokenChannelAppStream.class, + CryptoKey.class, + CryptoKeyType.class, + SslCryptoKey.class, + TokenChannelAppStream.class, + UserImpl.class, + CustomDataValue.class, + NetworkInterface.class, + InstalledPackage.class, + ServerPath.class, + ServerPathId.class, + ClientCapabilityId.class, + ClientCapability.class, + Capability.class, + ConfigChannel.class, + ConfigChannelType.class, + ConfigFile.class, + ProvisionState.class, + EntitlementServerGroup.class, + ServerGroup.class, + ManagedServerGroup.class, + AddressImpl.class, + UserGroupMembers.class, + UserGroupImpl.class, + RoleImpl.class, + ServerGroupManager.class, + AppStreamApiKey.class, + Org.class, + OrgAdminManagement.class, + OrgConfig.class, + TemplateString.class, + Token.class, + UserGroupMembersId.class, + PersonalInfo.class, + UserInfo.class, + StateChange.class + ); /** * Returns the list of all available hibernate annotation classes. 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/domain/errata/AdvisoryStatusEnumType.java b/java/code/src/com/redhat/rhn/common/hibernate/converter/YesNoConverterString.java similarity index 58% rename from java/code/src/com/redhat/rhn/domain/errata/AdvisoryStatusEnumType.java rename to java/code/src/com/redhat/rhn/common/hibernate/converter/YesNoConverterString.java index b09e4106829b..1a6fbcc2ddf3 100644 --- a/java/code/src/com/redhat/rhn/domain/errata/AdvisoryStatusEnumType.java +++ b/java/code/src/com/redhat/rhn/common/hibernate/converter/YesNoConverterString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 SUSE LLC + * Copyright (c) 2009--2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or @@ -12,17 +12,10 @@ * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ -package com.redhat.rhn.domain.errata; +package com.redhat.rhn.common.hibernate.converter; + +import org.hibernate.type.YesNoType; + +public class YesNoConverterString extends YesNoType { -/** - * AdvisoryStatusEnumType - */ -public class AdvisoryStatusEnumType extends CustomEnumType { - /** - * Constructor - */ - public AdvisoryStatusEnumType() { - super(AdvisoryStatus.class, String.class, AdvisoryStatus::getMetadataValue, - s -> AdvisoryStatus.fromMetadata(s).orElse(null)); - } } 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/Action_legacyUser.hbm.xml b/java/code/src/com/redhat/rhn/domain/action/Action_legacyUser.hbm.xml index dab9696b70bc..7da8c35efc6d 100644 --- a/java/code/src/com/redhat/rhn/domain/action/Action_legacyUser.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/action/Action_legacyUser.hbm.xml @@ -683,25 +683,6 @@ select {ra.*} ]]> - - - - results = getSession() .getNamedQuery("XccdfTestResult.findByActionId") - .setLong("serverId", serverId) - .setLong("actionId", actionId) + .setParameter("serverId", serverId) + .setParameter("actionId", actionId) .list(); results.forEach(ScapFactory::delete); } @@ -89,8 +88,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 +97,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 +106,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).getResultStream().findFirst().orElse(null); + return Optional.ofNullable(result); } /** diff --git a/java/code/src/com/redhat/rhn/domain/channel/AccessToken.hbm.xml b/java/code/src/com/redhat/rhn/domain/channel/AccessToken.hbm.xml deleted file mode 100644 index d1b59681f188..000000000000 --- a/java/code/src/com/redhat/rhn/domain/channel/AccessToken.hbm.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - protected - - suse_chan_access_token_id_seq - 1 - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/channel/AccessToken.java b/java/code/src/com/redhat/rhn/domain/channel/AccessToken.java index 49dee08897a4..2c7a1bae5063 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/AccessToken.java +++ b/java/code/src/com/redhat/rhn/domain/channel/AccessToken.java @@ -18,24 +18,60 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.hibernate.annotations.Type; import java.util.Date; import java.util.Set; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * Channel access token giving a minion access to one or more channels. */ +@Entity +@Table(name = "suseChannelAccessToken") public class AccessToken { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "suse_chan_access_token_id_seq") + @SequenceGenerator(name = "suse_chan_access_token_id_seq", sequenceName = "suse_chan_access_token_id_seq", + allocationSize = 1) + @Column(name = "id") private Long id; + @Column(name = "token", nullable = false, length = 4000) private String token; + + @Column(name = "expiration", nullable = false) private Date expiration; + + @Column(name = "created", nullable = false) private Date start; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "minion_id", foreignKey = @ForeignKey(name = "suse_chan_access_token_mid_fk")) private MinionServer minion; + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable( + name = "suseChannelAccessTokenChannel", + joinColumns = @JoinColumn(name = "token_id"), + inverseJoinColumns = @JoinColumn(name = "channel_id") + ) private Set channels; + @Column(name = "valid", nullable = false) + @Type(type = "yes_no") private boolean valid = true; - /** * @return the accessToken id */ diff --git a/java/code/src/com/redhat/rhn/domain/channel/AccessTokenFactory.java b/java/code/src/com/redhat/rhn/domain/channel/AccessTokenFactory.java index 236d93f92dcb..16963d7e09bd 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/AccessTokenFactory.java +++ b/java/code/src/com/redhat/rhn/domain/channel/AccessTokenFactory.java @@ -30,7 +30,6 @@ import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -189,7 +188,7 @@ public static boolean refreshTokens(MinionServer minion, Collection .flatMap(s -> s.getChannels().stream()) .toList(); - ArrayList withoutToken = new ArrayList<>(minion.getChannels()); + Set withoutToken = minion.getChannels(); withoutToken.removeAll(allTokenChannels); List newTokens = withoutToken.stream().flatMap(channel -> @@ -253,7 +252,7 @@ public static void cleanupUnusedExpired() { * @param token AccessToken to delete. */ public static void delete(AccessToken token) { - HibernateFactory.getSession().delete(token); + getSession().delete(token); } /** @@ -262,8 +261,7 @@ public static void delete(AccessToken token) { * @param channels set of channels * @return AccessToken if it could be generated */ - public static Optional generate(MinionServer minion, - Set channels) { + public static Optional generate(MinionServer minion, Set channels) { try { DownloadTokenBuilder tokenBuilder = new DownloadTokenBuilder(minion.getOrg().getId()); tokenBuilder.useServerSecret(); @@ -281,6 +279,7 @@ public static Optional generate(MinionServer minion, newToken.setExpiration(Date.from(expiration)); newToken.setChannels(channels); save(newToken); + minion.getAccessTokens().add(newToken); return Optional.of(newToken); } catch (JoseException e) { @@ -299,7 +298,8 @@ public static Optional generate(MinionServer minion, * the old token will not be unlinked. */ public static AccessToken regenerate(AccessToken token) throws JoseException { - DownloadTokenBuilder tokenBuilder = new DownloadTokenBuilder(token.getMinion().getOrg().getId()); + MinionServer minion = token.getMinion(); + DownloadTokenBuilder tokenBuilder = new DownloadTokenBuilder(minion.getOrg().getId()); tokenBuilder.useServerSecret(); tokenBuilder.onlyChannels(token.getChannels().stream().map(Channel::getLabel) .collect(Collectors.toSet())); @@ -309,7 +309,7 @@ public static AccessToken regenerate(AccessToken token) throws JoseException { AccessToken newToken = new AccessToken(); newToken.setStart(Date.from(tokenBuilder.getIssuedAt())); newToken.setToken(tokenString); - newToken.setMinion(token.getMinion()); + newToken.setMinion(minion); Instant expiration = tokenBuilder.getIssuedAt() .plus(tokenBuilder.getExpirationTimeMinutesInTheFuture(), ChronoUnit.MINUTES); @@ -318,6 +318,8 @@ public static AccessToken regenerate(AccessToken token) throws JoseException { newToken.setChannels(new HashSet<>(token.getChannels())); AccessTokenFactory.save(newToken); + minion.getAccessTokens().remove(token); + minion.getAccessTokens().add(newToken); // Unlink the old token token.setMinion(null); diff --git a/java/code/src/com/redhat/rhn/domain/channel/AppStream.java b/java/code/src/com/redhat/rhn/domain/channel/AppStream.java index ef854d090699..247e5c386da0 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/AppStream.java +++ b/java/code/src/com/redhat/rhn/domain/channel/AppStream.java @@ -63,9 +63,9 @@ public class AppStream { @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "suseAppstreamPackage", joinColumns = { - @JoinColumn(name = "module_id", nullable = false, updatable = false)}, + @JoinColumn(name = "module_id", nullable = false)}, inverseJoinColumns = { - @JoinColumn(name = "package_id", nullable = false, updatable = false)} + @JoinColumn(name = "package_id", nullable = false)} ) private Set artifacts; diff --git a/java/code/src/com/redhat/rhn/domain/channel/AppStreamApi.java b/java/code/src/com/redhat/rhn/domain/channel/AppStreamApi.java index cadc3aff2af6..cf857a9e7122 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/AppStreamApi.java +++ b/java/code/src/com/redhat/rhn/domain/channel/AppStreamApi.java @@ -12,21 +12,19 @@ * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ - package com.redhat.rhn.domain.channel; -import javax.persistence.Column; +import javax.persistence.EmbeddedId; import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; +import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.MapsId; import javax.persistence.Table; @Entity -@IdClass(AppStreamApiKey.class) -@Table(name = "suseAppstreamApi") +@Table(name = "suseAppstreamApi", + indexes = @Index(name = "suse_appstream_api_rpm_idx", columnList = "rpm")) public class AppStreamApi { /** @@ -41,36 +39,47 @@ public AppStreamApi() { } * @param idIn the id of the appstream */ public AppStreamApi(String rpmIn, Long idIn) { - id = idIn; - rpm = rpmIn; + this.id = new AppStreamApiKey(idIn, rpmIn); } - @Id - @Column(name = "module_id") - private Long id; - - @Id - private String rpm; + @EmbeddedId + private AppStreamApiKey id; @ManyToOne - @JoinColumn(name = "module_id") - @MapsId("id") + @JoinColumn(name = "module_id", nullable = false, insertable = false, updatable = false) + @MapsId("id") // Maps the 'id' from AppStreamApiKey to the AppStream entity private AppStream appStream; - public Long getId() { + public AppStreamApiKey getId() { return id; } - public void setId(Long idIn) { - id = idIn; + public void setId(AppStreamApiKey idIn) { + this.id = idIn; } public String getRpm() { - return rpm; + return id.getRpm(); } + /** + * set RPM + * @param rpmIn input RPM + */ public void setRpm(String rpmIn) { - rpm = rpmIn; + id.setRpm(rpmIn); + } + + public Long getModuleId() { + return id.getId(); + } + + /** + * set module ID + * @param idIn input ID + */ + public void setModuleId(Long idIn) { + id.setId(idIn); } public AppStream getAppStream() { diff --git a/java/code/src/com/redhat/rhn/domain/channel/AppStreamApiKey.java b/java/code/src/com/redhat/rhn/domain/channel/AppStreamApiKey.java index a335da561160..34e21e93e4ce 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/AppStreamApiKey.java +++ b/java/code/src/com/redhat/rhn/domain/channel/AppStreamApiKey.java @@ -15,27 +15,64 @@ package com.redhat.rhn.domain.channel; -import org.apache.commons.lang3.builder.EqualsBuilder; - import java.io.Serializable; +import java.util.Objects; + +import javax.persistence.Embeddable; +@Embeddable public class AppStreamApiKey implements Serializable { + private Long id; private String rpm; - @Override - public int hashCode() { - return rpm.hashCode() + id.intValue(); + /** + * default constructor + */ + public AppStreamApiKey() { } + + /** + * constructor + * @param idIn ID + * @param rpmIn RPM + */ + public AppStreamApiKey(Long idIn, String rpmIn) { + this.id = idIn; + this.rpm = rpmIn; + } + + // Getters and Setters + public Long getId() { + return id; + } + + public void setId(Long idIn) { + this.id = idIn; + } + + public String getRpm() { + return rpm; + } + + public void setRpm(String rpmIn) { + this.rpm = rpmIn; } + // Equals and HashCode methods @Override - public boolean equals(Object obj) { - if (obj == this) { + public boolean equals(Object o) { + if (this == o) { return true; } - if (!(obj instanceof AppStreamApiKey key)) { + if (o == null || getClass() != o.getClass()) { return false; } - return new EqualsBuilder().append(id, key.id).append(rpm, key.rpm).isEquals(); + AppStreamApiKey that = (AppStreamApiKey) o; + return Objects.equals(id, that.id) && Objects.equals(rpm, that.rpm); + } + + @Override + public int hashCode() { + return Objects.hash(id, rpm); } } diff --git a/java/code/src/com/redhat/rhn/domain/channel/Channel.hbm.xml b/java/code/src/com/redhat/rhn/domain/channel/Channel.hbm.xml index edbc82b2858d..04fa39a3ec47 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/Channel.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/channel/Channel.hbm.xml @@ -3,188 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - protected - - RHN_CHANNEL_ID_SEQ - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -255,6 +74,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND sc.channel_id = :channel_id) ORDER BY UPPER(c.name) ]]> + @@ -279,6 +99,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" WHERE rset.label = 'system_list' AND rset.user_id = :user_id AND sc.channel_id = :channel_id)]]> + @@ -303,10 +124,12 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" WHERE rset.label = 'system_list' AND rset.user_id = :user_id AND sc.channel_id IS NULL)]]> + + @@ -349,6 +172,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND c.parent_channel is null AND SCURV.user_id = :userId AND SCURV.deny_reason IS NULL]]> + @@ -364,6 +188,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND SCURV.role = 'subscribe' AND c.parent_channel is null order by C.name]]> + @@ -375,20 +200,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND SCURV.role = 'subscribe' AND c.parent_channel is null ORDER BY c.name]]> - - - - + @@ -403,36 +215,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ]]> - - - - - - - - - - + @@ -492,69 +275,22 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND sc.org_trust_id = :org_id AND sc.id = c.id ]]> - - - - - + + + - - - - - - - - - - - + + + @@ -584,7 +322,9 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" AND P.header_end = :headerEnd ORDER BY chanprio DESC, p.build_time ]]> - + + + @@ -612,6 +352,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + + + @@ -712,6 +455,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" where c.org_id is NULL and ccs.source_id IS NULL ]]> + @@ -724,6 +468,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" SELECT DISTINCT a.channel_id FROM suseAppstream a) ]]> + 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..0f60f001c7df 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/Channel.java +++ b/java/code/src/com/redhat/rhn/domain/channel/Channel.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2009--2018 Red Hat, Inc. + * Copyright (c) 2024 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or @@ -32,19 +33,45 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hibernate.annotations.Type; import java.util.ArrayList; import java.util.Arrays; 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; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Transient; + + /** * Channel */ +@Entity +@Table(name = "rhnChannel") +@Inheritance(strategy = InheritanceType.JOINED) + public class Channel extends BaseDomainHelper implements Comparable { /** @@ -64,7 +91,7 @@ public class Channel extends BaseDomainHelper implements Comparable { private String description; private Date endOfLife; - private boolean GPGCheck; + private boolean GPGCheck = true; private String GPGKeyUrl; private String GPGKeyId; private String GPGKeyFp; @@ -121,6 +148,7 @@ public Channel() { * @param orgIn what org you want to know if it is globally subscribable in * @return Returns whether or not this channel is globally subscribable. */ + @Transient public boolean isGloballySubscribable(Org orgIn) { return ChannelFactory.isGloballySubscribable(orgIn, this); } @@ -139,6 +167,7 @@ public void setGloballySubscribable(boolean value, Org orgIn) { * Returns true if this Channel is a mgr server channel. * @return true if this Channel is a mgr server channel. */ + @Transient public boolean isMgrServer() { return getChannelFamily().getLabel().startsWith( ChannelFamilyFactory.SATELLITE_CHANNEL_FAMILY_LABEL); @@ -148,6 +177,7 @@ public boolean isMgrServer() { * Returns true if this Channel is a Proxy channel. * @return true if this Channel is a Proxy channel. */ + @Transient public boolean isProxy() { ChannelFamily cfam = getChannelFamily(); @@ -162,29 +192,15 @@ public boolean isProxy() { * Returns true if this Channel is a Vendor channel. * @return true if this Channel is a Vendor channel. */ + @Transient public boolean isVendorChannel() { return org == null; } - /** - * Returns true if this channel is of specified release (f.e. RHEL6) - * @param ver release version - * @return true if this channel is of specified release - */ - public boolean isReleaseXChannel(Integer ver) { - if (getDistChannelMaps() != null) { - for (DistChannelMap map : getDistChannelMaps()) { - if (map.getRelease().contains(ver.toString())) { - return true; - } - } - } - return false; - } - /** * @return Returns the baseDir. */ + @Column(name = "basedir") public String getBaseDir() { return baseDir; } @@ -199,6 +215,8 @@ public void setBaseDir(String b) { /** * @return Returns the channelArch. */ + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "channel_arch_id") public ChannelArch getChannelArch() { return channelArch; } @@ -213,6 +231,8 @@ public void setChannelArch(ChannelArch c) { /** * @return Returns the channelChecksum. */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "checksum_type_id") public ChecksumType getChecksumType() { return checksumType; } @@ -235,6 +255,7 @@ public void setComps(Comps compsIn) { /** * @return Returns the Comps. */ + @OneToOne(mappedBy = "channel", cascade = CascadeType.ALL, fetch = FetchType.LAZY) public Comps getComps() { return comps; } @@ -251,6 +272,7 @@ public void setModules(Modules modulesIn) { * * @param from the Channel */ + @Transient public void cloneModulesFrom(Channel from) { ChannelFactory.cloneModulesMetadata(from, this); } @@ -258,10 +280,12 @@ public void cloneModulesFrom(Channel from) { /** * @return Returns the Modules. */ + @OneToOne(mappedBy = "channel", cascade = CascadeType.ALL, fetch = FetchType.LAZY) public Modules getModules() { return modules; } + @Transient public boolean isModular() { return modules != null; } @@ -276,6 +300,7 @@ public void setMediaProducts(MediaProducts mediaProductsIn) { /** * @return Returns the Modules. */ + @OneToOne(mappedBy = "channel", cascade = CascadeType.ALL, fetch = FetchType.LAZY) public MediaProducts getMediaProducts() { return mediaProducts; } @@ -283,6 +308,7 @@ public MediaProducts getMediaProducts() { /** * @return Returns the description. */ + @Column(name = "description") public String getDescription() { return description; } @@ -297,6 +323,7 @@ public void setDescription(String d) { /** * @return Returns the endOfLife. */ + @Column(name = "end_of_life") public Date getEndOfLife() { return endOfLife; } @@ -311,6 +338,7 @@ public void setEndOfLife(Date e) { /** * @return Returns the gPGKeyFp. */ + @Column(name = "gpg_key_fp") public String getGPGKeyFp() { return GPGKeyFp; } @@ -325,6 +353,7 @@ public void setGPGKeyFp(String k) { /** * @return Returns the gPGKeyId. */ + @Column(name = "gpg_key_id") public String getGPGKeyId() { return GPGKeyId; } @@ -339,6 +368,7 @@ public void setGPGKeyId(String k) { /** * @return Returns the gPGKeyUrl. */ + @Column(name = "gpg_key_url") public String getGPGKeyUrl() { return GPGKeyUrl; } @@ -353,6 +383,10 @@ public void setGPGKeyUrl(String k) { /** * @return Returns the id. */ + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_channel_seq") + @SequenceGenerator(name = "rhn_channel_seq", sequenceName = "RHN_CHANNEL_ID_SEQ", + allocationSize = 1) public Long getId() { return id; } @@ -367,6 +401,7 @@ public void setId(Long i) { /** * @return Returns the label. */ + @Column(name = "label") public String getLabel() { return label; } @@ -381,6 +416,7 @@ public void setLabel(String l) { /** * @return Returns the lastModified. */ + @Column(name = "last_modified") public Date getLastModified() { return lastModified; } @@ -395,6 +431,7 @@ public void setLastModified(Date l) { /** * @return Returns the lastSynced. */ + @Column(name = "last_synced") public Date getLastSynced() { return lastSynced; } @@ -409,6 +446,7 @@ public void setLastSynced(Date lastSyncedIn) { /** * @return Returns the name. */ + @Column(name = "name") public String getName() { return name; } @@ -423,6 +461,8 @@ public void setName(String n) { /** * @return Returns the org. */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "org_id") public Org getOrg() { return org; } @@ -437,6 +477,8 @@ public void setOrg(Org o) { /** * @return Returns the parentChannel. */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_channel", nullable = true) public Channel getParentChannel() { return parentChannel; } @@ -451,6 +493,7 @@ public void setParentChannel(Channel p) { /** * @return Returns the summary. */ + @Column(name = "summary") public String getSummary() { return summary; } @@ -465,6 +508,10 @@ public void setSummary(String s) { /** * @return Returns the set of erratas for this channel. */ + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) + @JoinTable(name = "rhnChannelErrata", + joinColumns = { @JoinColumn(name = "channel_id")}, + inverseJoinColumns = { @JoinColumn(name = "errata_id")}) public Set getErratas() { return erratas; } @@ -490,6 +537,10 @@ public void addErrata(Errata errataIn) { * * @return Returns the set of packages for this channel. */ + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) + @JoinTable(name = "rhnChannelPackage", + joinColumns = { @JoinColumn(name = "channel_id")}, + inverseJoinColumns = { @JoinColumn(name = "package_id")}) public Set getPackages() { return packages; } @@ -497,6 +548,7 @@ public Set getPackages() { /** * @return Returns the size of the package set for this channel. */ + @Transient public int getPackageCount() { // we don;t want to use packages.size() // this could be a lot (we don't want to load all the packages @@ -508,6 +560,7 @@ public int getPackageCount() { /** * @return Returns the size of the package set for this channel. */ + @Transient public int getErrataCount() { return ChannelFactory.getErrataCount(this); } @@ -533,6 +586,10 @@ public void setSources(Set sourcesIn) { * * @return set of yum repos for this channel */ + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) + @JoinTable(name = "rhnChannelContentSource", + joinColumns = { @JoinColumn(name = "channel_id")}, + inverseJoinColumns = { @JoinColumn(name = "source_id")}) public Set getSources() { return sources; } @@ -571,6 +628,10 @@ public void removePackage(Package packageIn, User user) { /** * @return Returns the set of channelFamiliess for this channel. */ + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) + @JoinTable(name = "rhnChannelFamilyMembers", + joinColumns = { @JoinColumn(name = "channel_id")}, + inverseJoinColumns = { @JoinColumn(name = "channel_family_id")}) public Set getChannelFamilies() { return channelFamilies; } @@ -580,11 +641,8 @@ public Set getChannelFamilies() { * @param channelFamiliesIn The set of channelFamilies */ public void setChannelFamilies(Set channelFamiliesIn) { - if (channelFamiliesIn.size() > 1) { - throw new TooManyChannelFamiliesException(this.getId(), - "A channel can only have one channel family"); - } - this.channelFamilies = channelFamiliesIn; + channelFamilies.clear(); + this.channelFamilies.addAll(channelFamiliesIn); } /** @@ -599,6 +657,10 @@ public void setTrustedOrgs(Set trustedOrgsIn) { * * @return set of trusted orgs for this channel */ + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) + @JoinTable(name = "rhnChannelTrust", + joinColumns = { @JoinColumn(name = "channel_id")}, + inverseJoinColumns = { @JoinColumn(name = "org_trust_id")}) public Set getTrustedOrgs() { return this.trustedOrgs; } @@ -606,6 +668,7 @@ public Set getTrustedOrgs() { /** * @return number of trusted organizations that have access to this channel */ + @Transient public int getTrustedOrgsCount() { if (trustedOrgs != null) { return trustedOrgs.size(); @@ -638,6 +701,7 @@ public void setChannelFamily(ChannelFamily channelFamilyIn) { * Get the channel family for this channel. * @return the channel's family, or null if none found */ + @Transient public ChannelFamily getChannelFamily() { if (this.getChannelFamilies().size() == 1) { Object[] cfams = this.getChannelFamilies().toArray(); @@ -651,6 +715,7 @@ public ChannelFamily getChannelFamily() { * Returns true if this channel is considered a base channel. * @return true if this channel is considered a base channel. */ + @Transient public boolean isBaseChannel() { return (getParentChannel() == null); } @@ -659,6 +724,7 @@ public boolean isBaseChannel() { * Returns true if this channel is a cloned channel. * @return whether the channel is cloned or not */ + @Transient public boolean isCloned() { return false; } @@ -688,6 +754,8 @@ public int hashCode() { /** * @return Returns the product. */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "channel_product_id") public ChannelProduct getProduct() { return product; } @@ -702,6 +770,7 @@ public void setProduct(ChannelProduct productIn) { /** * @return Returns the distChannelMaps. */ + @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL, orphanRemoval = true) public Set getDistChannelMaps() { return distChannelMaps; } @@ -723,6 +792,7 @@ public void setDistChannelMaps(Set distChannelMapsIn) { * @param server to check if subscribable * @return boolean if subscribable or not */ + @Transient public boolean isSubscribable(Org orgIn, Server server) { if (log.isDebugEnabled()) { @@ -744,6 +814,8 @@ public String toString() { /** * @return the productName */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_name_id") public ProductName getProductName() { return productName; } @@ -760,6 +832,7 @@ public void setProductName(ProductName productNameIn) { * @param acc the access value being checked * @return true if the access provided is valid */ + @Transient public boolean isValidAccess(String acc) { return acc.equals(Channel.PUBLIC) || acc.equals(Channel.PRIVATE) || acc.equals(Channel.PROTECTED); } @@ -774,6 +847,7 @@ public void setAccess(String acc) { /** * @return public, protected, or private */ + @Column(name = "channel_access") public String getAccess() { return access; } @@ -782,6 +856,7 @@ public String getAccess() { * * @return wheter channel is protected */ + @Transient public boolean isProtected() { return this.getAccess().equals(Channel.PROTECTED); } @@ -791,6 +866,7 @@ public boolean isProtected() { * @param user the User needed for accessibility issues * @return a list of child channels or empty list if there are none. */ + @Transient public List getAccessibleChildrenFor(User user) { if (isBaseChannel()) { return ChannelFactory.getAccessibleChildChannels(this, user); @@ -809,6 +885,7 @@ public int compareTo(Channel o) { /** * @return maintainer's name */ + @Column(name = "maint_name") public String getMaintainerName() { return maintainerName; } @@ -816,6 +893,7 @@ public String getMaintainerName() { /** * @return maintainer's email */ + @Column(name = "maint_email") public String getMaintainerEmail() { return maintainerEmail; } @@ -823,6 +901,7 @@ public String getMaintainerEmail() { /** * @return maintainer's phone number */ + @Column(name = "maint_phone") public String getMaintainerPhone() { return maintainerPhone; } @@ -830,6 +909,7 @@ public String getMaintainerPhone() { /** * @return channel's support policy */ + @Column(name = "support_policy") public String getSupportPolicy() { return supportPolicy; } @@ -866,6 +946,7 @@ public void setSupportPolicy(String policy) { * Created for taskomatic -- probably shouldn't be called from the webui * @return returns if custom channel */ + @Transient public boolean isCustom() { return getOrg() != null; } @@ -874,6 +955,7 @@ public boolean isCustom() { * Does this channel need repodata generated * @return Returns a boolean if repodata generation Required */ + @Transient public boolean isChannelRepodataRequired() { // generate repodata for all channels having channel checksum set except solaris if (archesToSkipRepodata.contains(this.channelArch.getLabel())) { @@ -887,6 +969,7 @@ public boolean isChannelRepodataRequired() { * true if the channel contains any kickstartstartable distros * @return true if the channel contains any distros. */ + @Transient public boolean containsDistributions() { return ChannelFactory.containsDistributions(this); } @@ -898,6 +981,7 @@ public boolean containsDistributions() { * If its RHEL-5 we use sha1 anything newer will be sha256. * @return checksumType */ + @Transient public String getChecksumTypeLabel() { if ((checksumType == null) || (checksumType.getLabel() == null)) { @@ -910,6 +994,7 @@ public String getChecksumTypeLabel() { /** * @return the updateTag */ + @Column(name = "update_tag") public String getUpdateTag() { return updateTag; } @@ -924,6 +1009,8 @@ public void setUpdateTag(String updateTagIn) { /** * @return Returns the installerUpdates. */ + @Column(name = "installer_updates") + @Type(type = "yes_no") public boolean isInstallerUpdates() { return installerUpdates; } @@ -943,10 +1030,12 @@ public void setInstallerUpdates(boolean installerUpdatesIn) { * Returns all cloned channels of this channel which includes all clones of clones. * @return all cloned channels */ + @Transient public Stream allClonedChannels() { return getClonedChannels().stream().flatMap(c -> Stream.concat(Stream.of(c), c.allClonedChannels())); } + @OneToMany(mappedBy = "original", cascade = CascadeType.ALL) public Set getClonedChannels() { return clonedChannels; } @@ -961,6 +1050,8 @@ public void setClonedChannels(Set clonedChannelsIn) { /** * @return the GPGCheck */ + @Column(name = "gpg_check") + @Type(type = "yes_no") public boolean isGPGCheck() { return GPGCheck; } @@ -972,26 +1063,21 @@ public void setGPGCheck(boolean gpgCheckIn) { this.GPGCheck = gpgCheckIn; } - /** - * @return the original Channel the channel was cloned from - */ - public Channel getOriginal() { - throw new UnsupportedOperationException(); - } - /** * Creates a Stream starting with this channel and waking up the getOriginal chain * until getting to the original non cloned channel. * * @return stream of channels */ + @Transient 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)); } /** * @return the {@link SUSEProductChannel} */ + @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL) public Set getSuseProductChannels() { return suseProductChannels; } @@ -1009,6 +1095,7 @@ public void setSuseProductChannels(Set suseProductChannelsIn * Note: does not work for all channels see comment in source. * @return suse product channel */ + @Transient public Optional findProduct() { Set suseProducts = getSuseProductChannels(); if (suseProducts.isEmpty()) { @@ -1023,6 +1110,7 @@ public Optional findProduct() { } } + @Transient private String getArchTypeLabel() { return this.getChannelArch().getArchType().getLabel(); } @@ -1030,6 +1118,7 @@ private String getArchTypeLabel() { /** * @return whether the channel is a RPM chanel or not */ + @Transient public boolean isTypeRpm() { return PackageFactory.ARCH_TYPE_RPM.equalsIgnoreCase(getArchTypeLabel()); } @@ -1037,6 +1126,7 @@ public boolean isTypeRpm() { /** * @return whether the channel is a DEB chanel or not */ + @Transient public boolean isTypeDeb() { return PackageFactory.ARCH_TYPE_DEB.equalsIgnoreCase(getArchTypeLabel()); } @@ -1046,6 +1136,7 @@ public boolean isTypeDeb() { * * @return the optional of {@link ClonedChannel} */ + @Transient public Optional asCloned() { return Optional.empty(); } @@ -1057,6 +1148,7 @@ public void setChannelSyncFlag(ChannelSyncFlag csf) { /** * @return the channels sync flag settings */ + @OneToOne(mappedBy = "channel", cascade = CascadeType.ALL, orphanRemoval = true) public ChannelSyncFlag getChannelSyncFlag() { if (channelSyncFlag == null) { channelSyncFlag = new ChannelSyncFlag(); @@ -1065,4 +1157,3 @@ public ChannelSyncFlag getChannelSyncFlag() { return this.channelSyncFlag; } } - diff --git a/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.hbm.xml b/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.hbm.xml index 18b36845adcb..0303db335d84 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.hbm.xml @@ -3,44 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - protected - - - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.java b/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.java index c3a9c2d504bc..4fd2a5ab35fb 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.java +++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelArch.java @@ -22,12 +22,27 @@ 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.Immutable; import java.util.Set; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + /** * ChannelArch */ +@Entity +@Table(name = "rhnChannelArch") +@Immutable public class ChannelArch extends BaseDomainHelper { private Long id; @@ -37,23 +52,10 @@ public class ChannelArch extends BaseDomainHelper { private Set compatibleServerArches; private Set compatiblePackageArches; - /** - * @return Returns the archType. - */ - public ArchType getArchType() { - return archType; - } - - /** - * @param a The archType to set. - */ - public void setArchType(ArchType a) { - this.archType = a; - } - /** * @return Returns the id. */ + @Id public Long getId() { return id; } @@ -68,6 +70,7 @@ public void setId(Long i) { /** * @return Returns the label. */ + @Column public String getLabel() { return label; } @@ -82,6 +85,7 @@ public void setLabel(String l) { /** * @return Returns the name. */ + @Column public String getName() { return name; } @@ -93,26 +97,64 @@ public void setName(String n) { this.name = n; } + /** + * @return Returns the archType. + */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "arch_type_id") + public ArchType getArchType() { + return archType; + } + + /** + * @param a The archType to set. + */ + public void setArchType(ArchType a) { + this.archType = a; + } + /** * Returns the set of server architectures compatible with this channel * architecture. * @return the set of server architectures compatible with this channel * architecture. */ + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "rhnServerChannelArchCompat", + joinColumns = { @JoinColumn(name = "channel_arch_id") }, + inverseJoinColumns = { @JoinColumn(name = "server_arch_id") }) public Set getCompatibleServerArches() { return compatibleServerArches; } + /** + * @param arches The compatible server arches to set. + */ + public void setCompatibleServerArches(Set arches) { + compatibleServerArches = arches; + } + /** * Returns the set of package architectures compatible with this channel * architecture. * @return the set of package architectures compatible with this channel * architecture. */ + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "rhnChannelPackageArchCompat", + joinColumns = { @JoinColumn(name = "channel_arch_id") }, + inverseJoinColumns = { @JoinColumn(name = "package_arch_id") }) public Set getCompatiblePackageArches() { return compatiblePackageArches; } + /** + * @param arches The compatible package arches to set. + */ + public void setCompatiblePackageArches(Set arches) { + compatiblePackageArches = arches; + } + /** * Returns true if the given server architecture is compatible with this * channel architecture. False if the server architecture is null or not @@ -120,6 +162,7 @@ public Set getCompatiblePackageArches() { * @param arch Server architecture to be verified. * @return true if compatible; false if null or not compatible. */ + @Transient public boolean isCompatible(ServerArch arch) { Set compats = getCompatibleServerArches(); if (compats == null) { @@ -136,6 +179,7 @@ public boolean isCompatible(ServerArch arch) { * @param arch Package architecture to be verified. * @return true if compatible; false if null or not compatible. */ + @Transient public boolean isCompatible(PackageArch arch) { Set compats = getCompatiblePackageArches(); if (compats == null) { @@ -174,18 +218,13 @@ public String toString() { this.getArchType()).toString(); } - /** - * @param arches The compatible package arches to set. - */ - public void setCompatiblePackageArches(Set arches) { - compatiblePackageArches = arches; - } /** * Get the equivalent cobbler arch string for this ChannelArch, or null. * Valid values are i386,x86_64,ia64,ppc,s390 * @return the cobbler arch */ + @Transient public String cobblerArch() { // will be like ["channel", "ia32", and possibly "deb"]. The second one is what // we care about, map it to a cobbler arch if possible. @@ -214,5 +253,4 @@ public String cobblerArch() { } return ""; } - } 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..1f9c1143fd38 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,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Criteria; +import org.hibernate.CacheMode; 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 java.util.ArrayList; import java.util.Arrays; @@ -51,6 +48,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 */ @@ -95,8 +99,23 @@ public static Channel lookupByIdAndUser(Long id, User userIn) { if (id == null || userIn == null) { return null; } - return singleton.lookupObjectByNamedQuery("Channel.findByIdAndUserId", - Map.of("cid", id, "userId", userIn.getId())); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT OUTER JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE c.id = :cid + AND EXISTS (SELECT 1 + FROM suseChannelUserRoleView scur + WHERE scur.channel_id = c.id + AND scur.user_id = :userId + AND deny_reason IS NULL) + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .addSynchronizedEntityClass(ChannelSyncFlag.class) + .setParameter("cid", id) + .setParameter("userId", userIn.getId()) + .getSingleResult(); } /** @@ -109,8 +128,29 @@ public static Channel lookupByLabelAndUser(String label, User userIn) { if (label == null || userIn == null) { return null; } - return singleton.lookupObjectByNamedQuery("Channel.findByLabelAndUserId", - Map.of(LABEL, label, "userId", userIn.getId())); + Session session = HibernateFactory.getSession(); + + Query query = session.createNativeQuery(""" + SELECT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT OUTER JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE c.label = :label AND + EXISTS (SELECT 1 + FROM suseChannelUserRoleView scur + WHERE scur.channel_id = c.id AND + scur.user_id = :userId AND + scur.deny_reason IS NULL) + """, Channel.class) + .setCacheable(false) + .addSynchronizedEntityClass(Channel.class) + .addSynchronizedEntityClass(ChannelSyncFlag.class) + .setParameter("label", label) + .setParameter("userId", userIn.getId()); + return query.uniqueResult(); + +// return singleton.lookupObjectByNamedQuery("Channel.findByLabelAndUserId", + // Map.of(LABEL, label, "userId", userIn.getId())); } /** @@ -308,6 +348,7 @@ public static void remove(Channel c) { Map inParams = new HashMap<>(); inParams.put("cid", c.getId()); + getSession().flush(); m.execute(inParams, new HashMap<>()); } @@ -372,8 +413,23 @@ public static List getUserAcessibleChannels(Long orgid, Long cid) { * @return the accessible child channels.. */ public static List getAccessibleChildChannels(Channel baseChannel, User user) { - return singleton.listObjectsByNamedQuery("Channel.accessibleChildChannels", - Map.of("userId", user.getId(), "cid", baseChannel.getId())); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT OUTER JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE parent_channel = :cid + AND (SELECT deny_reason + FROM suseChannelUserRoleView scur + WHERE scur.channel_id = c.id + AND scur.user_id = :userId + AND scur.role = 'subscribe' + ) IS NULL + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter("userId", user.getId()) + .setParameter("cid", baseChannel.getId()) + .list(); } /** @@ -383,7 +439,16 @@ public static List getAccessibleChildChannels(Channel baseChannel, User * @return A list of Channel Objects. */ public static List getAccessibleChannelsByOrg(Long orgid) { - return singleton.listObjectsByNamedQuery("Org.accessibleChannels", Map.of(ORG_ID, orgid)); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT JOIN rhnChannelCloned c_1_ ON c.id = c_1_.original_id + JOIN rhnAvailableChannels cfp ON c.id = cfp.channel_id + WHERE cfp.org_id = :org_id + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter(ORG_ID, orgid) + .list(); } /** @@ -392,8 +457,11 @@ 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"; // Adjust the SQL query as + // needed + List channelArchList + = session.createNativeQuery(sql, ChannelArch.class).getResultList(); + return channelArchList; } /** @@ -426,9 +494,9 @@ 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).uniqueResult(); } /** @@ -438,8 +506,20 @@ public static ChannelArch findArchByLabel(String label) { * @return the Channel whose label matches the given label. */ public static Channel lookupByLabel(Org org, String label) { - return singleton.lookupObjectByNamedQuery("Channel.findByLabelAndOrgId", - Map.of(LABEL, label, "orgId", org.getId())); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT OUTER JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE c.label = :label + AND (rhn_channel.get_org_access(c.id, :orgId) = 1 + OR EXISTS (select id from rhnSharedChannelView scv + where scv.label = :label + and scv.org_trust_id = :orgId)) + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter(LABEL, label) + .setParameter("orgId", org.getId()) + .getSingleResult(); } /** @@ -451,9 +531,18 @@ 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.*, + c_1_.original_id, + CASE + WHEN c_1_.original_id IS NULL THEN 0 + ELSE 1 + END AS clazz_ + FROM rhnChannel c + LEFT JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE c.label = :label"""; + return session.createNativeQuery(sql, Channel.class) + .setParameter("label", label).uniqueResult(); } /** @@ -636,8 +725,21 @@ public static boolean doesChannelNameExist(String name) { * @return list of channels */ public static List getKickstartableTreeChannels(Org org) { - return singleton.listObjectsByNamedQuery("Channel.kickstartableTreeChannels", - Map.of(ORG_ID, org.getId()), false); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel c + LEFT JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + JOIN rhnAvailableChannels ach ON ach.channel_id = c.id + JOIN rhnChannelArch ca ON ca.id = ach.channel_arch_id + WHERE ach.org_id = :org_id + AND ach.channel_depth = 1 + ORDER BY rhn_channel.channel_priority(ach.parent_or_self_id), + UPPER(ach.channel_name) + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter(ORG_ID, org.getId()) + .list(); } /** @@ -647,8 +749,26 @@ public static List getKickstartableTreeChannels(Org org) { * @return list of channels */ public static List getKickstartableChannels(Org org) { - return singleton.listObjectsByNamedQuery("Channel.kickstartableChannels", - Map.of(ORG_ID, org.getId()), false); + return getSession().createNativeQuery(""" + SELECT DISTINCT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_, + rhn_channel.channel_priority(ach.parent_or_self_id), + UPPER(ach.channel_name) + FROM rhnChannel c + LEFT JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + JOIN rhnAvailableChannels ach ON ach.channel_id = c.id + JOIN rhnChannelArch ca ON ca.id = ach.channel_arch_id + JOIN rhnKickstartableTree kt ON kt.channel_id = c.id + JOIN rhnKSInstallType ksit ON ksit.id = kt.install_type + WHERE ach.org_id = :org_id + AND ach.channel_depth = 1 + AND (ksit.label LIKE 'rhel%' OR ksit.label LIKE 'fedora%') + ORDER BY rhn_channel.channel_priority(ach.parent_or_self_id), + UPPER(ach.channel_name) + """, Channel.class) + .setCacheMode(CacheMode.GET) + .setParameter(ORG_ID, org.getId()) + .list(); } /** @@ -796,8 +916,10 @@ 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() + .createQuery("SELECT csf FROM ChannelSyncFlag csf WHERE channel = :channel", ChannelSyncFlag.class) + .setParameter("channel", channel) + .uniqueResult(); } /** @@ -971,7 +1093,41 @@ public static List listDistChannelMaps(Channel c) { * @return List of channels (including children) accessible for the provided user */ public static List findAllByUserOrderByChild(User user) { - return singleton.listObjectsByNamedQuery("Channel.findAllByUserOrderByChild", Map.of("userId", user.getId())); + return getSession().createNativeQuery(""" + with user_channel_roles as materialized( + select * from suseChannelUserRoleView s + where s.user_id = :userId + and s.deny_reason is null + ) + SELECT channel.*, channel_1_.original_id, CASE WHEN channel_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnChannel channel + LEFT OUTER JOIN rhnChannel parent ON channel.parent_channel = parent.id + LEFT OUTER JOIN rhnChannelCloned channel_1_ ON channel.id = channel_1_.id + WHERE EXISTS ( + SELECT 1 + FROM user_channel_roles scur + WHERE scur.channel_id = channel.id + ) + AND ( + channel.parent_channel IS NULL + OR ( + channel.parent_channel IS NOT NULL + AND EXISTS ( + SELECT 1 + FROM user_channel_roles scur + WHERE scur.channel_id = channel.parent_channel + ) + ) + ) + ORDER BY + channel.org_id NULLS FIRST, + COALESCE(parent.label, channel.label), + channel.parent_channel NULLS FIRST, + channel.label + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter("userId", user.getId()) + .list(); } /** @@ -1041,8 +1197,23 @@ public static List listSubscribableBaseChannels(User user) { * @return list of custom channels */ public static List listAllBaseChannels(User user) { - return singleton.listObjectsByNamedQuery("Channel.findAllBaseChannels", - Map.of(ORG_ID, user.getOrg().getId(), "user_id", user.getId())); + return getSession().createNativeQuery(""" + SELECT c.*, c_1_.original_id, + CASE WHEN c_1_.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM suseChannelUserRoleView SCURV + JOIN rhnChannel c ON c.id = SCURV.channel_id + LEFT OUTER JOIN rhnChannelCloned c_1_ ON c.id = c_1_.id + WHERE SCURV.org_id = :org_id + AND SCURV.deny_reason IS NULL + AND SCURV.user_id = :user_id + AND SCURV.role = 'subscribe' + AND c.parent_channel is null + ORDER BY c.name + """, Channel.class) + .addSynchronizedEntityClass(Channel.class) + .setParameter(ORG_ID, user.getOrg().getId()) + .setParameter("user_id", user.getId()) + .list(); } /** @@ -1074,8 +1245,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) + .setParameter("channel_id", channel.getId()) .list(); if (pkgs.isEmpty()) { return null; @@ -1095,12 +1266,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) + .setParameter("channel_id", channel.getId()) + .setParameter("headerStart", headerStart) + .setParameter("headerEnd", headerEnd).list(); if (pkgs.isEmpty()) { return null; } @@ -1116,10 +1286,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()).getSingleResult(); + return count.intValue() > 0; } /** @@ -1232,9 +1404,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 IS NULL"; + List contentSources + = session.createNativeQuery(sql, ContentSource.class).getResultList(); + return contentSources; } /** @@ -1243,23 +1417,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 +1479,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(); + String sql + = "SELECT * FROM rhnChannelProduct WHERE product = :product AND version = :version"; + TypedQuery query + = getSession().createNativeQuery(sql, ChannelProduct.class); + query.setParameter("product", product); + query.setParameter("version", version); + 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..1705a8a691d5 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_id", 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); + } } /** @@ -207,23 +223,6 @@ public static void save(PublicChannelFamily pcf) { singleton.saveObject(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 - * @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(); - } - /** * Return the name for a given channel family label. * @param label channel family label @@ -243,8 +242,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/channel/ChannelSyncFlag.java b/java/code/src/com/redhat/rhn/domain/channel/ChannelSyncFlag.java index 0c29da4a47de..e1edeef83fed 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ChannelSyncFlag.java +++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelSyncFlag.java @@ -20,7 +20,6 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; -import javax.persistence.MapsId; import javax.persistence.OneToOne; import javax.persistence.Table; @@ -28,12 +27,7 @@ @Table(name = "rhnChannelSyncFlag") public class ChannelSyncFlag implements Serializable { - @Id - @Column(name = "channel_id", nullable = false) - private Long id; - - @OneToOne(mappedBy = "channelSyncFlag") - @MapsId + @Id @OneToOne @JoinColumn(name = "channel_id") private Channel channel; @@ -54,14 +48,6 @@ public class ChannelSyncFlag implements Serializable { // Getters and Setters - public Long getId() { - return id; - } - - public void setId(Long idnr) { - this.id = idnr; - } - public boolean isNoStrict() { return noStrict; } diff --git a/java/code/src/com/redhat/rhn/domain/channel/ClonedChannel.java b/java/code/src/com/redhat/rhn/domain/channel/ClonedChannel.java index 7e8be18bc5ca..77f60bd2b4d9 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/ClonedChannel.java +++ b/java/code/src/com/redhat/rhn/domain/channel/ClonedChannel.java @@ -16,11 +16,22 @@ import com.redhat.rhn.domain.common.ChecksumType; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + import java.util.Optional; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + /** * ClonedChannel */ +@Entity +@Table(name = "rhnChannelCloned") public class ClonedChannel extends Channel { private Channel original; @@ -28,23 +39,21 @@ public class ClonedChannel extends Channel { /** * @return the original Channel the channel was cloned from */ - @Override + @ManyToOne + @JoinColumn(name = "original_id") public Channel getOriginal() { return original; } - /** - * Set the original version of the clone - * @param originalIn original Channel this clone was created from - */ public void setOriginal(Channel originalIn) { - this.original = originalIn; + original = originalIn; } /** * {@inheritDoc} */ @Override + @Transient public boolean isCloned() { return true; } @@ -53,6 +62,7 @@ public boolean isCloned() { * {@inheritDoc} */ @Override + @Transient public Optional asCloned() { return Optional.of(this); } @@ -61,6 +71,7 @@ public Optional asCloned() { * {@inheritDoc} */ @Override + @Transient public ChecksumType getChecksumType() { // We can reach a StackOverflow here if the current channel is also the // original. Happening because of a Hibernate problem. See BZ 837913. @@ -72,4 +83,24 @@ public ChecksumType getChecksumType() { } return super.getChecksumType(); } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(final Object other) { + if (!(other instanceof ClonedChannel castOther)) { + return false; + } + return new EqualsBuilder().append(getOriginal(), castOther.getOriginal()).isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder().append(getOriginal()).toHashCode(); + } + } diff --git a/java/code/src/com/redhat/rhn/domain/channel/test/AccessTokenFactoryTest.java b/java/code/src/com/redhat/rhn/domain/channel/test/AccessTokenFactoryTest.java index 5706c2871c78..ce572912d5d6 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/test/AccessTokenFactoryTest.java +++ b/java/code/src/com/redhat/rhn/domain/channel/test/AccessTokenFactoryTest.java @@ -20,11 +20,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.redhat.rhn.common.conf.Config; +import com.redhat.rhn.common.hibernate.HibernateFactory; import com.redhat.rhn.domain.channel.AccessToken; 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.server.MinionServer; +import com.redhat.rhn.domain.server.MinionServerFactory; import com.redhat.rhn.domain.server.test.MinionServerFactoryTest; import com.redhat.rhn.testing.BaseTestCaseWithUser; import com.redhat.rhn.testing.TestUtils; @@ -143,7 +145,9 @@ public void testGenerate() throws Exception { Channel child = ChannelFactoryTest.createTestChannel(user); assertTrue(AccessTokenFactory.generate(testMinionServer, Collections.singleton(base)).isPresent()); assertTrue(AccessTokenFactory.generate(testMinionServer, Collections.singleton(child)).isPresent()); - MinionServer minionServer = TestUtils.saveAndReload(testMinionServer); + HibernateFactory.getSession().flush(); + HibernateFactory.getSession().clear(); + MinionServer minionServer = MinionServerFactory.lookupById(testMinionServer.getId()).orElseThrow(); assertEquals(2, minionServer.getAccessTokens().size()); } @@ -164,7 +168,9 @@ public void testUnneeded() throws Exception { assertEquals(0, AccessTokenFactory.unneededTokens(testMinionServer, Collections.emptySet()).size()); testMinionServer.getChannels().remove(child); - MinionServer minionServer = TestUtils.saveAndReload(testMinionServer); + HibernateFactory.getSession().flush(); + HibernateFactory.getSession().clear(); + MinionServer minionServer = MinionServerFactory.lookupById(testMinionServer.getId()).orElseThrow(); assertEquals(1, minionServer.getChannels().size()); assertEquals(1, AccessTokenFactory.unneededTokens(minionServer, Collections.emptySet()).size()); @@ -178,11 +184,22 @@ public void testUnnededTokensInvalidatedOnRefresh() throws Exception { child.setParentChannel(base); testMinionServer.getChannels().add(base); testMinionServer.getChannels().add(child); - AccessToken token = AccessTokenFactory.generate(testMinionServer, Collections.singleton(child)).get(); + AccessTokenFactory.generate(testMinionServer, Collections.singleton(child)); testMinionServer.getChannels().remove(child); - MinionServer minionServer = TestUtils.saveAndReload(testMinionServer); + + HibernateFactory.getSession().flush(); + HibernateFactory.getSession().clear(); + MinionServer minionServer = MinionServerFactory.lookupById(testMinionServer.getId()).orElseThrow(); + AccessToken token = minionServer.getAccessTokens().stream().findFirst().orElseThrow(); + assertTrue(token.getValid()); + assertEquals(child.getId(), token.getChannels().stream().findFirst().map(Channel::getId).orElse(-1L)); + assertTrue(AccessTokenFactory.refreshTokens(minionServer)); + assertFalse(token.getValid()); + assertEquals(base.getId(), minionServer.getAccessTokens().stream().flatMap(t -> t.getChannels().stream()) + .findFirst() + .map(Channel::getId).orElse(-1L)); } @Test diff --git a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFactoryTest.java b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFactoryTest.java index 320121ce89d5..0b93644ddec2 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFactoryTest.java +++ b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFactoryTest.java @@ -70,6 +70,7 @@ public void testChannelFactory() throws Exception { Channel c2 = ChannelFactory.lookupById(c.getId()); assertEquals(c.getLabel(), c2.getLabel()); + HibernateFactory.getSession().flush(); Channel c3 = ChannelFactoryTest.createTestChannel(user); Long id = c3.getId(); assertNotNull(c.getChannelArch()); @@ -378,7 +379,6 @@ public void testPackageCount() throws Exception { ChannelFactory.save(original); TestUtils.flushAndEvict(original); - original = (Channel)reload(original); assertEquals(1, ChannelFactory.getPackageCount(original)); } @@ -722,6 +722,7 @@ public void testChannelSyncFlag() throws Exception { assertFalse(csf.isOnlyLatest()); assertFalse(csf.isQuitOnError()); + channel = ChannelFactory.lookupByIdAndUser(channelId, user); ChannelSyncFlag csf2 = ChannelFactory.lookupChannelReposyncFlag(channel); assertNotNull(csf2); @@ -740,6 +741,7 @@ public void testChannelSyncFlag() throws Exception { ChannelFactory.save(csf); flushAndEvict(csf); + csf = channel.getChannelSyncFlag(); assertNotNull(csf); assertTrue(csf.isCreateTree()); assertTrue(csf.isNoErrata()); diff --git a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFamilyFactoryTest.java b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFamilyFactoryTest.java index d632cee7d340..116916efcdf2 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFamilyFactoryTest.java +++ b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelFamilyFactoryTest.java @@ -31,8 +31,6 @@ import org.junit.jupiter.api.Test; -import java.util.List; - /** * ChannelFamilyFactoryTest */ @@ -64,16 +62,6 @@ public void testLookupByLabel() throws Exception { assertEquals(cfam.getId(), cfam2.getId()); } - @Test - public void testLookupByLabelLike() throws Exception { - ChannelFamily cfam = createTestChannelFamily(); - List cfams = ChannelFamilyFactory.lookupByLabelLike(cfam.getLabel(), - cfam.getOrg()); - ChannelFamily cfam2 = (ChannelFamily) cfams.get(0); - assertEquals(cfam.getId(), cfam2.getId()); - } - - @Test public void testVerifyOrgFamily() { User user = UserTestUtils.findNewUser("testUser", diff --git a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelTest.java b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelTest.java index 3b8a673d7458..037699e39c47 100644 --- a/java/code/src/com/redhat/rhn/domain/channel/test/ChannelTest.java +++ b/java/code/src/com/redhat/rhn/domain/channel/test/ChannelTest.java @@ -137,7 +137,7 @@ public void testEquals() throws Exception { public void testDistChannelMap() throws Exception { Channel c = ChannelFactoryTest.createTestChannel(user); ChannelTestUtils.addDistMapToChannel(c); - c = (Channel) reload(c); + c = TestUtils.saveAndReload(c); assertNotNull(c.getDistChannelMaps()); assertFalse(c.getDistChannelMaps().isEmpty()); } 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..9c5a923d4c32 100644 --- a/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java +++ b/java/code/src/com/redhat/rhn/domain/common/CommonFactory.java @@ -87,9 +87,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) + .setParameter("org_id", org.getId()) .uniqueResult(); } @@ -103,8 +106,8 @@ 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) + .setParameter("org_id", org.getId()).uniqueResult(); } /** @@ -150,7 +153,6 @@ 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).uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/domain/common/ExceptionMessage.java b/java/code/src/com/redhat/rhn/domain/common/ExceptionMessage.java index 11fdf54dcfbb..ace9ec85a54e 100644 --- a/java/code/src/com/redhat/rhn/domain/common/ExceptionMessage.java +++ b/java/code/src/com/redhat/rhn/domain/common/ExceptionMessage.java @@ -18,9 +18,9 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.criterion.Restrictions; + +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; /** @@ -43,12 +43,21 @@ protected ExceptionMessage() { * @return the associated exception object / null if not found otherwise */ public static ExceptionMessage lookup(long exceptionId) { - Session session = HibernateFactory.getSession(); - Criteria criteria = session.createCriteria(ExceptionMessage.class); - criteria.add(Restrictions.or( - Restrictions.eq("id", -1 * exceptionId), - Restrictions.eq("id", exceptionId))); - return (ExceptionMessage) criteria.uniqueResult(); + String sql = "SELECT * FROM exception_message WHERE id = :id OR id = :negId"; + + TypedQuery query = HibernateFactory.getSession() + .createNativeQuery(sql, ExceptionMessage.class); + query.setParameter("id", exceptionId); + query.setParameter("negId", -1 * exceptionId); + try { + return query.getSingleResult(); + } + catch (NoResultException e) { + return null; + } + catch (Exception e) { + throw new RuntimeException("Error retrieving ExceptionMessage", e); + } } /** diff --git a/java/code/src/com/redhat/rhn/domain/common/ProvisionState.hbm.xml b/java/code/src/com/redhat/rhn/domain/common/ProvisionState.hbm.xml deleted file mode 100644 index 214fea20ed21..000000000000 --- a/java/code/src/com/redhat/rhn/domain/common/ProvisionState.hbm.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - protected - - RHN_PROVSTATE_ID_SEQ - 1 - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/common/ProvisionState.java b/java/code/src/com/redhat/rhn/domain/common/ProvisionState.java index 883b59a3a7bc..83e47e603d5d 100644 --- a/java/code/src/com/redhat/rhn/domain/common/ProvisionState.java +++ b/java/code/src/com/redhat/rhn/domain/common/ProvisionState.java @@ -16,13 +16,35 @@ import com.redhat.rhn.domain.BaseDomainHelper; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * ProvisionState */ -public class ProvisionState extends BaseDomainHelper { +@Entity +@Table(name = "rhnProvisionState") +public class ProvisionState extends BaseDomainHelper implements Serializable { + + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_provstate_id_seq") + @SequenceGenerator(name = "rhn_provstate_id_seq", sequenceName = "RHN_PROVSTATE_ID_SEQ", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "label") private String label; + + @Column(name = "description") private String description; /** diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.hbm.xml deleted file mode 100644 index 97a8f320fe9b..000000000000 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.hbm.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - protected - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.java b/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.java index 3641a164f15c..485806cdafd7 100644 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.java +++ b/java/code/src/com/redhat/rhn/domain/config/ConfigChannel.java @@ -24,20 +24,53 @@ import java.util.Date; import java.util.SortedSet; +import java.util.TreeSet; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.persistence.Table; +import javax.persistence.Transient; /** * ConfigChannel - Class representation of the table rhnConfigChannel. */ +@Entity +@Table(name = "rhnConfigChannel") public class ConfigChannel extends BaseDomainHelper implements Identifiable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) // Assuming the ID is auto-generated or assigned + @Column(name = "id") private Long id; + + @ManyToOne + @JoinColumn(name = "org_id", nullable = false) private Org org; + + @Column(name = "name", length = 128, nullable = false) private String name; + + @Column(name = "label", length = 64, nullable = false) private String label; + + @Column(name = "description", length = 1024) private String description; + @ManyToOne + @JoinColumn(name = "confchan_type_id", nullable = false) private ConfigChannelType configChannelType; - private SortedSet configFiles; + @Transient + private SortedSet configFiles = new TreeSet<>(); /** * Protected constructor 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/ConfigChannelType.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.hbm.xml deleted file mode 100644 index 17ae8cfaf0bb..000000000000 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.hbm.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - protected - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.java b/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.java index 2ea706f0291a..0c036ca04fa4 100644 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.java +++ b/java/code/src/com/redhat/rhn/domain/config/ConfigChannelType.java @@ -22,14 +22,35 @@ import java.util.Map; import java.util.TreeMap; +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + /** * ConfigChannelType - Class representation of the table rhnConfigChannelType. */ +@Entity +@Table(name = "rhnConfigChannelType") +@Cacheable(true) // Using read-only cache as specified in the XML mapping +@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY) public class ConfigChannelType extends BaseDomainHelper { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) // Assuming ID is auto-generated or assigned + @Column(name = "id") private Long id; + + @Column(name = "label", length = 64, nullable = false) private String label; + + @Column(name = "name", length = 64, nullable = false) private String name; + + @Column(name = "priority", nullable = false) private Long priority; public static final String NORMAL = "normal"; diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigFile.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigFile.hbm.xml index f2083ab76474..b8c07ff53336 100644 --- a/java/code/src/com/redhat/rhn/domain/config/ConfigFile.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/config/ConfigFile.hbm.xml @@ -3,32 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - - - - - - - - - - - query + = getSession().createNativeQuery(sql, ConfigChannel.class); + + query.setParameter("org_id", org.getId()); + query.setParameter("label", label); + query.setParameter("cct", cct.getId()); + + return query.getSingleResult(); } /** @@ -431,9 +437,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(). + .setParameter("channel_id", channel) + .setParameter("name_id", name) + .setParameter("state_id", ConfigFileState.normal(). getId()); try { return query.uniqueResult(); @@ -464,7 +470,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); q.setParameter("cf", cf); return q.uniqueResult(); } @@ -513,9 +519,10 @@ public static ConfigFileName lookupConfigFileNameById(Long id) { */ static ConfigChannelType lookupConfigChannelTypeByLabel(String label) { Session session = HibernateFactory.getSession(); - return (ConfigChannelType) - session.getNamedQuery("ConfigChannelType.findByLabel") - .setString("label", label) + return session.createNativeQuery(""" + SELECT * FROM rhnConfigChannelType where label = :label + """, ConfigChannelType.class) + .setParameter("label", label) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -532,7 +539,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -546,7 +553,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/contentmgmt/ContentProjectHistoryEntry.java b/java/code/src/com/redhat/rhn/domain/contentmgmt/ContentProjectHistoryEntry.java index e03732a85409..792abe2ebc3a 100644 --- a/java/code/src/com/redhat/rhn/domain/contentmgmt/ContentProjectHistoryEntry.java +++ b/java/code/src/com/redhat/rhn/domain/contentmgmt/ContentProjectHistoryEntry.java @@ -141,7 +141,7 @@ public void setVersion(Long versionIn) { * * @return created */ - @Column(nullable = false, updatable = false) + @Column(nullable = false) @CreationTimestamp public Date getCreated() { return created; diff --git a/java/code/src/com/redhat/rhn/domain/credentials/BaseCredentials.java b/java/code/src/com/redhat/rhn/domain/credentials/BaseCredentials.java index c40750bec5d7..a38d7860ba07 100644 --- a/java/code/src/com/redhat/rhn/domain/credentials/BaseCredentials.java +++ b/java/code/src/com/redhat/rhn/domain/credentials/BaseCredentials.java @@ -62,7 +62,7 @@ ) @NamedQuery( name = "BaseCredentials.getLastSCCRefreshDate", - query = "SELECT MAX(modified) FROM BaseCredentials WHERE type IN ('scc', 'cloudrmt')" + query = "SELECT MAX(modified) FROM BaseCredentials" ) public abstract class BaseCredentials extends BaseDomainHelper implements Credentials { diff --git a/java/code/src/com/redhat/rhn/domain/credentials/test/CredentialsTest.java b/java/code/src/com/redhat/rhn/domain/credentials/test/CredentialsTest.java index ad456b1eac28..34feb68b9482 100644 --- a/java/code/src/com/redhat/rhn/domain/credentials/test/CredentialsTest.java +++ b/java/code/src/com/redhat/rhn/domain/credentials/test/CredentialsTest.java @@ -50,7 +50,8 @@ public void testSCCCredentials() throws Exception { assertEquals("secret", creds.getPassword()); Optional r = HibernateFactory.getSession() - .createSQLQuery("select password from suseCredentials where username = 'admin';") + .createNativeQuery( + "select password from suseCredentials where username = 'admin';") .uniqueResultOptional(); // this prove that we really store encoded content in DB assertEquals("c2VjcmV0", r.orElseThrow().toString()); diff --git a/java/code/src/com/redhat/rhn/domain/errata/AdvisoryStatusConverter.java b/java/code/src/com/redhat/rhn/domain/errata/AdvisoryStatusConverter.java new file mode 100644 index 000000000000..a911909d7ffe --- /dev/null +++ b/java/code/src/com/redhat/rhn/domain/errata/AdvisoryStatusConverter.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 SUSE LLC + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + */ +package com.redhat.rhn.domain.errata; + +import javax.persistence.AttributeConverter; + +/** + * JPA converter between AdvisoryStatus and String + */ +public class AdvisoryStatusConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(AdvisoryStatus statusIn) { + return statusIn.getMetadataValue(); + } + + @Override + public AdvisoryStatus convertToEntityAttribute(String s) { + return AdvisoryStatus.fromMetadata(s).orElse(null); + } +} diff --git a/java/code/src/com/redhat/rhn/domain/errata/Errata.hbm.xml b/java/code/src/com/redhat/rhn/domain/errata/Errata.hbm.xml index bdd917aca2b7..a7042359a25f 100644 --- a/java/code/src/com/redhat/rhn/domain/errata/Errata.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/errata/Errata.hbm.xml @@ -17,7 +17,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" length="32" /> - + @@ -195,6 +195,10 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" WHERE (pn.name || '-' || COALESCE(pevr.epoch || ':', '') || pevr.version || '-' || pevr.release || '.' || parch.label) in (:nevras) AND sid in (:sids) ]]> + + + + @@ -299,24 +303,4 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - - - - 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..a70ae73b2948 100644 --- a/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java +++ b/java/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java @@ -28,6 +28,7 @@ import com.redhat.rhn.common.hibernate.HibernateRuntimeException; 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.common.ChecksumFactory; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.product.Tuple2; @@ -227,7 +228,8 @@ public static List addToChannel(List errataList, Channel chan, throw new InvalidChannelException("Cloned channel expected: " + chan.getLabel()); } - Channel original = chan.getOriginal(); + Channel original = chan.asCloned().map(ClonedChannel::getOriginal) + .orElseThrow(() -> new InvalidChannelException("Cloned channel expected: " + chan.getLabel())); // see BZ 805714, if we are a clone of a clone the 1st clone // may not have the errata we want Set associatedChannels = errata.getChannels(); @@ -396,7 +398,7 @@ public static ErrataFileType lookupErrataFileType(String label) { ErrataFileType retval; try { retval = (ErrataFileType) getSession().getNamedQuery("ErrataFileType.findByLabel") - .setString("label", label).setCacheable(true).uniqueResult(); + .setParameter("label", label).setCacheable(true).uniqueResult(); } catch (HibernateException e) { throw new HibernateRuntimeException(e.getMessage(), e); @@ -414,8 +416,8 @@ public static List lookupErrataFilesByErrataAndFileType(Long errataI List retval; try { Query q = getSession().getNamedQuery("ErrataFile.listByErrataAndFileType"); - q.setLong("errata_id", errataId); - q.setString("file_type", fileType.toUpperCase()); + q.setParameter("errata_id", errataId); + q.setParameter("file_type", fileType.toUpperCase()); retval = q.list(); } catch (HibernateException e) { @@ -446,7 +448,7 @@ public static List lookupErratasByAdvisoryType(String advisoryType) { List retval; try { retval = getSession().getNamedQuery("Errata.findByAdvisoryType") - .setString("type", advisoryType) + .setParameter("type", advisoryType) //Retrieve from cache if there .setCacheable(true).list(); } @@ -466,7 +468,7 @@ public static Errata lookupErrataById(Long id) { Errata retval; try { retval = (Errata) getSession().getNamedQuery("Errata.findById") - .setLong("id", id).uniqueResult(); + .setParameter("id", id).uniqueResult(); } catch (HibernateException he) { log.error("Error loading ActionArchTypes from DB", he); @@ -954,7 +956,28 @@ private static void processRetracted(long errataId, long channelId, boolean retr * @return List of Errata Objects */ public static List listErrata(Collection ids, Long orgId) { - return singleton.listObjectsByNamedQuery("Errata.listAvailableToOrgByIds", Map.of("orgId", orgId), ids, "eids"); + return getSession().createNativeQuery(""" + SELECT E.*, EC.original_id, CASE WHEN EC.original_id IS NULL THEN 0 ELSE 1 END as clazz_ + FROM rhnErrata as E + LEFT JOIN rhnErrataCloned EC ON E.id = EC.id + WHERE E.id in (:eids) + AND (E.org_id = :orgId + OR EXISTS (SELECT 1 + FROM WEB_CUSTOMER ORG + INNER JOIN rhnTrustedOrgs TORG ON ORG.id = TORG.org_id + WHERE ORG.id = :orgId + AND E.org_id = TORG.org_trust_id) + OR EXISTS (SELECT 1 + FROM rhnAvailableChannels AC, + rhnChannelErrata CE + WHERE CE.errata_id = E.id + AND CE.channel_id = AC.channel_id + AND AC.org_id = :orgId)) + """, Errata.class) + .addSynchronizedEntityClass(Errata.class) + .setParameter("eids", ids) + .setParameter("orgId", orgId) + .list(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/image/ImageFile.java b/java/code/src/com/redhat/rhn/domain/image/ImageFile.java index 633d77a9e6fc..1a4b41c48a98 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ImageFile.java +++ b/java/code/src/com/redhat/rhn/domain/image/ImageFile.java @@ -32,6 +32,7 @@ import javax.persistence.SequenceGenerator; import javax.persistence.Table; + /** * ImageFile */ diff --git a/java/code/src/com/redhat/rhn/domain/image/ImageInfo.java b/java/code/src/com/redhat/rhn/domain/image/ImageInfo.java index fad24873f459..c91168d04bac 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ImageInfo.java +++ b/java/code/src/com/redhat/rhn/domain/image/ImageInfo.java @@ -50,6 +50,7 @@ import javax.persistence.Table; import javax.persistence.Transient; + /** * ImageInfo */ @@ -88,7 +89,7 @@ public class ImageInfo extends BaseDomainHelper { * @return the id */ @Id - @Column(name = "id") + @Column(name = "id", insertable = false, updatable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "imginfo_seq") @SequenceGenerator(name = "imginfo_seq", sequenceName = "suse_imginfo_imgid_seq", allocationSize = 1) @@ -304,13 +305,13 @@ public Pillar getPillar() { } @OneToMany - @JoinColumn(name = "source_image_id", updatable = false) + @JoinColumn(name = "source_image_id") public Set getDeltaSourceFor() { return deltaSourceFor; } @OneToMany - @JoinColumn(name = "target_image_id", updatable = false) + @JoinColumn(name = "target_image_id") public Set getDeltaTargetFor() { return deltaTargetFor; } diff --git a/java/code/src/com/redhat/rhn/domain/image/ImageInfoCustomDataValue.java b/java/code/src/com/redhat/rhn/domain/image/ImageInfoCustomDataValue.java index 26e8ad4ab815..f6d968bea23d 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ImageInfoCustomDataValue.java +++ b/java/code/src/com/redhat/rhn/domain/image/ImageInfoCustomDataValue.java @@ -124,14 +124,14 @@ public User getLastModifier() { /** * @return Returns the created. */ - @Column(insertable = false, updatable = false) + @Column public Date getCreated() { return created; } /** * @return Returns the modified. */ - @Column(insertable = false, updatable = false) + @Column public Date getModified() { return modified; } diff --git a/java/code/src/com/redhat/rhn/domain/image/ImageOverview.java b/java/code/src/com/redhat/rhn/domain/image/ImageOverview.java index 1365b43b7089..93ee9b5aa39e 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ImageOverview.java +++ b/java/code/src/com/redhat/rhn/domain/image/ImageOverview.java @@ -175,8 +175,7 @@ public Integer getCurrRevisionNum() { * @return the build action */ @ManyToOne - @JoinColumn(name = "build_action_id", referencedColumnName = "id", insertable = false, - updatable = false) + @JoinColumn(name = "build_action_id", referencedColumnName = "id") public Action getBuildAction() { return buildAction; } @@ -185,8 +184,7 @@ public Action getBuildAction() { * @return the inspect action */ @ManyToOne - @JoinColumn(name = "inspect_action_id", referencedColumnName = "id", insertable = false, - updatable = false) + @JoinColumn(name = "inspect_action_id", referencedColumnName = "id") public Action getInspectAction() { return inspectAction; } @@ -221,7 +219,8 @@ public boolean isBuilt() { /** * @return the custom data values */ - @OneToMany(fetch = FetchType.LAZY, mappedBy = "imageInfo") + @OneToMany + @JoinColumn(name = "image_info_custom_data_value_id") public Set getCustomDataValues() { return customDataValues; } @@ -232,9 +231,9 @@ public Set getCustomDataValues() { @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "suseImageInfoChannel", joinColumns = { - @JoinColumn(name = "image_info_id", nullable = false, updatable = false)}, + @JoinColumn(name = "image_info_id", nullable = false)}, inverseJoinColumns = { - @JoinColumn(name = "channel_id", nullable = false, updatable = false)} + @JoinColumn(name = "channel_id", nullable = false)} ) public Set getChannels() { return channels; @@ -246,9 +245,9 @@ public Set getChannels() { @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "suseImageInfoInstalledProduct", joinColumns = { - @JoinColumn(name = "image_info_id", nullable = false, updatable = false)}, + @JoinColumn(name = "image_info_id", nullable = false)}, inverseJoinColumns = { - @JoinColumn(name = "installed_product_id", nullable = false, updatable = false) + @JoinColumn(name = "installed_product_id", nullable = false) }) public Set getInstalledProducts() { return installedProducts; @@ -257,7 +256,8 @@ public Set getInstalledProducts() { /** * @return the packages */ - @OneToMany(fetch = FetchType.LAZY, mappedBy = "imageInfo") + @OneToMany + @JoinColumn(name = "packages_id") public Set getPackages() { return packages; } @@ -277,7 +277,8 @@ public Set getPatches() { /** * @return the files */ - @OneToMany(fetch = FetchType.LAZY, mappedBy = "imageInfo") + @OneToMany + @JoinColumn(name = "image_info_id") public Set getImageFiles() { return imageFiles; } 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..01fddee2b563 100644 --- a/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java +++ b/java/code/src/com/redhat/rhn/domain/image/ProfileCustomDataValue.java @@ -104,14 +104,14 @@ public User getLastModifier() { /** * @return Returns the created. */ - @Column(insertable = false, updatable = false) + @Column public Date getCreated() { return created; } /** * @return Returns the modified. */ - @Column(insertable = false, updatable = false) + @Column public Date getModified() { return modified; } diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.hbm.xml b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.hbm.xml index 56a1574a3442..d33d58f6078a 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.hbm.xml @@ -94,24 +94,9 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - - - - - - - - - - - - - - - @@ -127,15 +112,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" and ck in elements(kd.cryptoKeys)]]> - - - SELECT {sortcol.*} - FROM rhnKickstartCommand sortcol, rhnKickstartCommandName cname - WHERE KICKSTART_ID = :id - AND sortcol.ks_command_name_id = cname.id - ORDER BY cname.sort_order, custom_position - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java index db3367c7862c..94b236ebe980 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java @@ -54,6 +54,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.persistence.OrderBy; + + /** * KickstartData - Class representation of the table RhnKSData. */ @@ -81,6 +84,7 @@ public class KickstartData { private Set defaultRegTokens; private Set preserveFileLists; private Set ksPackages = new HashSet<>(); + @OrderBy("commandName.sortOrder, customPosition") private Collection commands = new LinkedHashSet<>(); private Set ips; // rhnKickstartIpRange private Set scripts; // rhnKickstartScript 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..8aead665fb56 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartFactory.java @@ -37,12 +37,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.cobbler.Profile; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.query.Query; -import org.hibernate.type.LongType; -import org.hibernate.type.StringType; import java.io.File; import java.util.ArrayList; @@ -58,6 +54,7 @@ import javax.persistence.criteria.Root; + /** * KickstartFactory */ @@ -190,10 +187,14 @@ else if (minor.contains("u")) { * @return Kickstart Data object by ksid */ public static KickstartData lookupKickstartDataByIdAndOrg(Org orgIn, Long ksid) { - return (KickstartData) HibernateFactory.getSession() - .getNamedQuery("KickstartData.findByIdAndOrg") - .setParameter("id", ksid, LongType.INSTANCE) - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + return (KickstartData) HibernateFactory.getSession() .createNativeQuery(""" + SELECT * FROM RHNKSDATA WHERE + id = :id and + org_id = :org_id + """, + KickstartData.class) + .setParameter("id", ksid) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -204,10 +205,14 @@ public static KickstartData lookupKickstartDataByIdAndOrg(Org orgIn, Long ksid) */ public static KickstartData lookupKickstartDataByCobblerIdAndOrg(Org orgIn, String cobblerId) { - return (KickstartData) HibernateFactory.getSession() - .getNamedQuery("KickstartData.findByCobblerIdAndOrg") + return (KickstartData) HibernateFactory.getSession() .createNativeQuery(""" + SELECT * FROM RHNKSDATA WHERE + cobblerId = :id and + org_id = :org_id + """, + KickstartData.class) .setParameter("id", cobblerId) - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -223,9 +228,14 @@ public static KickstartData lookupKickstartDataByLabelAndOrgId( throw new IllegalArgumentException("kickstartLabel cannot be null"); } return (KickstartData) HibernateFactory.getSession(). - getNamedQuery("KickstartData.findByLabelAndOrg") + createNativeQuery(""" + SELECT * FROM RHNKSDATA WHERE + label = :label and + org_id = :org_id + """, + KickstartData.class) .setParameter(LABEL, label) - .setParameter(ORG_ID, orgId, LongType.INSTANCE) + .setParameter(ORG_ID, orgId) .uniqueResult(); } @@ -241,10 +251,15 @@ public static KickstartData lookupKickstartDataByCILabelAndOrgId( if (StringUtils.isBlank(label)) { throw new IllegalArgumentException("kickstartLabel cannot be null"); } - return (KickstartData) HibernateFactory.getSession(). - getNamedQuery("KickstartData.findByCILabelAndOrg") + return HibernateFactory.getSession(). + createNativeQuery(""" + SELECT * FROM RHNKSDATA WHERE + lower(label) = lower(:label) and + org_id = :org_id + """, + KickstartData.class) .setParameter(LABEL, label) - .setParameter(ORG_ID, orgId, LongType.INSTANCE) + .setParameter(ORG_ID, orgId) .uniqueResult(); } @@ -259,7 +274,11 @@ public static KickstartData lookupKickstartDataByLabel( throw new IllegalArgumentException("kickstartLabel cannot be null"); } return (KickstartData) HibernateFactory.getSession(). - getNamedQuery("KickstartData.findByLabel") + createNativeQuery(""" + SELECT * FROM RHNKSDATA WHERE + label = :label + """, + KickstartData.class) .setParameter(LABEL, label) .uniqueResult(); } @@ -485,7 +504,7 @@ public static CryptoKey lookupCryptoKey(String description, Org org) { if (org != null) { query = session.getNamedQuery("CryptoKey.findByDescAndOrg") .setParameter("description", description) - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE); + .setParameter(ORG_ID, org.getId()); } else { query = session.getNamedQuery("CryptoKey.findByDescAndNullOrg") @@ -502,8 +521,11 @@ public static CryptoKey lookupCryptoKey(String description, Org org) { public static List lookupCryptoKeys(Org org) { //look for Kickstart data by id Session session = HibernateFactory.getSession(); - return session.getNamedQuery("CryptoKey.findByOrg") - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + return session.createNativeQuery(""" + SELECT 0 AS dtype, c.* FROM rhnCryptoKey c + WHERE c.org_id = :org_id + """, CryptoKey.class) + .setParameter(ORG_ID, org.getId()) .list(); } @@ -516,7 +538,7 @@ public static List lookupSslCryptoKeys(Org org) { //look for Kickstart data by id Session session = HibernateFactory.getSession(); return session.getNamedQuery("SslCryptoKey.findByOrg") - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, org.getId()) .list(); } @@ -530,8 +552,8 @@ public static CryptoKey lookupCryptoKeyById(Long keyId, Org org) { //look for Kickstart data by id Session session = HibernateFactory.getSession(); return (CryptoKey) session.getNamedQuery("CryptoKey.findByIdAndOrg") - .setParameter("key_id", keyId, LongType.INSTANCE) - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + .setParameter("key_id", keyId) + .setParameter(ORG_ID, org.getId()) .uniqueResult(); } @@ -545,8 +567,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) - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + return query.setParameter("key_id", keyId) + .setParameter(ORG_ID, org.getId()) .uniqueResult(); } @@ -576,7 +598,7 @@ public static KickstartableTree lookupKickstartTreeByLabel(String label, Org org KickstartableTree retval = (KickstartableTree) session.getNamedQuery("KickstartableTree.findByLabelAndOrg") .setParameter(LABEL, label) - .setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, org.getId()) .uniqueResult(); // If we don't find by label + org then // we try by label and NULL org (RHN owned channel) @@ -614,8 +636,8 @@ public static List lookupKickstartTreesByChannelAndOrg(Long c String query = "KickstartableTree.findByChannelAndOrg"; Session session = HibernateFactory.getSession(); return session.getNamedQuery(query). - setParameter("channel_id", channelId, LongType.INSTANCE). - setParameter(ORG_ID, org.getId(), LongType.INSTANCE) + setParameter("channel_id", channelId). + setParameter(ORG_ID, org.getId()) //Retrieve from cache if there .setCacheable(true).list(); } @@ -630,7 +652,7 @@ public static List lookupKickstartTreesByChannelAndNullOrg( String query = "KickstartableTree.findByChannelAndNullOrg"; Session session = HibernateFactory.getSession(); return session.getNamedQuery(query) - .setParameter("channel_id", channelId, LongType.INSTANCE) + .setParameter("channel_id", channelId) // Retrieve from cache if there .setCacheable(true).list(); } @@ -651,8 +673,8 @@ public static List lookupKickstartableTrees( query = "KickstartableTree.findByChannel"; session = HibernateFactory.getSession(); retval = session.getNamedQuery(query). - setParameter("channel_id", channelId, LongType.INSTANCE). - setParameter(ORG_ID, org.getId(), LongType.INSTANCE). + setParameter("channel_id", channelId). + setParameter(ORG_ID, org.getId()). list(); return retval; } @@ -716,8 +738,8 @@ public static KickstartableTree lookupKickstartTreeByIdAndOrg(Long treeId, Org o if (treeId != null && org != null) { Session session = HibernateFactory.getSession(); Query query = session.getNamedQuery(queryName); - query.setParameter(ORG_ID, org.getId(), LongType.INSTANCE); - query.setParameter("tree_id", treeId, LongType.INSTANCE); + query.setParameter(ORG_ID, org.getId()); + query.setParameter("tree_id", treeId); //Retrieve from cache if there return query.setCacheable(true).uniqueResult(); } @@ -737,8 +759,14 @@ public static KickstartableTree lookupKickstartTreeByIdAndOrg(Long treeId, Org o */ public static KickstartSession lookupKickstartSessionByServer(Long sidIn) { Session session = HibernateFactory.getSession(); - List ksessions = session.getNamedQuery("KickstartSession.findByServer") - .setParameter("server", sidIn, LongType.INSTANCE) + List ksessions = session.createNativeQuery(""" + SELECT * FROM rhnKickStartSession WHERE + new_server_id = :server + OR host_server_id = :server + ORDER BY CREATED DESC + """, + KickstartSession.class) + .setParameter("server", sidIn) .list(); if (!ksessions.isEmpty()) { return ksessions.iterator().next(); @@ -755,9 +783,13 @@ public static KickstartSession lookupKickstartSessionByServer(Long sidIn) { public static KickstartSession lookupDefaultKickstartSessionForKickstartData(KickstartData ksdata) { Session session = HibernateFactory.getSession(); - List ksessions = session.getNamedQuery( - "KickstartSession.findDefaultKickstartSessionForKickstartData") - .setParameter("ksdata", ksdata.getId(), LongType.INSTANCE) + List ksessions = session.createNativeQuery( + """ + SELECT * FROM rhnKickstartSession + WHERE kstree_id = :kstree_id + AND kickstart_mode = :mode order by created desc + """) + .setParameter("kstree_id", ksdata.getId()) .setParameter("mode", KickstartSession.MODE_DEFAULT_SESSION) .list(); if (!ksessions.isEmpty()) { @@ -796,7 +828,7 @@ public static void saveKickstartSession(KickstartSession ksession) { public static List lookupAllKickstartSessionsByServer(Long sidIn) { Session session = HibernateFactory.getSession(); return session.getNamedQuery("KickstartSession.findByServer") - .setParameter("server", sidIn, LongType.INSTANCE) + .setParameter("server", sidIn) .list(); } @@ -829,9 +861,9 @@ public static boolean verifyTreeAssignment(Long channelId, Long orgId, Long tree Session session = HibernateFactory.getSession(); Query query = session. getNamedQuery("KickstartableTree.verifyTreeAssignment"); - query.setParameter("channel_id", channelId, LongType.INSTANCE); - query.setParameter(ORG_ID, orgId, LongType.INSTANCE); - query.setParameter("tree_id", treeId, LongType.INSTANCE); + query.setParameter("channel_id", channelId); + query.setParameter(ORG_ID, orgId); + query.setParameter("tree_id", treeId); KickstartableTree tree = query.uniqueResult(); return tree != null; } @@ -906,8 +938,14 @@ public static void removeKickstartableTree(KickstartableTree tree) { public static List lookupKickstartDatasByTree(KickstartableTree tree) { String query = "KickstartData.lookupByTreeId"; Session session = HibernateFactory.getSession(); - return session.getNamedQuery(query) - .setParameter("kstree_id", tree.getId(), LongType.INSTANCE) + return session.createNativeQuery(""" + SELECT * + FROM rhnKickstartDefaults ksd, + rhnksdata k + WHERE k.id = ksd.kickstart_id + AND ksd.kstree_id = :kstree_id]]> + """, KickstartData.class) + .setParameter("kstree_id", tree.getId()) .list(); } @@ -917,11 +955,10 @@ public static List lookupKickstartDatasByTree(KickstartableTree t * @return List of KickstartData objects if found */ public static List listAllKickstartData() { - Session session = getSession(); - Criteria c = session.createCriteria(KickstartData.class); - // Hibernate does not filter out duplicate references by default - c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); - return c.list(); + String sql = "SELECT DISTINCT * FROM kickstart_data"; + Query query = + getSession().createNativeQuery(sql, KickstartData.class); + return query.getResultList(); } /** @@ -947,7 +984,7 @@ public static KickstartData lookupOrgDefault(Org org) { return (KickstartData) session .getNamedQuery("KickstartData.findOrgDefault") .setParameter("org", org) - .setParameter("isOrgDefault", "Y", StringType.INSTANCE) + .setParameter("isOrgDefault", "Y") .uniqueResult(); } @@ -1077,8 +1114,8 @@ public static List lookupKsPackageByKsDataAndPackageName( KickstartData ksData, PackageName packageName) { return HibernateFactory.getSession() .getNamedQuery("KickstartPackage.findByKickstartDataAndPackageName") - .setParameter("ks_data", ksData.getId(), LongType.INSTANCE) - .setParameter("package_name", packageName.getId(), LongType.INSTANCE) + .setParameter("ks_data", ksData.getId()) + .setParameter("package_name", packageName.getId()) .list(); } diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartSessionQueries.hbm.xml b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartSessionQueries.hbm.xml index 8815252790df..52d8225f4f47 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartSessionQueries.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartSessionQueries.hbm.xml @@ -9,12 +9,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" t.newServer = :server or t.oldServer = :server or t.hostServer = :server order by created desc ]]> - - - - - - - - protected - - RHN_CRYPTOKEY_ID_SEQ - 1 - - - - - - - - - - - - - - - @@ -47,10 +19,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - - - diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKey.java b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKey.java index 9f4a9f7a97c9..ec565c0183fd 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKey.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKey.java @@ -14,23 +14,54 @@ */ package com.redhat.rhn.domain.kickstart.crypto; +import com.redhat.rhn.domain.BaseDomainHelper; import com.redhat.rhn.domain.Identifiable; import com.redhat.rhn.domain.org.Org; + +import java.io.Serializable; import java.nio.charset.StandardCharsets; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + + /** * CryptoKey - Class representation of the table rhnCryptoKey. */ -public class CryptoKey implements Identifiable { - +@Entity +@Table(name = "rhnCryptoKey") +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +public class CryptoKey extends BaseDomainHelper implements Identifiable, Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cryptoKeySeq") + @SequenceGenerator(name = "cryptoKeySeq", sequenceName = "RHN_CRYPTOKEY_ID_SEQ", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "description", nullable = false, length = 1024) private String description; + + @Column(name = "key") private byte[] key; - private CryptoKeyType cryptoKeyType; + @ManyToOne + @JoinColumn(name = "org_id") private Org org; + @ManyToOne + @JoinColumn(name = "crypto_key_type_id", referencedColumnName = "id") + private CryptoKeyType cryptoKeyType; /** * Getter for id @@ -138,5 +169,4 @@ public String getKeyString() { } return ""; } - } diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.hbm.xml b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.hbm.xml index 170952dfe783..a274ed89311c 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.hbm.xml @@ -3,21 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - RHN_CRYPTOKEY_TYPE_ID_SEQ - 1 - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.java b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.java index 88f6e039ed2a..32708823f48a 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/CryptoKeyType.java @@ -14,21 +14,39 @@ */ package com.redhat.rhn.domain.kickstart.crypto; + +import com.redhat.rhn.domain.BaseDomainHelper; + 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.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; /** * CryptoKeyType - Class representation of the table rhnCryptoKeyType. */ -public class CryptoKeyType { - +@Entity +@Table(name = "rhnCryptoKeyType") +public class CryptoKeyType extends BaseDomainHelper { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cryptoKeyTypeSeq") + @SequenceGenerator(name = "cryptoKeyTypeSeq", sequenceName = "RHN_CRYPTOKEY_TYPE_ID_SEQ", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "label", nullable = false, length = 32) private String label; + + @Column(name = "description", nullable = false, length = 256) private String description; - private Date created; - private Date modified; /** * Getter for id @@ -78,38 +96,6 @@ public void setDescription(String descriptionIn) { this.description = descriptionIn; } - /** - * Getter for created - * @return Date to get - */ - public Date getCreated() { - return this.created; - } - - /** - * Setter for created - * @param createdIn to set - */ - public void setCreated(Date createdIn) { - this.created = createdIn; - } - - /** - * Getter for modified - * @return Date to get - */ - public Date getModified() { - return this.modified; - } - - /** - * Setter for modified - * @param modifiedIn to set - */ - public void setModified(Date modifiedIn) { - this.modified = modifiedIn; - } - /** * {@inheritDoc} */ diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/GpgCryptoKey.java b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/GpgCryptoKey.java index 5beb033b8e4e..0beda98c8794 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/GpgCryptoKey.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/GpgCryptoKey.java @@ -14,10 +14,14 @@ */ package com.redhat.rhn.domain.kickstart.crypto; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; /** * GpgCryptoKey */ +@Entity +@DiscriminatorValue("GPG") // Make sure the discriminator value matches the value used in the inheritance strategy public class GpgCryptoKey extends CryptoKey { /** * diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/SslCryptoKey.java b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/SslCryptoKey.java index 583560a70b3b..61c737a1045a 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/crypto/SslCryptoKey.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/crypto/SslCryptoKey.java @@ -14,10 +14,14 @@ */ package com.redhat.rhn.domain.kickstart.crypto; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; /** * SslCryptoKey */ +@Entity +@DiscriminatorValue("SSL") // Make sure the discriminator value matches the value used in the inheritance strategy public class SslCryptoKey extends CryptoKey { /** * diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/test/KickstartDataTest.java b/java/code/src/com/redhat/rhn/domain/kickstart/test/KickstartDataTest.java index 7a2e27823060..fd49ffe1dd57 100644 --- a/java/code/src/com/redhat/rhn/domain/kickstart/test/KickstartDataTest.java +++ b/java/code/src/com/redhat/rhn/domain/kickstart/test/KickstartDataTest.java @@ -74,7 +74,6 @@ import org.cobbler.Distro; import org.cobbler.test.MockConnection; import org.hibernate.Session; -import org.hibernate.type.LongType; import org.junit.jupiter.api.Test; import java.io.File; @@ -333,7 +332,7 @@ private KickstartData lookupById(Org orgIn, Long id) { Session session = HibernateFactory.getSession(); return (KickstartData) session.getNamedQuery("KickstartData.findByIdAndOrg") .setParameter("id", id) - .setParameter("org_id", orgIn.getId(), LongType.INSTANCE) + .setParameter("org_id", orgIn.getId()) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/domain/matcher/MatcherRunDataFactory.java b/java/code/src/com/redhat/rhn/domain/matcher/MatcherRunDataFactory.java index db127e62e604..edbb9a646cce 100644 --- a/java/code/src/com/redhat/rhn/domain/matcher/MatcherRunDataFactory.java +++ b/java/code/src/com/redhat/rhn/domain/matcher/MatcherRunDataFactory.java @@ -20,6 +20,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + + /** * MatcherRunData hibernate factory. */ @@ -44,9 +51,22 @@ public static void updateData(MatcherRunData newData) { * @return MatcherRunData instance */ public static MatcherRunData getSingle() { - return (MatcherRunData) getSession() - .createCriteria(MatcherRunData.class) - .uniqueResult(); + CriteriaBuilder cb = getSession().getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(MatcherRunData.class); + Root root = cq.from(MatcherRunData.class); + cq.select(root); + + TypedQuery query = getSession().createQuery(cq); + + try { + return query.getSingleResult(); + } + catch (NoResultException e) { + return null; + } + catch (Exception e) { + throw new RuntimeException("Error retrieving MatcherRunData", e); + } } /** diff --git a/java/code/src/com/redhat/rhn/domain/notification/UserNotification.java b/java/code/src/com/redhat/rhn/domain/notification/UserNotification.java index 8475d5c1cf34..0dfcc3e8b669 100644 --- a/java/code/src/com/redhat/rhn/domain/notification/UserNotification.java +++ b/java/code/src/com/redhat/rhn/domain/notification/UserNotification.java @@ -34,6 +34,7 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; + /** * A notification UserNotification Object. */ diff --git a/java/code/src/com/redhat/rhn/domain/notification/types/SubscriptionWarning.java b/java/code/src/com/redhat/rhn/domain/notification/types/SubscriptionWarning.java index 0e03d8d7b0b4..efdae975f639 100644 --- a/java/code/src/com/redhat/rhn/domain/notification/types/SubscriptionWarning.java +++ b/java/code/src/com/redhat/rhn/domain/notification/types/SubscriptionWarning.java @@ -31,7 +31,7 @@ public class SubscriptionWarning implements NotificationData { * @return boolean **/ public boolean expiresSoon() { - Optional result = getSession().createSQLQuery( + Optional result = getSession().createNativeQuery( "select exists (select name, expires_at, status, subtype " + "from susesccsubscription where subtype != 'internal' " + " and ((status = 'ACTIVE' and expires_at < now() + interval '90 day') " + diff --git a/java/code/src/com/redhat/rhn/domain/org/Org.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/Org.hbm.xml index b47046bb96d4..836b86f0c379 100644 --- a/java/code/src/com/redhat/rhn/domain/org/Org.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/org/Org.hbm.xml @@ -3,66 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - web_customer_id_seq - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/Org.java b/java/code/src/com/redhat/rhn/domain/org/Org.java index 347f576c2a6e..8f7135d6829d 100644 --- a/java/code/src/com/redhat/rhn/domain/org/Org.java +++ b/java/code/src/com/redhat/rhn/domain/org/Org.java @@ -32,6 +32,7 @@ import com.redhat.rhn.domain.iss.IssSlave; import com.redhat.rhn.domain.org.usergroup.UserGroup; import com.redhat.rhn.domain.org.usergroup.UserGroupFactory; +import com.redhat.rhn.domain.org.usergroup.UserGroupImpl; import com.redhat.rhn.domain.role.Role; import com.redhat.rhn.domain.server.EntitlementServerGroup; import com.redhat.rhn.domain.server.ManagedServerGroup; @@ -49,8 +50,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.hibernate.Session; import java.io.Serializable; @@ -63,36 +62,86 @@ import java.util.Map; import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Transient; + + /** * Class Org that reflects the DB representation of web_customer DB table: * web_customer */ +@Entity +@Table(name = "WEB_CUSTOMER") public class Org extends BaseDomainHelper implements SaltConfigurable, Serializable { private static final String USER_ID_KEY = "user_id"; private static final String ORG_ID_KEY = "org_id"; - protected static Logger log = LogManager.getLogger(Org.class); - + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "web_customer_seq") + @SequenceGenerator(name = "web_customer_seq", sequenceName = "web_customer_id_seq", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "name") private String name; - private Set usergroups; + + @OneToOne(mappedBy = "org") // mappedBy refers to the field in Org that owns the relationship + private OrgConfig orgConfig; + + @OneToOne(mappedBy = "org") // mappedBy refers to the field in Org that owns the relationship + private OrgAdminManagement orgAdminMgmt; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "orgId") + private Set userGroups; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "org") private Set ownedChannels; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "org") private Set customDataKeys; + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinTable( + name = "rhnTrustedOrgs", + joinColumns = @JoinColumn(name = "org_id"), + inverseJoinColumns = @JoinColumn(name = "org_trust_id") + ) private Set trustedOrgs; + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinTable( + name = "rhnissslaveorgs", + joinColumns = @JoinColumn(name = "org_id"), + inverseJoinColumns = @JoinColumn(name = "slave_id") + ) private Set allowedToSlaves; - private Token token; - private OrgAdminManagement orgAdminMgmt; - private OrgConfig orgConfig; - private Set pillars = new HashSet<>(); + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "org") + private Set pillars; + + @Transient + private Token token; /** * Construct new Org */ protected Org() { - usergroups = new HashSet<>(); + userGroups = new HashSet<>(); } /** @@ -183,7 +232,7 @@ public void setName(String nameIn) { */ public Set getRoles() { Set orgRoles = new HashSet<>(); - for (UserGroup ug : usergroups) { + for (UserGroup ug : userGroups) { orgRoles.add(ug.getRole()); } return Collections.unmodifiableSet(orgRoles); @@ -208,9 +257,9 @@ public void addRole(Role newRole) { // specified role. if (!hasRole(newRole)) { // Create a new UserGroup based on the Role specified - UserGroup newGroup = UserGroupFactory + UserGroupImpl newGroup = UserGroupFactory .createUserGroup(this, newRole); - usergroups.add(newGroup); + userGroups.add(newGroup); } } @@ -221,7 +270,7 @@ public void addRole(Role newRole) { * @return the UserGroup if found, otherwise null. */ public UserGroup getUserGroup(Role roleIn) { - for (UserGroup ug : usergroups) { + for (UserGroup ug : userGroups) { if (ug.getRole().equals(roleIn)) { return ug; } @@ -234,8 +283,8 @@ public UserGroup getUserGroup(Role roleIn) { * to map Roles to UserGroups * @return userGroup array */ - public Set getUserGroups() { - return usergroups; + public Set getUserGroups() { + return userGroups; } /** @@ -243,8 +292,8 @@ public Set getUserGroups() { * to map Roles to UserGroups * @param ugIn the new array */ - public void setUserGroups(Set ugIn) { - usergroups = ugIn; + public void setUserGroups(Set ugIn) { + userGroups = ugIn; } /** diff --git a/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.hbm.xml deleted file mode 100644 index 9b22908d85cd..000000000000 --- a/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.hbm.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - org - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.java b/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.java index 7153286609a0..50fd0036bc97 100644 --- a/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.java +++ b/java/code/src/com/redhat/rhn/domain/org/OrgAdminManagement.java @@ -17,14 +17,48 @@ import com.redhat.rhn.domain.BaseDomainHelper; +import org.hibernate.annotations.Type; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + + /** * OrgAdminManagement */ -public class OrgAdminManagement extends BaseDomainHelper { +@Entity +@Table(name = "rhnOrgAdminManagement") +public class OrgAdminManagement extends BaseDomainHelper implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "org_id") private Long orgId; + + @OneToOne + @JoinColumn(name = "org_id", insertable = false, updatable = false) + private Org org; // The foreign key relationship with Org entity + + @Column(name = "enabled", nullable = false) + @Type(type = "yes_no") private boolean enabled; + public Org getOrg() { + return org; + } + + public void setOrg(Org orgIn) { + org = orgIn; + } + /** * @return Returns the orgId. */ diff --git a/java/code/src/com/redhat/rhn/domain/org/OrgConfig.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/OrgConfig.hbm.xml deleted file mode 100644 index c4f1bac7b8f9..000000000000 --- a/java/code/src/com/redhat/rhn/domain/org/OrgConfig.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - org - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/OrgConfig.java b/java/code/src/com/redhat/rhn/domain/org/OrgConfig.java index 0435594b428e..617f337c54a8 100644 --- a/java/code/src/com/redhat/rhn/domain/org/OrgConfig.java +++ b/java/code/src/com/redhat/rhn/domain/org/OrgConfig.java @@ -20,23 +20,55 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + + /** * Class OrgConfig that reflects the DB representation of rhnOrgConfiguration DB table: * rhnOrgConfiguration */ +@Entity +@Table(name = "rhnOrgConfiguration") public class OrgConfig extends BaseDomainHelper { protected static Logger log = LogManager.getLogger(OrgConfig.class); + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) // Or use another generation strategy as required + @Column(name = "org_id") private Long orgId; + + @OneToOne + @JoinColumn(name = "org_id", insertable = false, updatable = false) + private Org org; + + @Column(name = "staging_content_enabled", nullable = false) private boolean stagingContentEnabled; + + @Column(name = "errata_emails_enabled", nullable = false) private boolean errataEmailsEnabled; + + @Column(name = "scapfile_upload_enabled", nullable = false) private boolean scapfileUploadEnabled; + + @Column(name = "scap_file_sizelimit", nullable = false) private Long scapFileSizelimit; + + @Column(name = "scap_retention_period_days", nullable = true) private Long scapRetentionPeriodDays; + + @Column(name = "create_default_sg", nullable = false) private boolean createDefaultSg; - private boolean clmSyncPatches; + @Column(name = "clm_sync_patches", nullable = false) + private boolean clmSyncPatches; /** * Gets the current value of org_id * @return Returns the value of org_id @@ -161,4 +193,13 @@ public boolean isClmSyncPatches() { public void setClmSyncPatches(boolean clmSyncPatchesIn) { clmSyncPatches = clmSyncPatchesIn; } + + public Org getOrg() { + return org; + } + + public void setOrg(Org orgIn) { + org = orgIn; + } + } diff --git a/java/code/src/com/redhat/rhn/domain/org/OrgFactory.java b/java/code/src/com/redhat/rhn/domain/org/OrgFactory.java index 25ccd5f4a4e0..0b9553ac7712 100644 --- a/java/code/src/com/redhat/rhn/domain/org/OrgFactory.java +++ b/java/code/src/com/redhat/rhn/domain/org/OrgFactory.java @@ -36,7 +36,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; -import org.hibernate.type.LongType; import java.sql.Types; import java.util.Collections; @@ -159,7 +158,7 @@ public static CustomDataKey lookupKeyById(Long cikid) { Session session = HibernateFactory.getSession(); return (CustomDataKey) session.getNamedQuery("CustomDataKey.findById") - .setParameter("id", cikid, LongType.INSTANCE) + .setParameter("id", cikid) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -234,7 +233,7 @@ public static Org lookupById(Long id) { public static Long getActiveUsers(Org orgIn) { Session session = HibernateFactory.getSession(); return (Long) session.getNamedQuery("Org.numOfActiveUsers") - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -247,7 +246,7 @@ public static Long getActiveUsers(Org orgIn) { public static Long getActiveSystems(Org orgIn) { Session session = HibernateFactory.getSession(); return (Long) session.getNamedQuery("Org.numOfSystems") - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -259,7 +258,7 @@ public static Long getActiveSystems(Org orgIn) { public static Long getServerGroups(Org orgIn) { Session session = HibernateFactory.getSession(); return (Long) session.getNamedQuery("Org.numOfServerGroups") - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -271,7 +270,7 @@ public static Long getServerGroups(Org orgIn) { public static Long getConfigChannels(Org orgIn) { Session session = HibernateFactory.getSession(); return (Long) session.getNamedQuery("Org.numOfConfigChannels") - .setParameter(ORG_ID, orgIn.getId(), LongType.INSTANCE) + .setParameter(ORG_ID, orgIn.getId()) .uniqueResult(); } @@ -309,10 +308,14 @@ public static Long getKickstarts(Org orgIn) { * @return the Template found */ public static TemplateString lookupTemplateByLabel(String label) { + // Obtain the current Hibernate session Session session = HibernateFactory.getSession(); - return (TemplateString) session.getNamedQuery("TemplateString.findByLabel") + + // Execute the native SQL query + return (TemplateString) session.createNativeQuery( + "SELECT * FROM RHNTEMPLATESTRING t WHERE t.label = :label", TemplateString.class) .setParameter("label", label) - //Retrieve from cache if there + // Retrieve from cache if available .setCacheable(true) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/domain/org/TemplateString.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/TemplateString.hbm.xml deleted file mode 100644 index a4ed8fc6a064..000000000000 --- a/java/code/src/com/redhat/rhn/domain/org/TemplateString.hbm.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - protected - - RHN_TEMPLATE_STR_ID_SEQ - 1 - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/TemplateString.java b/java/code/src/com/redhat/rhn/domain/org/TemplateString.java index 781ed3f96987..9928c4b61a38 100644 --- a/java/code/src/com/redhat/rhn/domain/org/TemplateString.java +++ b/java/code/src/com/redhat/rhn/domain/org/TemplateString.java @@ -16,15 +16,43 @@ import com.redhat.rhn.domain.BaseDomainHelper; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + + + /** * TemplateString */ +@Entity +@Table(name = "RHNTEMPLATESTRING") public class TemplateString extends BaseDomainHelper { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "template_string_seq") + @SequenceGenerator(name = "template_string_seq", sequenceName = "RHN_TEMPLATE_STR_ID_SEQ", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "label", length = 64) private String label; + + @Column(name = "value", length = 4000) private String value; + + @Column(name = "description", length = 512) private String description; + + @ManyToOne + @JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false, insertable = false, + updatable = false) private TemplateCategory category; /** 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/org/usergroup/UserGroupFactory.java b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupFactory.java index 63f5cd6bef71..ef8d076da75d 100644 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupFactory.java +++ b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupFactory.java @@ -57,8 +57,8 @@ protected Logger getLogger() { * @param role the Role to base this new UserGroup on. * @return the UserGroup created */ - public static UserGroup createUserGroup(Org org, Role role) { - UserGroup retval = new UserGroupImpl(); + public static UserGroupImpl createUserGroup(Org org, Role role) { + UserGroupImpl retval = new UserGroupImpl(); LocalizationService ls = LocalizationService.getInstance(); // Concat the Role name with the letter s to form the UserGroup name // such as: "Organization Applicants" @@ -166,8 +166,8 @@ public static OrgUserExtGroup lookupOrgExtGroupByLabelAndOrg(String labelIn, Org */ public static int deleteTemporaryRoles() { return HibernateFactory.getSession() - .getNamedQuery("UserGroupMembers.deleteTemporary") - .executeUpdate(); + .createNativeQuery("DELETE FROM rhnUserGroupMembers WHERE temporary = 'Y'", Integer.class) + .executeUpdate(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.hbm.xml deleted file mode 100644 index 90d3db36e18e..000000000000 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.hbm.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - protected - - rhn_user_group_id_seq - 1 - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.java b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.java index 7526307cb98e..28e81174063d 100644 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.java +++ b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupImpl.java @@ -17,19 +17,47 @@ import com.redhat.rhn.domain.BaseDomainHelper; import com.redhat.rhn.domain.role.Role; +import com.redhat.rhn.domain.role.RoleImpl; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; /** * Class UserGroup that reflects the DB representation of RHNUSERGROUP * DB table: RHNUSERGROUP */ +@Entity +@Table(name = "RHNUSERGROUP") +@SequenceGenerator(name = "rhn_user_group_seq", sequenceName = "rhn_user_group_id_seq", allocationSize = 1) public class UserGroupImpl extends BaseDomainHelper implements UserGroup { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_user_group_seq") + @Column(name = "id") private Long id; + + @Column(name = "name", length = 64) private String name; + + @Column(name = "description", length = 1024) private String description; + + @Column(name = "current_members", insertable = false, updatable = true) private Long currentMembers; + + @Column(name = "org_id") private Long orgId; - private Role role; + + @ManyToOne + @JoinColumn(name = "group_type", referencedColumnName = "id", nullable = false) + private RoleImpl role; /** * Getter for id @@ -108,7 +136,7 @@ public void setCurrentMembers(Long currentMembersIn) { * {@inheritDoc} */ @Override - public Role getRole() { + public RoleImpl getRole() { return role; } @@ -118,7 +146,7 @@ public Role getRole() { */ @Override public void setRole(Role roleIn) { - role = roleIn; + role = (RoleImpl) roleIn; } /** diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.hbm.xml b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.hbm.xml deleted file mode 100644 index 1c915d72a486..000000000000 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.hbm.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.java b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.java index de980be37555..3c7cdfd6fa68 100644 --- a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.java +++ b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembers.java @@ -14,23 +14,41 @@ */ package com.redhat.rhn.domain.org.usergroup; -import com.redhat.rhn.domain.BaseDomainHelper; -import com.redhat.rhn.domain.user.User; +import com.redhat.rhn.domain.user.legacy.UserImpl; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.hibernate.annotations.Type; import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + /** * UserGroupMembers */ -public class UserGroupMembers extends BaseDomainHelper implements Serializable { +@Entity +@Table(name = "rhnUserGroupMembers", uniqueConstraints = { + @UniqueConstraint(columnNames = {"user_id", "user_group_id"}) +}) +public class UserGroupMembers implements Serializable { + @EmbeddedId + private UserGroupMembersId id; + + @Column(name = "user_id", insertable = false, updatable = false) + private UserImpl user; + + @Column(name = "user_group_id", insertable = false, updatable = false) + private UserGroupImpl userGroup; - private User user; - private UserGroup userGroup; - private boolean temporary; + @Column(name = "temporary", insertable = false, updatable = false, nullable = false) + @Type(type = "yes_no") + private boolean temporary = false; // default value to avoid nulls /** * Constructor @@ -44,10 +62,11 @@ public UserGroupMembers() { * @param userIn user * @param ugIn user group */ - public UserGroupMembers(User userIn, UserGroup ugIn) { + public UserGroupMembers(UserImpl userIn, UserGroupImpl ugIn) { + id = new UserGroupMembersId(userIn, ugIn, false); user = userIn; userGroup = ugIn; - temporary = false; + this.setTemporary(false); } /** @@ -56,50 +75,53 @@ public UserGroupMembers(User userIn, UserGroup ugIn) { * @param ugIn user group * @param tempIn temporary flag */ - public UserGroupMembers(User userIn, UserGroup ugIn, boolean tempIn) { + public UserGroupMembers(UserImpl userIn, UserGroupImpl ugIn, boolean tempIn) { + id = new UserGroupMembersId(userIn, ugIn, tempIn); user = userIn; userGroup = ugIn; - temporary = tempIn; + this.setTemporary(temporary); } /** * @return Returns the user. */ - public User getUser() { + public UserImpl getUser() { return user; } /** * @param userIn The user to set. */ - public void setUser(User userIn) { + public void setUser(UserImpl userIn) { user = userIn; } /** * @return Returns the userGroup. */ - public UserGroup getUserGroup() { + public UserGroupImpl getUserGroup() { return userGroup; } /** * @param userGroupIn The userGroup to set. */ - public void setUserGroup(UserGroup userGroupIn) { + public void setUserGroup(UserGroupImpl userGroupIn) { userGroup = userGroupIn; } /** * @return Returns the temporary. */ - public boolean getTemporary() { + @Type(type = "yes_no") + public boolean isTemporary() { return temporary; } /** * @param temporaryIn The temporary to set. */ + @Type(type = "yes_no") public void setTemporary(boolean temporaryIn) { temporary = temporaryIn; } @@ -126,7 +148,16 @@ public int hashCode() { return new HashCodeBuilder() .append(this.getUser()) .append(this.getUserGroup()) - .append(this.getTemporary()) + .append(this.isTemporary()) .toHashCode(); } + + public UserGroupMembersId getId() { + return id; + } + + public void setId(UserGroupMembersId idIn) { + id = idIn; + } + } diff --git a/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembersId.java b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembersId.java new file mode 100644 index 000000000000..11f671bcc220 --- /dev/null +++ b/java/code/src/com/redhat/rhn/domain/org/usergroup/UserGroupMembersId.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 SUSE LLC + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * Red Hat trademarks are not licensed under GPLv2. No permission is + * granted to use or replicate Red Hat trademarks that are incorporated + * in this software or its documentation. + */ +package com.redhat.rhn.domain.org.usergroup; + +import com.redhat.rhn.domain.user.legacy.UserImpl; + +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.hibernate.annotations.Type; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; + + +@MappedSuperclass +@Embeddable +public class UserGroupMembersId implements Serializable { + + @ManyToOne + @JoinColumn(name = "user_id", insertable = false, updatable = false) + private UserImpl userId; + + @ManyToOne + @JoinColumn(name = "user_group_id", insertable = false, updatable = false) + private UserGroupImpl userGroupId; + + @Column(name = "temporary", insertable = false, updatable = false) + @Type(type = "yes_no") + private boolean temporary; + + /** + * default constructor + */ + public UserGroupMembersId() { } + + /** + * constructor + * @param userIn user + * @param userGroupIn user group + * @param temporaryIn true if it's a temporary group member + * + */ + public UserGroupMembersId(UserImpl userIn, UserGroupImpl userGroupIn, boolean temporaryIn) { + this.userId = userIn; + this.userGroupId = userGroupIn; + this.setTemporary(temporaryIn); + } + + // Getters and setters + public UserImpl getUserId() { + return userId; + } + + public void setUserId(UserImpl user) { + this.userId = user; + } + + public UserGroupImpl getUserGroupId() { + return userGroupId; + } + + public void setUserGroupId(UserGroupImpl userGroup) { + this.userGroupId = userGroup; + } + + @Type(type = "yes_no") + public boolean isTemporary() { + return temporary; + } + + @Type(type = "yes_no") + public void setTemporary(boolean temporaryIn) { + this.temporary = temporaryIn; + } + + // Override equals and hashCode + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UserGroupMembersId that = (UserGroupMembersId) o; + return temporary == that.temporary && + userId.equals(that.userId) && + userGroupId.equals(that.userGroupId); + } + + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(this.getUserId()) + .append(this.getUserGroupId()) + .append(this.isTemporary()) + .toHashCode(); + } +} 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..fb690503b247 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageEvrFactory.java @@ -95,7 +95,7 @@ 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( + return (PackageEvr) session.getNamedQuery("PackageEvr.findById").setParameter( "id", id).uniqueResult(); } @@ -111,10 +111,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) + .setParameter("v_in", version) + .setParameter("r_in", release) + .setParameter("t_in", type.getDbString()) .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..a374195fa4fa 100644 --- a/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java +++ b/java/code/src/com/redhat/rhn/domain/rhnpackage/PackageFactory.java @@ -300,7 +300,7 @@ 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).uniqueResult(); } /** @@ -313,7 +313,7 @@ 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).uniqueResult(); } /** @@ -342,8 +342,8 @@ 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( + "Package.lookupByNevra").setParameter("org", org).setParameter("name", name) + .setParameter("version", version).setParameter("release", release).setParameter( "arch", arch).list(); if (epoch == null || packages.size() < 2) { @@ -388,11 +388,11 @@ 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) + .setParameter("channel", channel) + .setParameter("name", name) + .setParameter("version", version) + .setParameter("release", release) + .setParameter("arch", arch) .setString("checksum", checksum.orElse(null)) .list(); 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..0155f5b1bfb4 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 @@ -73,7 +73,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/role/Role.hbm.xml b/java/code/src/com/redhat/rhn/domain/role/Role.hbm.xml index 32ab3ac9c003..823df1ee01d4 100644 --- a/java/code/src/com/redhat/rhn/domain/role/Role.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/role/Role.hbm.xml @@ -3,23 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - protected - - rhn_usergroup_type_seq - 1 - - - - - - - - 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..d44cd724967b 100644 --- a/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java +++ b/java/code/src/com/redhat/rhn/domain/role/RoleFactory.java @@ -56,7 +56,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -70,7 +70,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); diff --git a/java/code/src/com/redhat/rhn/domain/role/RoleImpl.java b/java/code/src/com/redhat/rhn/domain/role/RoleImpl.java index 8b4bf4db22aa..5dc99fbb883f 100644 --- a/java/code/src/com/redhat/rhn/domain/role/RoleImpl.java +++ b/java/code/src/com/redhat/rhn/domain/role/RoleImpl.java @@ -20,16 +20,35 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * Class Role that reflects the DB representation of RHNUSERGROUP * DB table: RHNUSERGROUP */ -public class RoleImpl extends BaseDomainHelper implements Role { - +@Entity +@Table(name = "RHNUSERGROUPTYPE") +public class RoleImpl extends BaseDomainHelper implements Role, Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_usergroup_type_seq") + @SequenceGenerator(name = "rhn_usergroup_type_seq", sequenceName = "rhn_usergroup_type_seq", allocationSize = 1) + @Column(name = "id") private Long id; + + @Column(name = "name", length = 64) private String name; - private String label; + @Column(name = "label", length = 64) + private String label; /** * Protected constructor 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 0704321eb030..1f6660e8fc31 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,6 @@ 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 java.math.BigDecimal; import java.util.ArrayList; @@ -53,6 +50,10 @@ import java.util.Set; import java.util.stream.Stream; +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.Query; +import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaQuery; @@ -176,9 +177,10 @@ public static SCCSubscription saveJsonSubscription(SCCSubscriptionJson jsonSub, @SuppressWarnings("unchecked") public static List lookupSubscriptions() { log.debug("Retrieving subscriptions from cache"); - Session session = getSession(); - Criteria c = session.createCriteria(SCCSubscription.class); - return c.list(); + String sql = "SELECT * FROM suseSCCSubscription"; + TypedQuery query + = getSession().createNativeQuery(sql, SCCSubscription.class); + return query.getResultList(); } /** @@ -190,20 +192,29 @@ public static SCCSubscription lookupSubscriptionBySccId(Long id) { if (id == null) { return null; } - Session session = getSession(); - Criteria c = session.createCriteria(SCCSubscription.class); - c.add(Restrictions.eq("sccId", id)); - return (SCCSubscription) c.uniqueResult(); + + // Define the SQL query + String sql = "SELECT * FROM suseSCCSubscription WHERE scc_id = :sccId"; + + // Create and execute the query + Query query + = getSession().createNativeQuery(sql, SCCSubscription.class); + query.setParameter("sccId", id); + try { + return (SCCSubscription) query.getSingleResult(); + } + catch (NoResultException e) { + return null; + } } /** * Clear all subscriptions from the database. */ public static void clearSubscriptions() { - CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaDelete delete = builder.createCriteriaDelete(SCCSubscription.class); - delete.from(SCCSubscription.class); - getSession().createQuery(delete).executeUpdate(); - + EntityManager em = getSession(); // Obtain EntityManager + String sql = "DELETE FROM suseSCCSubscription"; + Query query = em.createNativeQuery(sql); + query.executeUpdate(); } /** @@ -213,9 +224,12 @@ public static void clearSubscriptions() { @SuppressWarnings("unchecked") public static List lookupOrderItems() { log.debug("Retrieving orderItems from cache"); - Session session = getSession(); - Criteria c = session.createCriteria(SCCOrderItem.class); - return c.list(); + + String sql = "SELECT * FROM suseSCCOrderItem"; + + TypedQuery query + = getSession().createNativeQuery(sql, SCCOrderItem.class); + return query.getResultList(); } /** 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/Capability.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/Capability.hbm.xml deleted file mode 100644 index 62b332f2589f..000000000000 --- a/java/code/src/com/redhat/rhn/domain/server/Capability.hbm.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - protected - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/server/Capability.java b/java/code/src/com/redhat/rhn/domain/server/Capability.java index f70412fe0a09..ffb3569e456c 100644 --- a/java/code/src/com/redhat/rhn/domain/server/Capability.java +++ b/java/code/src/com/redhat/rhn/domain/server/Capability.java @@ -17,12 +17,30 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; /** * Capability */ -public class Capability { +@Entity +@Table(name = "rhnClientCapabilityName") +public class Capability implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private Long id; + + @Column(name = "name") private String name; diff --git a/java/code/src/com/redhat/rhn/domain/server/ClientCapability.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/ClientCapability.hbm.xml deleted file mode 100644 index d2e1cd481436..000000000000 --- a/java/code/src/com/redhat/rhn/domain/server/ClientCapability.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/server/ClientCapability.java b/java/code/src/com/redhat/rhn/domain/server/ClientCapability.java index 47bb1a66c5a7..28edc22a519a 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ClientCapability.java +++ b/java/code/src/com/redhat/rhn/domain/server/ClientCapability.java @@ -19,13 +19,29 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + + /** * ClientCapability */ -public class ClientCapability extends BaseDomainHelper { +@Entity +@Table(name = "rhnClientCapability") +public class ClientCapability extends BaseDomainHelper implements Serializable { + + private static final long serialVersionUID = 1L; + // Composite ID + @EmbeddedId private ClientCapabilityId id; + // Regular fields + @Column(name = "version", nullable = false) private long version; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/ClientCapabilityId.java b/java/code/src/com/redhat/rhn/domain/server/ClientCapabilityId.java index 3611e9b460ec..0e3af5185ccd 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ClientCapabilityId.java +++ b/java/code/src/com/redhat/rhn/domain/server/ClientCapabilityId.java @@ -19,12 +19,25 @@ import java.io.Serializable; +import javax.persistence.Embeddable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + + /** * ClientCapabilityId */ +@Embeddable public class ClientCapabilityId implements Serializable { + private static final long serialVersionUID = 1L; + + @ManyToOne + @JoinColumn(name = "server_id", nullable = false) private Server server; + + @ManyToOne + @JoinColumn(name = "capability_name_id", nullable = false) private Capability capability; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/CustomDataValue.java b/java/code/src/com/redhat/rhn/domain/server/CustomDataValue.java index 6548aa2e85d6..7f80ae153ed6 100644 --- a/java/code/src/com/redhat/rhn/domain/server/CustomDataValue.java +++ b/java/code/src/com/redhat/rhn/domain/server/CustomDataValue.java @@ -17,6 +17,7 @@ import com.redhat.rhn.common.util.StringUtil; import com.redhat.rhn.domain.org.CustomDataKey; import com.redhat.rhn.domain.user.User; +import com.redhat.rhn.domain.user.legacy.UserImpl; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -24,18 +25,47 @@ import java.io.Serializable; import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + /** * CustomDataValue */ +@Entity +@Table(name = "rhnServerCustomDataValue") public class CustomDataValue implements Serializable { private static final long serialVersionUID = 1L; + + @Id + @ManyToOne + @JoinColumn(name = "server_id", insertable = false, updatable = false) private Server server; + + @Id + @ManyToOne + @JoinColumn(name = "key_id", insertable = false, updatable = false) private CustomDataKey key; + + @Column(name = "value", length = 4000) private String value; + + @ManyToOne(targetEntity = UserImpl.class) + @JoinColumn(name = "created_by") private User creator; + + @ManyToOne(targetEntity = UserImpl.class) + @JoinColumn(name = "last_modified_by") private User lastModifier; + + @Column(name = "created", insertable = false, updatable = false) private Date created; + + @Column(name = "modified", insertable = false, updatable = false) private Date modified; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/CustomDataValue_legacyUser.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/CustomDataValue_legacyUser.hbm.xml index d00cf8ff50da..b2fc4ed08a74 100644 --- a/java/code/src/com/redhat/rhn/domain/server/CustomDataValue_legacyUser.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/CustomDataValue_legacyUser.hbm.xml @@ -3,33 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - { - /** - * - */ private static final long serialVersionUID = -6158622200264142583L; + + // Composite primary key + @Id + @ManyToOne + @JoinColumn(name = "server_id") // Foreign key to the Server entity + private Server server; + + @Id + @ManyToOne + @JoinColumn(name = "evr_id") // Foreign key to the PackageEvr entity private PackageEvr evr; + + @Id + @ManyToOne + @JoinColumn(name = "name_id") // Foreign key to the PackageName entity private PackageName name; + + @Id + @ManyToOne + @JoinColumn(name = "package_arch_id") // Foreign key to the PackageArch entity private PackageArch arch; - private Server server; + + // Property for install time + @Column(name = "installtime") private Date installTime; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/ManagedServerGroup.java b/java/code/src/com/redhat/rhn/domain/server/ManagedServerGroup.java index f4676d125113..40b042468587 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ManagedServerGroup.java +++ b/java/code/src/com/redhat/rhn/domain/server/ManagedServerGroup.java @@ -16,19 +16,39 @@ import com.redhat.rhn.GlobalInstanceHolder; import com.redhat.rhn.domain.user.User; +import com.redhat.rhn.domain.user.legacy.UserImpl; import com.redhat.rhn.manager.system.ServerGroupManager; +import org.hibernate.annotations.Cascade; + import java.util.HashSet; import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Transient; /** * This class represents the User Managed Server Groups * i.e. the types */ +@Entity +@DiscriminatorValue("null") public class ManagedServerGroup extends ServerGroup { - private Set associatedAdmins = new HashSet<>(); + @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinTable( + name = "rhnUserServerGroupPerms", + joinColumns = @JoinColumn(name = "server_group_id"), + inverseJoinColumns = @JoinColumn(name = "user_id") + ) + private Set associatedAdmins = new HashSet<>(); + @Transient private final ServerGroupManager serverGroupManager = GlobalInstanceHolder.SERVER_GROUP_MANAGER; /** @@ -38,7 +58,7 @@ public class ManagedServerGroup extends ServerGroup { * list does not include that. * @return a set of users */ - protected Set getAssociatedAdmins() { + protected Set getAssociatedAdmins() { return associatedAdmins; } @@ -50,7 +70,7 @@ protected Set getAssociatedAdmins() { * @param user needed for authentication * @return a set of users */ - public Set getAssociatedAdminsFor(User user) { + public Set getAssociatedAdminsFor(User user) { serverGroupManager.validateAdminCredentials(user); return getAssociatedAdmins(); } @@ -59,8 +79,8 @@ public Set getAssociatedAdminsFor(User user) { * sets admins * @param newUsers the associated users of the group */ - protected void setAssociatedAdmins(Set newUsers) { - this.associatedAdmins = newUsers; + protected void setAssociatedAdmins(Set newUsers) { + this.associatedAdmins.addAll(newUsers); } /** diff --git a/java/code/src/com/redhat/rhn/domain/server/MinionServer.java b/java/code/src/com/redhat/rhn/domain/server/MinionServer.java index 5d37415107fd..127dcf8b768d 100644 --- a/java/code/src/com/redhat/rhn/domain/server/MinionServer.java +++ b/java/code/src/com/redhat/rhn/domain/server/MinionServer.java @@ -34,17 +34,35 @@ import java.util.Set; import java.util.stream.Collectors; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.OneToMany; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + /** * MinionServer */ +@Entity +@PrimaryKeyJoinColumn(name = "server_id") +@Table(name = "suseMinionInfo") public class MinionServer extends Server implements SaltConfigurable { - + @Column(name = "minion_id") private String minionId; + @Column(name = "kernel_live_version", length = 255) private String kernelLiveVersion; + @Column(name = "ssh_push_port") private Integer sshPushPort; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "minion", orphanRemoval = true) private Set accessTokens = new HashSet<>(); + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "minion", orphanRemoval = true) private Set pillars = new HashSet<>(); + @Column(name = "reboot_required_after", columnDefinition = "timestamp") private Date rebootRequiredAfter; + @Column(name = "os_family", length = 64) + private String osFamily; /** * Constructs a MinionServer instance. @@ -53,6 +71,26 @@ public MinionServer() { super(); } + /** + * Constructs a MinionServer instance for result map + * @param id id + * @param minionIdIn minionIdIn + * @param osFamilyIn osFamilyIn + * @param kernelLiveVersionIn kernelLiveVersionIn + * @param sshPushPortIn sshPushPortIn + * @param rebootRequiredAfterIn rebootRequiredAfterIn + */ + public MinionServer(Long id, String minionIdIn, String osFamilyIn, String kernelLiveVersionIn, + Integer sshPushPortIn, Date rebootRequiredAfterIn) { + super(); + this.setId(id); + this.setOsFamily(osFamilyIn); + this.minionId = minionIdIn; + this.kernelLiveVersion = kernelLiveVersionIn; + this.sshPushPort = sshPushPortIn; + this.rebootRequiredAfter = rebootRequiredAfterIn; + } + /** * Minimal constructor used to avoid loading all properties in SSM config channel subscription * @@ -78,6 +116,22 @@ public void setMinionId(String minionIdIn) { this.minionId = minionIdIn; } + /** + * @return the os family + */ + @Override + public String getOsFamily() { + return osFamily; + } + + /** + * @param osFamilyIn the os family id to set + */ + @Override + public void setOsFamily(String osFamilyIn) { + osFamily = osFamilyIn; + } + /** * Gets kernel live version. * @@ -255,7 +309,8 @@ public Set getAccessTokens() { */ @Deprecated public void setAccessTokens(Set accessTokensIn) { - this.accessTokens = accessTokensIn; + this.accessTokens.clear(); + this.accessTokens.addAll(accessTokensIn); } /** 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..6f516d062224 100644 --- a/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/MinionServerFactory.java @@ -27,19 +27,24 @@ 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 java.math.BigDecimal; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; 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.ColumnResult; +import javax.persistence.ConstructorResult; +import javax.persistence.NoResultException; +import javax.persistence.SqlResultSetMapping; +import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Join; @@ -51,21 +56,44 @@ * MinionFactory - the singleton class used to fetch and store * com.redhat.rhn.domain.server.MinionServer objects from the database. */ +@SqlResultSetMapping( + name = "findMinionServers", + classes = { + @ConstructorResult( + targetClass = MinionServer.class, + columns = { + @ColumnResult(name = "server_id", type = Long.class), + @ColumnResult(name = "minion_id", type = String.class), + @ColumnResult(name = "os_family", type = String.class), + @ColumnResult(name = "kernel_live_version", type = String.class), + @ColumnResult(name = "ssh_push_port", type = Integer.class), + @ColumnResult(name = "reboot_required_after", type = Date.class), + } + ) + } +) public class MinionServerFactory extends HibernateFactory { private static final Logger LOG = LogManager.getLogger(MinionServerFactory.class); /** * Lookup all Servers that belong to an org + * * @param orgId the org id to search for * @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(); + if (orgId == null) { + return List.of(); + } + + String sql = "SELECT DISTINCT * FROM suseMinionInfo WHERE org_id = :orgId"; + + TypedQuery query + = getSession().createNativeQuery(sql, MinionServer.class); + query.setParameter("orgId", orgId); + + return query.getResultList(); } /** @@ -91,10 +119,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()); + if (machineId == null) { + return Optional.empty(); + } + String sql = "SELECT * FROM suseMinionInfo WHERE machine_id = :machineId"; + + TypedQuery query + = getSession().createNativeQuery(sql, MinionServer.class); + query.setParameter("machineId", machineId); + + try { + // Attempt to get a single result + MinionServer result = query.getSingleResult(); + return Optional.ofNullable(result); + } + catch (NoResultException e) { + return Optional.empty(); // Return empty if no result is found + } } /** @@ -104,10 +145,13 @@ 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()); + MinionServer result + = getSession().createQuery(""" + SELECT m FROM MinionServer m WHERE m.minionId = :minionId + """, + MinionServer.class) + .setParameter("minionId", minionId).getSingleResult(); + return Optional.ofNullable(result); } /** @@ -115,25 +159,11 @@ public static Optional findByMinionId(String minionId) { * * @return a list of all minions */ - @SuppressWarnings("unchecked") public static List listMinions() { - return getSession().createCriteria(MinionServer.class) - .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) - .list(); - } - - /** - * Find all minion ids that belong to an organization. - * - * @param orgId the organization id - * @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(); + String sql = "SELECT DISTINCT * FROM suseMinionInfo"; + Query query + = getSession().createNativeQuery(sql, MinionServer.class); + return query.getResultList(); } /** @@ -168,10 +198,12 @@ 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(); + CriteriaBuilder cb = getSession().getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(MinionServer.class); + Root root = query.from(MinionServer.class); + Predicate predicate = cb.equal(root.get("minionId"), minionIds); + query.select(root).where(predicate).distinct(true); + return getSession().createQuery(query).getResultList(); } } @@ -180,11 +212,13 @@ 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(); + String sql = "SELECT ms.* FROM suseMinionInfo ms " + + "JOIN contact_method cm ON ms.contact_method_id = cm.id " + + "WHERE cm.label IN (:labels)"; + + return HibernateFactory.getSession().createNativeQuery(sql, MinionServer.class) + .setParameter("labels", Arrays.asList("ssh-push", "ssh-push-tunnel")) + .getResultList(); } /** @@ -231,13 +265,34 @@ public static List findQueuedMinionSummaries(Long actionId) { private static List findMinionSummariesInStatus(Long actionId, List allowedStatues) { Session session = HibernateFactory.getSession(); - Query query = session.createNamedQuery("Action.findMinionSummaries", MinionSummary.class) - .setParameter("id", actionId) - .setParameter("allowedStatues", allowedStatues); + if (allowedStatues == null || allowedStatues.isEmpty()) { + return Collections.emptyList(); // Return empty list if no statuses are provided + } + + // Get status IDs (assuming ActionStatus has getId method that returns the ID of the status) + List statusIds = allowedStatues.stream() + .map(ActionStatus::getId) // or toString() depending on how your enum is represented + .collect(Collectors.toList()); + + // Create the query with parameter placeholder for a list + Query query = session.createNativeQuery(""" + SELECT sa.server_id AS serverId, + s.id AS minionId, + s.digital_server_id AS digitalServerId, + s.machine_id AS machineId, + c.label AS contactMethodLabel, + s.os AS os + FROM rhnServerAction sa + JOIN rhnServer s ON sa.server_id = s.id + JOIN suseServerContactMethod c ON s.contact_method_id = c.id + WHERE sa.action_id = :id + AND sa.status IN (:allowedStatues) + """) + .setParameter("id", actionId) + .setParameterList("allowedStatues", statusIds); // Use setParameterList for collections return query.getResultList(); } - /** * Find all minions by their server ids. * diff --git a/java/code/src/com/redhat/rhn/domain/server/MinionSummary.java b/java/code/src/com/redhat/rhn/domain/server/MinionSummary.java index 24b7c8ffa1d2..8bb2dfa611e7 100644 --- a/java/code/src/com/redhat/rhn/domain/server/MinionSummary.java +++ b/java/code/src/com/redhat/rhn/domain/server/MinionSummary.java @@ -20,9 +20,32 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.persistence.ColumnResult; +import javax.persistence.ConstructorResult; +import javax.persistence.SqlResultSetMapping; + + /** * This class represents a summary of a minion. */ +@SqlResultSetMapping( + name = "findMinionSummaries", + classes = { + @ConstructorResult( + targetClass = com.redhat.rhn.domain.server.MinionSummary.class, + columns = { + @ColumnResult(name = "serverId", type = Long.class), + @ColumnResult(name = "minionId", type = String.class), + @ColumnResult(name = "digitalServerId"), + @ColumnResult(name = "machineId"), + @ColumnResult(name = "contactMethodLabel"), + @ColumnResult(name = "os") + } + ) + } +) + public class MinionSummary { private final Long serverId; @@ -31,33 +54,28 @@ public class MinionSummary { private final String machineId; private final String os; private final String contactMethodLabel; - private final boolean transactionalUpdate; /** - * Convenience constructor from a MinionServer instance. + * Default constructor. * - * @param minion the minion */ - public MinionSummary(MinionServer minion) { - this(minion.getId(), minion.getMinionId(), minion.getDigitalServerId(), - minion.getMachineId(), minion.getContactMethodLabel().orElse(null), minion.getOs(), - minion.doesOsSupportsTransactionalUpdate()); + public MinionSummary() { + this.serverId = null; + this.minionId = null; + this.digitalServerId = null; + this.machineId = null; + this.contactMethodLabel = null; + this.os = null; } /** - * Standard constructor. + * Convenience constructor from a MinionServer instance. * - * @param serverIdIn the server id - * @param minionIdIn the minion id - * @param digitalServerIdIn the digital server id - * @param machineIdIn the machine id - * @param contactMethodLabelIn the contact method label - * @param osIn the minion os + * @param minion the minion */ - public MinionSummary(Long serverIdIn, String minionIdIn, String digitalServerIdIn, String machineIdIn, - String contactMethodLabelIn, String osIn) { - this(serverIdIn, minionIdIn, digitalServerIdIn, machineIdIn, contactMethodLabelIn, osIn, - ServerConstants.SLEMICRO.equals(osIn)); + public MinionSummary(MinionServer minion) { + this(minion.getId(), minion.getMinionId(), minion.getDigitalServerId(), + minion.getMachineId(), minion.getContactMethodLabel().orElse(null), minion.getOs()); } /** @@ -69,25 +87,22 @@ public MinionSummary(Long serverIdIn, String minionIdIn, String digitalServerIdI * @param machineIdIn the machine id * @param contactMethodLabelIn the contact method label * @param osIn the minion os - * @param transactionalUpdateIn if minion supports transactional update - */ public MinionSummary(Long serverIdIn, String minionIdIn, String digitalServerIdIn, String machineIdIn, - String contactMethodLabelIn, String osIn, boolean transactionalUpdateIn) { + String contactMethodLabelIn, String osIn) { this.serverId = serverIdIn; this.minionId = minionIdIn; this.digitalServerId = digitalServerIdIn; this.machineId = machineIdIn; this.contactMethodLabel = contactMethodLabelIn; this.os = osIn; - this.transactionalUpdate = transactionalUpdateIn; } /** * @return true is minion is transactional update */ public boolean isTransactionalUpdate() { - return transactionalUpdate; + return ServerConstants.SLEMICRO.equals(this.os); } diff --git a/java/code/src/com/redhat/rhn/domain/server/NetworkInterface.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/NetworkInterface.hbm.xml index 0194591c68be..7aaeff82bc53 100644 --- a/java/code/src/com/redhat/rhn/domain/server/NetworkInterface.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/NetworkInterface.hbm.xml @@ -3,24 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - - - - - - - - - - sa4 = null; + + @Transient private ArrayList sa6 = null; private static final String IPV6_REGEX = "^(((?=(?>.*?::)(?!.*::)))(::)?" + "([0-9A-F]{1,4}::?){0,5}|([0-9A-F]{1,4}:){6})(\\2([0-9A-F]{1,4}(::?|$)){0,2}" + "|((25[0-5]|(2[0-4]|1\\d|[1-9])?\\d)(\\.|$)){4}|[0-9A-F]{1,4}:[0-9A-F]{1,4})" + "(? listPinnedSubscriptions() { - return getSession().createCriteria(PinnedSubscription.class).list(); + String sql = "SELECT * FROM susePinnedSubscription"; + + TypedQuery query + = getSession().createNativeQuery(sql, PinnedSubscription.class); + return query.getResultList(); } /** @@ -96,7 +104,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) .executeUpdate(); } @@ -106,10 +114,10 @@ public void cleanStalePins() { * @return PinnedSubscription object */ public PinnedSubscription lookupById(Long id) { + String sql = "SELECT * FROM susePinnedSubscription WHERE id = :id"; return (PinnedSubscription) getSession() - .createCriteria(PinnedSubscription.class) - .add(Restrictions.eq("id", id)) - .uniqueResult(); + .createNativeQuery(sql, PinnedSubscription.class).setParameter("id", id) + .getSingleResult(); } /** @@ -120,10 +128,17 @@ public PinnedSubscription lookupById(Long id) { */ public PinnedSubscription lookupBySystemIdAndSubscriptionId(Long systemId, Long subscriptionId) { - return (PinnedSubscription) getSession() - .createCriteria(PinnedSubscription.class) - .add(Restrictions.eq("systemId", systemId)) - .add(Restrictions.eq("subscriptionId", subscriptionId)) - .uniqueResult(); + + CriteriaBuilder cb = getSession().getCriteriaBuilder(); + + CriteriaQuery query = cb.createQuery(PinnedSubscription.class); + + Root root = query.from(PinnedSubscription.class); + + Predicate predicate = cb.equal(root.get("systemId"), systemId); + predicate = cb.and(predicate, cb.equal(root.get("subscriptionId"), subscriptionId)); + + query.select(root).where(predicate); + return getSession().createQuery(query).uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/domain/server/Server.java b/java/code/src/com/redhat/rhn/domain/server/Server.java index d8bcb0e0dd4d..349d2866c58f 100644 --- a/java/code/src/com/redhat/rhn/domain/server/Server.java +++ b/java/code/src/com/redhat/rhn/domain/server/Server.java @@ -33,9 +33,9 @@ import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.org.OrgFactory; import com.redhat.rhn.domain.product.SUSEProductSet; -import com.redhat.rhn.domain.rhnpackage.PackageEvr; import com.redhat.rhn.domain.rhnpackage.PackageType; import com.redhat.rhn.domain.user.User; +import com.redhat.rhn.domain.user.legacy.UserImpl; import com.redhat.rhn.manager.configuration.ConfigurationManager; import com.redhat.rhn.manager.entitlement.EntitlementManager; import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper; @@ -47,14 +47,15 @@ import com.suse.utils.Opt; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.cobbler.CobblerConnection; import org.cobbler.SystemRecord; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.Where; +import org.hibernate.annotations.WhereJoinTable; import java.net.IDN; import java.sql.Timestamp; @@ -75,80 +76,244 @@ import java.util.stream.IntStream; import java.util.stream.Stream; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.OrderColumn; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Transient; + /** * Server - Class representation of the table rhnServer. */ +@Entity +@Table(name = "rhnServer") +@Inheritance(strategy = InheritanceType.JOINED) // Parent class inheritance strategy public class Server extends BaseDomainHelper implements Identifiable { /** * Logger for this class */ + @Transient private static Logger log = LogManager.getLogger(Server.class); - private Boolean ignoreEntitlementsForMigration; - + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_server_id_seq") + @SequenceGenerator(name = "rhn_server_id_seq", sequenceName = "rhn_server_id_seq", allocationSize = 1) + @Column(name = "id") private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "org_id") private Org org; + + @Column(name = "digital_server_id", length = 1024) private String digitalServerId; + + @Column(name = "os", length = 64) private String os; + + @Transient private String osFamily; + + @Column(name = "release", length = 64) private String release; + + @Column(name = "name", length = 128) private String name; + + @Column(name = "description", length = 256) private String description; + + @Column(name = "info", length = 128) private String info; + + @Column(name = "secret", length = 64) private String secret; + + @ManyToOne(targetEntity = UserImpl.class, fetch = FetchType.LAZY) + @JoinColumn(name = "creator_id") private User creator; + + @Column(name = "auto_update", length = 1) private String autoUpdate; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "contact_method_id") private ContactMethod contactMethod; + + @Column(name = "running_kernel", length = 64) private String runningKernel; + + @Column(name = "last_boot") private Long lastBoot; - private ServerArch serverArch; - private ProvisionState provisionState; + + @Column(name = "channels_changed") private Date channelsChanged; - private Date created; + + @Column(name = "cobbler_id", length = 64) private String cobblerId; - private Set devices; + + @Column(name = "machine_id", length = 256) + private String machineId; + + @Column(name = "hostname", length = 128) + private String hostname; + + @Column(name = "payg") + @Type(type = "yes_no") + private Boolean payg = false; + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set notes = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set devices = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set networkInterfaces = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set customDataValues = new HashSet<>(); + + @ManyToMany + @JoinTable(name = "rhnServerChannel", + joinColumns = @JoinColumn(name = "server_id"), + inverseJoinColumns = @JoinColumn(name = "channel_id")) + private Set channels = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set fqdns = new HashSet<>(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "server_arch_id") + private ServerArch serverArch; + + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "provision_state_id") + private ProvisionState provisionState; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private ServerInfo serverInfo; + + @OneToMany(mappedBy = "id.server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) private Set serverPaths = new HashSet<>(); + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private CPU cpu; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private ServerLock lock; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private ServerUuid serverUuid; - private Set notes; - private Set fqdns; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private ProxyInfo proxyInfo; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private MgrServerInfo mgrServerInfo; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private PushClient pushClient; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Ram ram; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Dmi dmi; - private NetworkInterface primaryInterface; - private Set networkInterfaces; - private Set customDataValues; - private Set channels = new HashSet<>(); - private List configChannels = new ArrayList<>(); - private Set localChannels = new HashSet<>(); + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Location serverLocation; + + @OneToOne(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private ServerCoCoAttestationConfig cocoAttestationConfig; - private Set cocoAttestationReports; + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set cocoAttestationReports = new HashSet<>(); + + @OneToMany(mappedBy = "hostSystem", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set guests = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set history = new HashSet<>(); + + @OneToMany(mappedBy = "server", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private Set packages = new HashSet<>(); + + @ManyToMany + @JoinTable(name = "suseServerInstalledProduct", + joinColumns = @JoinColumn(name = "rhn_server_id"), + inverseJoinColumns = @JoinColumn(name = "suse_installed_product_id")) + private Set installedProducts = new HashSet<>(); + + @ManyToMany + @JoinTable(name = "suseServerAppstream", + joinColumns = @JoinColumn(name = "id"), + inverseJoinColumns = @JoinColumn(name = "server_id")) + private Set appStreams = new HashSet<>(); + + @Transient + private Boolean ignoreEntitlementsForMigration; + @Transient + private NetworkInterface primaryInterface; + @ManyToMany + @JoinTable( + name = "rhnServerConfigChannel", + joinColumns = @JoinColumn(name = "server_id"), + inverseJoinColumns = @JoinColumn(name = "config_channel_id")) + @WhereJoinTable(clause = "position > 0") + private List configChannelsHibernate = new ArrayList<>(); + + @ManyToMany + @JoinTable( + name = "rhnServerConfigChannel", + joinColumns = @JoinColumn(name = "server_id"), + inverseJoinColumns = @JoinColumn(name = "config_channel_id")) + @WhereJoinTable(clause = "position IS NULL") + private Set localChannels = new HashSet<>(); + @Transient private VirtualInstance virtualInstance; - private PushClient pushClient; + @Transient private final ConfigChannelListProcessor configListProc = new ConfigChannelListProcessor(); - private Set history = new HashSet<>(); - private Set packages = new HashSet<>(); - private ProxyInfo proxyInfo; - private MgrServerInfo mgrServerInfo; + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable( + name = "rhnServerGroupMembers", + joinColumns = @JoinColumn(name = "server_id"), + inverseJoinColumns = @JoinColumn(name = "server_group_id") + ) private Set groups = new HashSet<>(); + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @JoinColumn(name = "server_id") // Foreign key column private Set capabilities = new HashSet<>(); - private Set installedProducts = new HashSet<>(); - private String machineId; - private String hostname; - private boolean payg; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "maintenance_schedule_id") private MaintenanceSchedule maintenanceSchedule; + + @Transient private Boolean hasConfigFeature; - private Set appStreams = new HashSet<>(); + @Column(name = "cpe", length = 64) private String cpe; + @Column(name = "valid_cnames") public static final String VALID_CNAMES = "valid_cnames_"; - /** * @return Returns the capabilities. */ @@ -339,8 +504,8 @@ public void setSandboxOverride(ConfigChannel ch) { */ protected void setConfigChannelsHibernate( List configChannelsIn) { - configChannels = configChannelsIn; - configChannels.removeIf(Objects::isNull); + configChannelsHibernate = configChannelsIn; + configChannelsHibernate.removeIf(Objects::isNull); } /** @@ -349,12 +514,12 @@ protected void setConfigChannelsHibernate( * @return List of config channels */ protected List getConfigChannelsHibernate() { - return configChannels; + return configChannelsHibernate; } protected List getConfigChannels() { ensureConfigManageable(); - return configChannels; + return configChannelsHibernate; } /** @@ -373,7 +538,7 @@ protected List getConfigChannels() { * @return A stream of the ServerConfigChannels mappings */ public Stream getConfigChannelStream() { - return getConfigChannels().stream(); + return getConfigChannelsHibernate().stream(); } /** @@ -392,7 +557,7 @@ public Stream getConfigChannelStream() { * @return A list of the ServerConfigChannels mappings */ public List getConfigChannelList() { - return new ArrayList<>(getConfigChannels()); + return new ArrayList<>(getConfigChannelsHibernate()); } /** @@ -400,7 +565,7 @@ public List getConfigChannelList() { * the server. */ public int getConfigChannelCount() { - return getConfigChannels().size(); + return getConfigChannelsHibernate().size(); } public void setHasConfigFeature(Boolean hasConfig) { @@ -460,7 +625,7 @@ public final void unsubscribeConfigChannel(ConfigChannel configChannel, User use * @param user The user doing the action */ public void unsubscribeConfigChannels(List configChannelList, User user) { - configChannelList.forEach(cc -> configListProc.remove(getConfigChannels(), cc)); + configChannelList.forEach(cc -> configListProc.remove(getConfigChannelsHibernate(), cc)); } /** @@ -469,7 +634,7 @@ public void unsubscribeConfigChannels(List configChannelList, Use * @param user The user doing the action */ public void setConfigChannels(List configChannelList, User user) { - configListProc.replace(getConfigChannels(), configChannelList); + configListProc.replace(getConfigChannelsHibernate(), configChannelList); } /** @@ -480,10 +645,10 @@ public void storeConfigChannels() { .setParameter("sid", getId()) .executeUpdate(); - if (!configChannels.isEmpty()) { - String values = IntStream.range(0, configChannels.size()) + if (!configChannelsHibernate.isEmpty()) { + String values = IntStream.range(0, configChannelsHibernate.size()) .boxed() - .map(i -> String.format("(%s, %s, %s)", getId(), configChannels.get(i).getId(), i + 1)) + .map(i -> String.format("(%s, %s, %s)", getId(), configChannelsHibernate.get(i).getId(), i + 1)) .collect(Collectors.joining(",")); @@ -1768,33 +1933,15 @@ void setVirtualInstance(VirtualInstance instance) { * {@inheritDoc} */ @Override - public boolean equals(final Object other) { - if (!(other instanceof Server castOther)) { + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { return false; } - - Optional proxyVersion = - Optional.ofNullable(proxyInfo).map(ProxyInfo::getVersion); - Optional otherProxyVersion = - Optional.ofNullable(castOther.getProxyInfo()).map(ProxyInfo::getVersion); - Optional mgrVersion = - Optional.ofNullable(mgrServerInfo).map(MgrServerInfo::getVersion); - Optional otherMgrVersion = - Optional.ofNullable(castOther.getMgrServerInfo()).map(MgrServerInfo::getVersion); - - return new EqualsBuilder().append(os, castOther.getOs()) - .append(release, castOther.getRelease()) - .append(name, castOther.getName()) - .append(description, castOther.getDescription()) - .append(info, castOther.getInfo()) - .append(secret, castOther.getSecret()) - .append(autoUpdate, castOther.getAutoUpdate()) - .append(runningKernel, castOther.getRunningKernel()) - .append(lastBoot, castOther.getLastBoot()) - .append(channelsChanged, castOther.getChannelsChanged()) - .append(proxyVersion, otherProxyVersion) - .append(mgrVersion, otherMgrVersion) - .isEquals(); + Server server = (Server) o; + return Objects.equals(id, server.id); } /** @@ -1802,18 +1949,7 @@ public boolean equals(final Object other) { */ @Override public int hashCode() { - Optional proxyVersion = - Optional.ofNullable(getProxyInfo()).map(ProxyInfo::getVersion); - Optional mgrVersion = - Optional.ofNullable(getMgrServerInfo()).map(MgrServerInfo::getVersion); - return new HashCodeBuilder().append(id).append(digitalServerId).append(os) - .append(release).append(name).append(description) - .append(info).append(secret) - .append(autoUpdate).append(runningKernel) - .append(lastBoot).append(channelsChanged) - .append(proxyVersion) - .append(mgrVersion) - .toHashCode(); + return Objects.hash(id); } /** @@ -1826,22 +1962,6 @@ public String toString() { "description", description).toString(); } - /** - * @return Returns the created. - */ - @Override - public Date getCreated() { - return created; - } - - /** - * @param createdIn The created to set. - */ - @Override - public void setCreated(Date createdIn) { - this.created = createdIn; - } - /** * @return Returns the lock. */ 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..453e9ca63429 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java @@ -54,13 +54,7 @@ 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.StandardBasicTypes; @@ -79,6 +73,7 @@ import java.util.stream.Stream; import javax.persistence.Tuple; +import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.JoinType; @@ -202,53 +197,45 @@ public static List lookupStorageDevicesByServer(Server s) { @SuppressWarnings("unchecked") public static Optional lookupProxyServer(String name) { boolean nameIsFullyQualified = name.contains("."); - if (!nameIsFullyQualified) { - log.warn("Specified master name \"{}\" is not fully-qualified,proxy attachment might not be correct", 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); + Optional result = Optional.empty(); + 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(); - + String sql + = "SELECT * FROM rhnServer WHERE hostname = :hostname AND id IN (SELECT server_id FROM rhnProxyInfo)"; + Query query + = HibernateFactory.getSession().createNativeQuery(sql, Server.class); + query.setParameter("hostname", name); + List servers = query.getResultList(); + result = servers.stream().findFirst(); if (result.isPresent()) { return result; } - // precise search did not work, try imprecise 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(); + String strippedHostname = name.split("\\.")[0]; + sql = "SELECT * FROM rhnServer WHERE hostname = :hostname AND id IN" + + "(SELECT server_id FROM rhnProxyInfo)"; + query = HibernateFactory.getSession().createNativeQuery(sql, Server.class); + query.setParameter("hostname", strippedHostname); + servers = query.getResultList(); + result = servers.stream().findFirst(); + if (result.isPresent()) { + return result; + } } else { - return HibernateFactory.getSession() - .createCriteria(Server.class) - .add(Subqueries.propertyIn("id", proxyIds)) - .add(Restrictions.like("hostname", name + ".", MatchMode.START)) - .list() - .stream() - .findFirst(); + sql = "SELECT * FROM rhnServer WHERE hostname LIKE :hostnamePattern AND " + + "id IN (SELECT server_id FROM rhnProxyInfo)"; + query = HibernateFactory.getSession().createNativeQuery(sql, Server.class); + query.setParameter("hostnamePattern", name + "%"); + servers = query.getResultList(); + result = servers.stream().findFirst(); } + return result; } /** @@ -393,28 +380,52 @@ public static void addServersToGroup(Collection servers, ServerGroup ser } private static boolean insertServersToGroup(List serverIds, Long sgid) { - WriteMode m = ModeFactory.getWriteMode(SYSTEM_QUERIES, "add_servers_to_server_group"); - - Map params = new HashMap<>(); - params.put("sgid", sgid); - - int insertsCount = m.executeUpdate(params, serverIds); - - if (insertsCount > 0) { - updateCurrentMembersOfServerGroup(sgid, insertsCount); - return true; - } - return false; + String sql = """ + INSERT INTO rhnServerGroupMembers (server_id, server_group_id) + SELECT S.id AS server_id, :sgid + FROM rhnServerGroup SG + JOIN rhnServer S ON S.org_id = SG.org_id + WHERE S.id IN (:serverIds) + AND SG.id = :sgid + AND NOT EXISTS ( + SELECT 1 + FROM rhnServerGroupMembers SGM + WHERE SGM.server_id = S.id + AND SGM.server_group_id = SG.id + ) + ON CONFLICT (server_id, server_group_id) DO NOTHING + """; + + // Create a native query + Query query = HibernateFactory.getSession().createNativeQuery(sql, ServerGroup.class); + + // Set parameters for the query + query.setParameter("sgid", sgid); + query.setParameter("serverIds", serverIds); + + // Execute the update + int insertsCount = query.executeUpdate(); + + if (insertsCount > 0) { + // Update the current members if there were inserts + updateCurrentMembersOfServerGroup(HibernateFactory.getSession(), sgid, insertsCount); + return true; + } + return false; } - private static void updateCurrentMembersOfServerGroup(Long sgid, int membersCount) { - WriteMode mode = ModeFactory.getWriteMode(SYSTEM_QUERIES, "update_current_members_of_server_group"); + private static void updateCurrentMembersOfServerGroup(Session session, Long sgid, int membersCount) { + // Native query to update the current members count + String updateSql = """ + UPDATE rhnServerGroup + SET current_members = :members_count + WHERE id = :sgid + """; - Map params = new HashMap<>(); - params.put("sgid", sgid); - params.put("members_count", membersCount); - - mode.executeUpdate(params); + Query updateQuery = session.createNativeQuery(updateSql, Object.class); + updateQuery.setParameter("sgid", sgid); + updateQuery.setParameter("members_count", membersCount); + updateQuery.executeUpdate(); } private static void updatePermissionsForServerGroup(Long sgid) { @@ -487,7 +498,7 @@ private static boolean removeServersFromGroup(List serverIds, Long sgid) { int removesCount = m.executeUpdate(params, serverIds); if (removesCount > 0) { - updateCurrentMembersOfServerGroup(sgid, -removesCount); + updateCurrentMembersOfServerGroup(HibernateFactory.getSession(), sgid, -removesCount); return true; } return false; @@ -756,9 +767,11 @@ 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()) { + String sql = "SELECT * FROM Server WHERE rhnServer = :id"; + List servers = getSession().createNativeQuery(sql, Server.class) + .setParameter("id", id).getResultList(); + + for (Server server : servers) { if (server.hasEntitlement(EntitlementManager.getByName("foreign_entitled"))) { return server; } @@ -793,7 +806,7 @@ public static List lookupByServerIds(List ids, Strin */ public static ServerGroupType lookupServerGroupTypeByLabel(String label) { return (ServerGroupType) HibernateFactory.getSession().getNamedQuery("ServerGroupType.findByLabel") - .setString("label", label) + .setParameter("label", label) // Retrieve from cache if there .setCacheable(true).uniqueResult(); @@ -897,7 +910,7 @@ 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) + .setParameter("label", label) // Retrieve from cache if there .setCacheable(true).uniqueResult(); } @@ -923,7 +936,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) + .setParameter("name", name) // Retrieve from cache if there .setCacheable(true).uniqueResult(); } @@ -1299,7 +1312,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) // Do not use setCacheable(true), as tag deletion will // usually end up making this query's output out of date .uniqueResult(); @@ -1311,7 +1324,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) // Do not use setCacheable(true), as tag deletion will // usually end up making this query's output out of date .uniqueResult(); @@ -1340,10 +1353,17 @@ 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(); + String sql = "SELECT * FROM suseServerContactMethod WHERE label = :label"; + TypedQuery query + = getSession().createNativeQuery(sql, ContactMethod.class); + query.setParameter("label", label); + + // Execute the query and get the result + List results = query.getResultList(); + if (!results.isEmpty()) { + return results.get(0); // Get the first result if available + } + return null; } /** @@ -1499,10 +1519,10 @@ 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()); + String jpql = "SELECT s FROM rhnServer s WHERE s.machineId = :machineId"; + TypedQuery query = getSession().createQuery(jpql, Server.class); + query.setParameter("machineId", machineId); + return Optional.ofNullable(query.getResultStream().findFirst().orElse(null)); } /** @@ -1511,9 +1531,12 @@ public static Optional findByMachineId(String machineId) { * @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()); + String sql = "SELECT * FROM Capability WHERE name = :name"; + Capability capability + = (Capability) getSession().createNativeQuery(sql, Capability.class) + .setParameter("name", name).uniqueResult(); + return Optional.ofNullable(capability); + } /** diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerGroup.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/ServerGroup.hbm.xml index ef52cda01695..9406730ba24f 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerGroup.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/ServerGroup.hbm.xml @@ -3,43 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - rhn_server_group_id_seq - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -168,21 +131,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ]]> - - - - - pillars = new HashSet<>(); + @Transient + private Set pillars = new HashSet<>(); /** * Getter for id * @return Long to get @@ -110,6 +142,10 @@ public void setOrg(Org orgIn) { this.org = orgIn; } + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_type", insertable = false, updatable = false) + private ServerGroupType groupType; + /** * @return Returns the groupType. */ diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerGroupFactory.java b/java/code/src/com/redhat/rhn/domain/server/ServerGroupFactory.java index baea70c6b10e..c4f617690c47 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerGroupFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerGroupFactory.java @@ -35,6 +35,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Session; +import org.hibernate.query.Query; import java.math.BigDecimal; import java.util.List; @@ -81,12 +82,24 @@ public static List listAdministeredServerGroups(User user) { public static Optional findCompatibleServerGroupForBaseEntitlement( Long serverId, Entitlement baseEnt) { Session session = HibernateFactory.getSession(); - ServerGroup serverGroup = (ServerGroup) session - .getNamedQuery("ServerGroup.findCompatibleServerGroupForBaseEntitlement") + return session.createNativeQuery(""" + SELECT SG.* + FROM rhnServerGroupType SGT + JOIN rhnServerGroup SG ON (SG.group_type = SGT.id) + JOIN rhnServer S ON (S.org_id = SG.org_id) + JOIN rhnServerServerGroupArchCompat SSGAC ON + (SSGAC.server_arch_id = S.server_arch_id AND SSGAC.server_group_type = SGT.id) + WHERE S.id = :sid + AND SGT.label = :entitlement_label + AND NOT EXISTS (SELECT 1 + FROM rhnServerGroupMembers SGM + WHERE SGM.server_group_id = SG.id + AND SGM.server_id = S.id) + """, ServerGroup.class) + .addSynchronizedEntityClass(ServerGroup.class) .setParameter("sid", serverId) - .setParameter("entitlement_label", baseEnt.getLabel()).uniqueResult(); - - return Optional.ofNullable(serverGroup); + .setParameter("entitlement_label", baseEnt.getLabel()) + .uniqueResultOptional(); } /** @@ -100,11 +113,27 @@ public static Optional findCompatibleServerGroupForBaseEntitlement( public static Optional findCompatibleServerGroupForAddonEntitlement( Long serverId, Entitlement addOnEnt, Long baseEntId) { Session session = HibernateFactory.getSession(); - ServerGroup serverGroup = (ServerGroup) session - .getNamedQuery("ServerGroup.findCompatibleServerGroupForAddOnEntitlement") - .setParameter("sid", serverId) + Query query = session + .createNativeQuery(""" + SELECT SG.* + FROM rhnServerGroupType SGT + JOIN rhnServerGroup SG ON SG.group_type = SGT.id + JOIN rhnServer S ON S.org_id = SG.org_id + JOIN rhnSGTypeBaseAddonCompat SGTBAC ON SGTBAC.addon_id = SGT.id + WHERE S.id = :sid + AND SGT.label = :addon_entitlement_label + AND SGTBAC.base_id = :base_ent_id + AND NOT EXISTS ( + SELECT 1 + FROM rhnServerGroupMembers SGM + WHERE SGM.server_group_id = SG.id + AND SGM.server_id = S.id) + """, + ServerGroup.class).setParameter("sid", serverId) .setParameter("addon_entitlement_label", addOnEnt.getLabel()) - .setParameter("base_ent_id", baseEntId).uniqueResult(); + .setParameter("base_ent_id", baseEntId); + + ServerGroup serverGroup = query.uniqueResult(); if (serverGroup != null) { return Optional.of(serverGroup); diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.hbm.xml index b3a51e20f30b..5127e7b7cad5 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.hbm.xml @@ -3,34 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - - protected - - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.java b/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.java index 824a508d01af..d94e921b5285 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerGroupType.java @@ -21,50 +21,115 @@ import java.util.HashSet; import java.util.Set; +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + /** * Class that represents the rhnServerGroupType table. - * */ +@Entity +@Table(name = "rhnServerGroupType") +@Cacheable +@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY) public class ServerGroupType extends AbstractLabelNameHelper { - private char permanent; - private char isBaseChar; - private Set features = new HashSet<>(); - /** - * @return Returns the isBase. - */ - public char getIsBaseChar() { - return isBaseChar; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "label") + private String label; + + @Column(name = "name") + private String name; + + @Column(name = "permanent", insertable = false, updatable = false) + private Character permanent; + + @Column(name = "is_base", insertable = false, updatable = false) + private Character isBaseChar; + + @Column(name = "created", insertable = false, updatable = false) + private java.sql.Timestamp created; + + @Column(name = "modified", insertable = false, updatable = false) + private java.sql.Timestamp modified; + + @ManyToMany + @JoinTable( + name = "rhnServerGroupTypeFeature", + joinColumns = @JoinColumn(name = "server_group_type_id"), + inverseJoinColumns = @JoinColumn(name = "feature_id") + ) + private Set features = new HashSet<>(); // Initialize as an empty set + + // Getters and Setters + + public Long getId() { + return id; } - /** - * @param isBaseCharIn The isBase to set. - */ - public void setIsBaseChar(char isBaseCharIn) { - this.isBaseChar = isBaseCharIn; + + public void setId(Long idIn) { + this.id = idIn; } - /** - * @return true if this server group type is a base type, false otherwise - */ - public boolean isBase() { - return getIsBaseChar() == 'Y'; + public String getLabel() { + return label; } - /** - * @return Returns the permanent. - */ - public char getPermanent() { + + public void setLabel(String labelIn) { + this.label = labelIn; + } + + public String getName() { + return name; + } + + public void setName(String nameIn) { + this.name = nameIn; + } + + public Character getPermanent() { return permanent; } - /** - * @param permanentIn The permanent to set. - */ - public void setPermanent(char permanentIn) { + + public void setPermanent(Character permanentIn) { this.permanent = permanentIn; } - /** - * @return Returns the features. - */ + public Character getIsBaseChar() { + return isBaseChar; + } + + public void setIsBaseChar(Character isBaseCharIn) { + this.isBaseChar = isBaseCharIn; + } + + public java.sql.Timestamp getCreated() { + return created; + } + + public void setCreated(java.sql.Timestamp createdIn) { + this.created = createdIn; + } + + public java.sql.Timestamp getModified() { + return modified; + } + + public void setModified(java.sql.Timestamp modifiedIn) { + this.modified = modifiedIn; + } + public Set getFeatures() { return features; } @@ -73,7 +138,11 @@ public Set getFeatures() { * @param featuresIn The features to set. */ public void setFeatures(Set featuresIn) { - features = featuresIn; + this.features = featuresIn; + } + + public boolean isBase() { + return getIsBaseChar() != null && getIsBaseChar() == 'Y'; } /** diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerPath.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/ServerPath.hbm.xml deleted file mode 100644 index 822b3d62e6b5..000000000000 --- a/java/code/src/com/redhat/rhn/domain/server/ServerPath.hbm.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerPath.java b/java/code/src/com/redhat/rhn/domain/server/ServerPath.java index 68f54736b3e6..7aee53aeb12a 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerPath.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerPath.java @@ -20,18 +20,31 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + /** * POJO for a rhnServerPath row. */ -public class ServerPath extends BaseDomainHelper { +@Entity +@Table(name = "rhnServerPath") +public class ServerPath extends BaseDomainHelper implements Serializable { + + private static final long serialVersionUID = 1L; - /** The id. */ + // Embedded composite key + @EmbeddedId private ServerPathId id; - /** The position. */ + // Regular properties + @Column(name = "position") private Long position; - /** The hostname. */ + @Column(name = "hostname") private String hostname; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerPathId.java b/java/code/src/com/redhat/rhn/domain/server/ServerPathId.java index 16d1a41613ee..be3d1ef12faf 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerPathId.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerPathId.java @@ -20,15 +20,25 @@ import java.io.Serializable; + +import javax.persistence.Embeddable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + /** * Composite id for {@link ServerPath}. */ +@Embeddable public class ServerPathId implements Serializable { - /** The server. */ + private static final long serialVersionUID = 1L; + + @ManyToOne + @JoinColumn(name = "server_id") private Server server; - /** The proxy server. */ + @ManyToOne + @JoinColumn(name = "proxy_server_id") private Server proxyServer; /** diff --git a/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml index 977545c6b6a0..3fef322f67f6 100644 --- a/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml @@ -3,216 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - rhn_server_id_seq - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/server/VirtualInstance.java b/java/code/src/com/redhat/rhn/domain/server/VirtualInstance.java index b2c454c53f19..9935f1d51e17 100644 --- a/java/code/src/com/redhat/rhn/domain/server/VirtualInstance.java +++ b/java/code/src/com/redhat/rhn/domain/server/VirtualInstance.java @@ -20,6 +20,8 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; +import java.io.Serializable; + /** * VirtualInstance represents a virtual guest system. When the guest is * registered, there is an associated {@link Server} that contains additional @@ -30,7 +32,7 @@ * being implemented in the RHN 500 release. * */ -public class VirtualInstance extends BaseDomainHelper { +public class VirtualInstance extends BaseDomainHelper implements Serializable { private static final VirtualInstanceInfo NULL_INFO = new VirtualInstanceInfo(); 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..2a2a0ad73c0b 100644 --- a/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/VirtualInstanceFactory.java @@ -251,7 +251,7 @@ public Set findGuestsWithoutAHostByOrg(Org org) { */ public VirtualInstanceType getParaVirtType() { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", "para_virtualized") + "VirtualInstanceType.findByLabel").setParameter("label", "para_virtualized") .setCacheable(true).uniqueResult(); } @@ -262,7 +262,7 @@ public VirtualInstanceType getParaVirtType() { */ public VirtualInstanceType getFullyVirtType() { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", "fully_virtualized") + "VirtualInstanceType.findByLabel").setParameter("label", "fully_virtualized") .setCacheable(true).uniqueResult(); } @@ -274,7 +274,7 @@ public VirtualInstanceType getFullyVirtType() { */ public VirtualInstanceType getVirtualInstanceType(String label) { return (VirtualInstanceType)getSession().getNamedQuery( - "VirtualInstanceType.findByLabel").setString("label", label) + "VirtualInstanceType.findByLabel").setParameter("label", label) .setCacheable(true).uniqueResult(); } @@ -285,7 +285,7 @@ public VirtualInstanceType getVirtualInstanceType(String label) { */ public VirtualInstanceState getRunningState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "running") + "VirtualInstanceState.findByLabel").setParameter("label", "running") .uniqueResult(); } @@ -296,7 +296,7 @@ public VirtualInstanceState getRunningState() { */ public VirtualInstanceState getStoppedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "stopped") + "VirtualInstanceState.findByLabel").setParameter("label", "stopped") .uniqueResult(); } @@ -307,7 +307,7 @@ public VirtualInstanceState getStoppedState() { */ public VirtualInstanceState getPausedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "paused") + "VirtualInstanceState.findByLabel").setParameter("label", "paused") .uniqueResult(); } @@ -318,7 +318,7 @@ public VirtualInstanceState getPausedState() { */ public VirtualInstanceState getCrashedState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "crashed") + "VirtualInstanceState.findByLabel").setParameter("label", "crashed") .uniqueResult(); } @@ -329,7 +329,7 @@ public VirtualInstanceState getCrashedState() { */ public VirtualInstanceState getUnknownState() { return (VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", "unknown") + "VirtualInstanceState.findByLabel").setParameter("label", "unknown") .uniqueResult(); } @@ -341,7 +341,7 @@ public VirtualInstanceState getUnknownState() { */ public Optional getState(String label) { return Optional.ofNullable((VirtualInstanceState)getSession().getNamedQuery( - "VirtualInstanceState.findByLabel").setString("label", label) + "VirtualInstanceState.findByLabel").setParameter("label", label) .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..b53263cd14df 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 @@ -57,7 +57,7 @@ public void testLocation() throws Exception { Session session = HibernateFactory.getSession(); loc2 = (Location) session.getNamedQuery("Location.findById") - .setLong("id", loc1.getId()) + .setParameter("id", loc1.getId()) .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..26bab402048c 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 @@ -50,7 +50,7 @@ public void testEquals() throws Exception { Session session = HibernateFactory.getSession(); note2 = (Note) session.getNamedQuery("Note.findById") - .setLong("id", note1.getId()) + .setParameter("id", note1.getId()) .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 0697f7e94c40..7ad19d618da0 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 @@ -633,11 +633,6 @@ private static Server createTestServer(User owner, boolean ensureOwnerAccess, SYSTEM_ENTITLEMENT_MANAGER.addEntitlementToServer(newS, mgmt.getGroupType().getAssociatedEntitlement()); } - - EntitlementServerGroup sg = ServerGroupTestUtils.createEntitled(owner.getOrg(), - type); - - SYSTEM_ENTITLEMENT_MANAGER.addEntitlementToServer(newS, sg.getGroupType().getAssociatedEntitlement()); return TestUtils.saveAndReload(newS); } @@ -707,8 +702,7 @@ public static Server createUnentitledTestServer(User owner, boolean ensureOwnerA } Long id = newS.getId(); - HibernateFactory.getSession().flush(); - HibernateFactory.getSession().evict(newS); + TestUtils.saveAndReload(newS); newS = ServerFactory.lookupByIdAndOrg(id, owner.getOrg()); assertNotNull(newS.getEntitledGroupTypes()); assertNotNull(newS.getManagedGroups()); diff --git a/java/code/src/com/redhat/rhn/domain/server/test/VirtualInstanceFactoryTest.java b/java/code/src/com/redhat/rhn/domain/server/test/VirtualInstanceFactoryTest.java index 0a495363ae87..79eaf92a55c9 100644 --- a/java/code/src/com/redhat/rhn/domain/server/test/VirtualInstanceFactoryTest.java +++ b/java/code/src/com/redhat/rhn/domain/server/test/VirtualInstanceFactoryTest.java @@ -43,7 +43,6 @@ import org.apache.commons.collections.CollectionUtils; import org.hibernate.Session; -import org.hibernate.criterion.Restrictions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -51,6 +50,12 @@ import java.util.List; import java.util.Set; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + + /** * VirtualInstanceFactoryTest */ @@ -297,12 +302,19 @@ public void testLookupGuestByUuid() throws Exception { @Test public void testLookupHostVirtualInstanceByHostId() throws Exception { - Server host = ServerTestUtils.createVirtHostWithGuest(systemEntitlementManager); + Server host = ServerTestUtils + .createVirtHostWithGuest(systemEntitlementManager); + CriteriaBuilder cb = HibernateFactory.getSession().getCriteriaBuilder(); + CriteriaQuery query + = cb.createQuery(VirtualInstance.class); + + Root root = query.from(VirtualInstance.class); + + Predicate predicate = cb.equal(root.get("hostSystem"), host); + predicate = cb.and(predicate, cb.equal(root.get("guestSystem"), null)); - VirtualInstance fromDb = (VirtualInstance) HibernateFactory.getSession() - .createCriteria(VirtualInstance.class) - .add(Restrictions.eq("hostSystem", host)) - .add(Restrictions.eq("guestSystem", null)) + query.select(root).where(predicate); + VirtualInstance fromDb = HibernateFactory.getSession().createQuery(query) .uniqueResult(); VirtualInstance hostVirtInstance = VirtualInstanceFactory.getInstance() 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..a57ff71c3491 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,18 @@ 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 java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.Set; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Subquery; + + /** * Factory class for working with states. */ @@ -193,14 +195,26 @@ public static Optional> latestConfigChannels(Org org) { 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(); + // Get the CriteriaBuilder + CriteriaBuilder cb = getSession().getCriteriaBuilder(); + + // Create the main query + CriteriaQuery query = cb.createQuery(revisionType); + Root root = query.from(revisionType); + + // Create a subquery to get the maximum ID + Subquery subquery = query.subquery(Long.class); + Root subRoot = subquery.from(revisionType); + subquery.select(cb.max(subRoot.get("id"))) + .where(cb.equal(subRoot.get(field), bean)); + + // Add the subquery result as a restriction in the main query + query.select(root).where(cb.equal(root.get(field), bean), + cb.equal(root.get("id"), subquery)); + + // Execute the query + T revision = getSession().createQuery(query).getSingleResult(); + return Optional.ofNullable(revision); } 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..d0f8f7c1e695 100644 --- a/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java +++ b/java/code/src/com/redhat/rhn/domain/token/ActivationKeyFactory.java @@ -60,7 +60,7 @@ public static ActivationKey lookupByKey(String key) { return (ActivationKey) HibernateFactory.getSession() .getNamedQuery("ActivationKey.findByKey") - .setString("key", key) + .setParameter("key", key) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/domain/token/Token.java b/java/code/src/com/redhat/rhn/domain/token/Token.java index b8cae1747d2c..06147cf9c29d 100644 --- a/java/code/src/com/redhat/rhn/domain/token/Token.java +++ b/java/code/src/com/redhat/rhn/domain/token/Token.java @@ -37,28 +37,97 @@ import java.util.Objects; import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * Token */ +@Entity +@Table(name = "rhnRegToken") public class Token implements Identifiable { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RHN_REG_TOKEN_SEQ") + @SequenceGenerator(name = "RHN_REG_TOKEN_SEQ", sequenceName = "RHN_REG_TOKEN_SEQ", allocationSize = 1) private Long id; + + @Column(name = "note", length = 2048) private String note; + + @Column(name = "disabled") private Long disabled; + + @Column(name = "deploy_configs") private boolean deployConfigs; + + @Column(name = "usage_limit") private Long usageLimit; + + @ManyToOne + @JoinColumn(name = "org_id") private Org org; + + @ManyToOne + @JoinColumn(name = "user_id") private User creator; + + @ManyToOne + @JoinColumn(name = "server_id") private Server server; + + @ManyToOne + @JoinColumn(name = "contact_method_id") private ContactMethod contactMethod; - private Set activatedSystems = new HashSet<>(); + + @OneToMany(mappedBy = "token") + private Set activatedServers = new HashSet<>(); + + @OneToMany(mappedBy = "token", fetch = FetchType.LAZY) private List configChannels = new LinkedList<>(); + + @ManyToMany + @JoinTable( + name = "rhnRegTokenEntitlement", + joinColumns = @JoinColumn(name = "reg_token_id"), + inverseJoinColumns = @JoinColumn(name = "server_group_type_id") + ) private Set entitlements = new HashSet<>(); + + @ManyToMany + @JoinTable( + name = "rhnRegTokenChannels", + joinColumns = @JoinColumn(name = "token_id"), + inverseJoinColumns = @JoinColumn(name = "channel_id") + ) private Set channels = new HashSet<>(); - private Set serverGroups = new HashSet<>(); + + @OneToMany(mappedBy = "token", cascade = CascadeType.ALL, orphanRemoval = true) private Set packages = new HashSet<>(); + + @OneToMany(mappedBy = "token", cascade = CascadeType.ALL, orphanRemoval = true) private Set appStreams = new HashSet<>(); + @ManyToMany + @JoinTable( + name = "rhnRegTokenGroups", + joinColumns = @JoinColumn(name = "token_id"), + inverseJoinColumns = @JoinColumn(name = "server_group_id") + ) + private Set serverGroups = new HashSet<>(); + /** * @return Returns the entitlements. */ @@ -465,14 +534,14 @@ public void clearPackages() { * @return Returns the activated systems */ public Set getActivatedServers() { - return activatedSystems; + return activatedServers; } /** * @param servers the activated servers to set. */ protected void setActivatedServers(Set servers) { - this.activatedSystems = servers; + this.activatedServers = servers; } /** 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..d7a6e9a70bc4 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 @@ -64,7 +64,7 @@ public void testEquals() throws Exception { Session session = HibernateFactory.getSession(); token2 = (Token) session.getNamedQuery("Token.findById") - .setLong("id", token1.getId()) + .setParameter("id", token1.getId()) .uniqueResult(); assertEquals(token1, token2); diff --git a/java/code/src/com/redhat/rhn/domain/user/AddressImpl.java b/java/code/src/com/redhat/rhn/domain/user/AddressImpl.java index 82549ede4fbf..a99f0fbd91a8 100644 --- a/java/code/src/com/redhat/rhn/domain/user/AddressImpl.java +++ b/java/code/src/com/redhat/rhn/domain/user/AddressImpl.java @@ -18,21 +18,55 @@ import com.redhat.rhn.domain.BaseDomainHelper; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + /** * Class AddressImpl that implements Address */ +@Entity +@Table(name = "WEB_USER_SITE_INFO") public class AddressImpl extends BaseDomainHelper implements Address { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "web_user_site_info_seq") + @SequenceGenerator(name = "web_user_site_info_seq", sequenceName = "WEB_USER_SITE_INFO_ID_SEQ", allocationSize = 1) + @Column(name = "id", insertable = false, updatable = false) private Long id; + + @Column(name = "address1", length = 128) private String address1; + + @Column(name = "address2", length = 128) private String address2; + + @Column(name = "city", length = 128) private String city; + + @Column(name = "state", length = 60) private String state; + + @Column(name = "zip", length = 32) private String zip; + + @Column(name = "country", length = 2) private String country; + + @Column(name = "phone", length = 32) private String phone; + + @Column(name = "fax", length = 32) private String fax; + + @Column(name = "is_po_box", length = 1) private String isPoBox; + + @Column(name = "type", length = 1) private String privType; /** diff --git a/java/code/src/com/redhat/rhn/domain/user/StateChange.java b/java/code/src/com/redhat/rhn/domain/user/StateChange.java index f55389c23b5c..85c7a24d1d7c 100644 --- a/java/code/src/com/redhat/rhn/domain/user/StateChange.java +++ b/java/code/src/com/redhat/rhn/domain/user/StateChange.java @@ -14,6 +14,8 @@ */ package com.redhat.rhn.domain.user; +import com.redhat.rhn.domain.user.legacy.UserImpl; + import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -21,15 +23,45 @@ import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + /** * StateChange */ +@Entity +@Table(name = "rhnWebContactChangeLog") public class StateChange implements Comparable { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rhn_wcon_disabled_seq") + @SequenceGenerator(name = "rhn_wcon_disabled_seq", sequenceName = "RHN_WCON_DISABLED_SEQ", allocationSize = 1) + @Column(name = "id") private Long id; - private Date date = new Date(); - private User user; - private User changedBy; + + @Column(name = "date_completed", insertable = false, updatable = false) + @Temporal(TemporalType.DATE) + private Date date; + + @ManyToOne + @JoinColumn(name = "web_contact_id", nullable = false) + private UserImpl user; + + @ManyToOne + @JoinColumn(name = "web_contact_from_id", nullable = false) + private UserImpl changedBy; + + @ManyToOne + @JoinColumn(name = "change_state_id", nullable = false) private State state; @@ -58,7 +90,7 @@ public User getChangedBy() { * @param d The changedBy to set. */ public void setChangedBy(User d) { - this.changedBy = d; + this.changedBy = (UserImpl) d; } /** @@ -100,7 +132,7 @@ public User getUser() { * @param u The user to set. */ public void setUser(User u) { - this.user = u; + this.user = (UserImpl) u; } /** 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..7456cdaa0bdc 100644 --- a/java/code/src/com/redhat/rhn/domain/user/UserFactory.java +++ b/java/code/src/com/redhat/rhn/domain/user/UserFactory.java @@ -446,7 +446,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -461,7 +461,7 @@ public static RhnTimeZone getTimeZone(String olsonName) { Session session = HibernateFactory.getSession(); return (RhnTimeZone) session .getNamedQuery("RhnTimeZone.loadTimeZoneByOlsonName") - .setString("ton", olsonName) + .setParameter("ton", olsonName) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -682,7 +682,26 @@ public List findAllUsers(Optional inOrg) { * @return list of users. */ public List findAllOrgAdmins(Org inOrg) { - return listObjectsByNamedQuery("User.findAllOrgAdmins", Map.of("org_id", inOrg.getId())); + // The native SQL query to get all users who are org_admins in the given organization + String sql = """ + SELECT u.* + FROM web_contact u + WHERE EXISTS ( + SELECT 1 + FROM rhnUserGroupMembers ugm + JOIN rhnUserGroup ug ON ugm.user_group_id = ug.id + JOIN rhnUserGroupType r ON ug.role_id = r.id + WHERE ug.org_id = :org_id + AND r.label = 'org_admin' + AND ugm.user_id = u.id + ) + """; + + Query query = HibernateFactory.getSession().createNativeQuery(sql, User.class); + query.setParameter("org_id", inOrg.getId()); + + // Execute the query and return the result + return query.getResultList(); } /** diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/AbstractUserChild.java b/java/code/src/com/redhat/rhn/domain/user/legacy/AbstractUserChild.java index 56236ad0f468..6948acea4129 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/AbstractUserChild.java +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/AbstractUserChild.java @@ -17,11 +17,13 @@ import com.redhat.rhn.domain.BaseDomainHelper; +import java.io.Serializable; + /** * Class that contains webUserId field to be used by children of the User object * (parent key) */ -public abstract class AbstractUserChild extends BaseDomainHelper { +public abstract class AbstractUserChild extends BaseDomainHelper implements Serializable { private Long webUserId; /** diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/AddressImpl.hbm.xml b/java/code/src/com/redhat/rhn/domain/user/legacy/AddressImpl.hbm.xml deleted file mode 100644 index bfb6c4b6f977..000000000000 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/AddressImpl.hbm.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - protected - - WEB_USER_SITE_INFO_ID_SEQ - 1 - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.hbm.xml b/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.hbm.xml deleted file mode 100644 index 1cdbe38e47be..000000000000 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.hbm.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - user - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.java b/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.java index dbd9e3b5f350..6b2950650155 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.java +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/PersonalInfo.java @@ -17,21 +17,54 @@ import com.redhat.rhn.domain.user.User; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + /** * Class PersonalInfo that reflects the DB representation of WEB_USER_PERSONAL_INFO * DB table: WEB_USER_PERSONAL_INFO */ +@Entity +@Table(name = "WEB_USER_PERSONAL_INFO") public class PersonalInfo extends AbstractUserChild { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "web_user_id") + private Long webUserId; + @Column(name = "prefix", length = 12) private String prefix; + + @Column(name = "first_names", length = 128) private String firstNames; + + @Column(name = "last_name", length = 128) private String lastName; + + @Column(name = "company", length = 128) private String company; + + @Column(name = "title", length = 128) private String title; + + @Column(name = "phone", length = 128) private String phone; + + @Column(name = "fax", length = 128) private String fax; + + @Column(name = "email", length = 128) private String email; - private User user; + + @OneToOne + @JoinColumn(name = "web_user_id", referencedColumnName = "id", insertable = false, updatable = false) + private UserImpl user; /** * Create a new empty user @@ -40,10 +73,10 @@ protected PersonalInfo() { } protected void setUser(User u) { - user = u; + user = (UserImpl) u; } - protected User getUser() { + protected UserImpl getUser() { return user; } @@ -174,4 +207,16 @@ public String getEmail() { public void setEmail(String emailIn) { this.email = emailIn; } + + @Override + public Long getWebUserId() { + return webUserId; + } + + @Override + public void setWebUserId(Long webUserIdIn) { + webUserId = webUserIdIn; + } + + } diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/StateChange.hbm.xml b/java/code/src/com/redhat/rhn/domain/user/legacy/StateChange.hbm.xml index abb16e4bc915..bf5ef23635b7 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/StateChange.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/StateChange.hbm.xml @@ -3,29 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - RHN_WCON_DISABLED_SEQ - 1 - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.hbm.xml b/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.hbm.xml index 30312ce503da..00ab8cbb5a19 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.hbm.xml @@ -3,77 +3,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - - - protected - - WEB_CONTACT_ID_SEQ - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -99,17 +28,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - - - SELECT ugm.user_id as user_id diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.java b/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.java index 83d9b0b05cd8..2b69d0e716ac 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.java +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/UserImpl.java @@ -24,12 +24,14 @@ import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.org.usergroup.UserGroup; import com.redhat.rhn.domain.org.usergroup.UserGroupFactory; +import com.redhat.rhn.domain.org.usergroup.UserGroupImpl; import com.redhat.rhn.domain.org.usergroup.UserGroupMembers; import com.redhat.rhn.domain.role.Role; import com.redhat.rhn.domain.role.RoleFactory; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.server.ServerGroup; import com.redhat.rhn.domain.user.Address; +import com.redhat.rhn.domain.user.AddressImpl; import com.redhat.rhn.domain.user.EnterpriseUser; import com.redhat.rhn.domain.user.Pane; import com.redhat.rhn.domain.user.RhnTimeZone; @@ -42,49 +44,116 @@ import com.suse.pam.PamReturnValue; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hibernate.annotations.Proxy; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Transient; + + + /** * Class UserImpl that reflects the DB representation of web_contact * and ancillary tables. * DB table: web_contact */ +@Entity +@Table(name = "WEB_CONTACT") +@SequenceGenerator(name = "web_contact_seq", sequenceName = "WEB_CONTACT_ID_SEQ", allocationSize = 1) +@Proxy(lazy = true) // Optional: To allow lazy-loading if needed public class UserImpl extends BaseDomainHelper implements User { - private static final Logger LOG = LogManager.getLogger(UserImpl.class); - private EnterpriseUserImpl euser; + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "web_contact_seq") + @Column(name = "id", insertable = false, updatable = false) private Long id; + + @Column(name = "login", length = 64) private String login; + + @Column(name = "login_uc", length = 64) private String loginUc; - private String password; + + @Column(name = "password", length = 110) + private String password; // Note: access = field can be added if using field-based access + + @Column(name = "read_only", nullable = false) private boolean readOnly; - private Set groupMembers; - private Org org; - private Set stateChanges; - private Set
addresses; - private Set hiddenPanes; - private Set associatedServerGroups; - private Set servers; - // PersonalInfo sub-object object + + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) private PersonalInfo personalInfo; - // UserInfo sub-object + + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) private UserInfo userInfo; - // Keep track of whether the user used to be an org admin + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "org_id") + private Org org; + + @OneToMany(mappedBy = "id", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set addresses = new HashSet<>(); + + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY) + private Set groupMembers = new HashSet<>(); + + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set stateChanges = new HashSet<>(); + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable( + name = "RHNUSERINFOPANE", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "pane_id") + ) + private Set hiddenPanes = new HashSet<>(); + + @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) + @JoinTable( + name = "rhnUserServerGroupPerms", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "server_group_id") + ) + private Set associatedServerGroups; + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable( + name = "rhnUserServerPerms", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "server_id") + ) + private Set servers = new HashSet<>(); + + @Transient private Boolean wasOrgAdmin; + @Transient + private EnterpriseUserImpl euser; + /** * Create a new empty user */ @@ -241,7 +310,7 @@ public Set getRoles() { public Set getTemporaryRoles() { Set userRoles = new HashSet<>(); for (UserGroupMembers ugm : groupMembers) { - if (ugm.getTemporary()) { + if (ugm.isTemporary()) { userRoles.add(ugm.getUserGroup().getRole()); } } @@ -261,7 +330,7 @@ public Set getTemporaryRoles() { public Set getPermanentRoles() { Set userRoles = new HashSet<>(); for (UserGroupMembers ugm : groupMembers) { - if (!ugm.getTemporary()) { + if (!ugm.isTemporary()) { userRoles.add(ugm.getUserGroup().getRole()); } } @@ -320,7 +389,7 @@ private void addRole(Role label, boolean temporary) { if (!roles.contains(label)) { UserGroup ug = org.getUserGroup(label); if (ug != null) { - UserGroupMembers ugm = new UserGroupMembers(this, ug, temporary); + UserGroupMembers ugm = new UserGroupMembers(this, (UserGroupImpl) ug, temporary); groupMembers.add(ugm); UserGroupFactory.save(ugm); } @@ -350,7 +419,7 @@ private void removeRole(Role label, boolean temporary) { for (Iterator ugmIter = groupMembers.iterator(); ugmIter.hasNext();) { UserGroupMembers ugm = ugmIter.next(); - if (ugm.getUserGroup().equals(ug) && ugm.getTemporary() == temporary) { + if (ugm.getUserGroup().equals(ug) && ugm.isTemporary() == temporary) { UserGroupFactory.delete(ugm); ugmIter.remove(); } @@ -788,14 +857,15 @@ public String toString() { * {@inheritDoc} */ @Override - public boolean equals(Object other) { - if (!(other instanceof User otherUser)) { + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { return false; } - return new EqualsBuilder().append(login, otherUser.getLogin()) - .append(org, otherUser.getOrg()) - .append(id, otherUser.getId()) - .isEquals(); + UserImpl user = (UserImpl) o; + return Objects.equals(id, user.id); } /** @@ -803,9 +873,8 @@ public boolean equals(Object other) { */ @Override public int hashCode() { - return new HashCodeBuilder().append(login).append(org).append(id).toHashCode(); + return Objects.hash(id); } - /** * Getter for address1 * @return Address1 @@ -960,7 +1029,7 @@ public void setHiddenPanes(Set p) { hiddenPanes = p; } - protected void setAddress(Address addIn) { + protected void setAddress(AddressImpl addIn) { addresses.clear(); addresses.add(addIn); } @@ -968,7 +1037,7 @@ protected void setAddress(Address addIn) { protected Address getAddress() { Address baddr = null; Address addr = null; - Address[] addrA = addresses.toArray(new Address[addresses.size()]); + Address[] addrA = addresses.toArray(new AddressImpl[addresses.size()]); if (!addresses.isEmpty()) { for (Address addressIn : addrA) { if (addressIn.getType().equals(Address.TYPE_MARKETING)) { @@ -992,7 +1061,7 @@ protected Address getAddress() { addr.setState(baddr.getState()); addr.setZip(baddr.getZip()); } - addresses.add(addr); + addresses.add((AddressImpl)addr); } return addr; } @@ -1001,7 +1070,7 @@ protected Address getAddress() { * Set the addresses. * @param s the set */ - protected void setAddresses(Set
s) { + protected void setAddresses(Set s) { addresses = s; } @@ -1009,7 +1078,7 @@ protected void setAddresses(Set
s) { * Get the addresses * @return Set of addresses */ - protected Set
getAddresses() { + protected Set getAddresses() { return addresses; } @@ -1258,7 +1327,7 @@ public void setTimeZone(RhnTimeZone timeZoneIn) { @Override public void setAddress(Address addressIn) { addresses.clear(); - addresses.add(addressIn); + addresses.add((AddressImpl)addressIn); } /** @@ -1293,7 +1362,7 @@ public Address getAddress() { addr.setState(baddr.getState()); addr.setZip(baddr.getZip()); } - addresses.add(addr); + addresses.add((AddressImpl)addr); } return addr; } diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.hbm.xml b/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.hbm.xml deleted file mode 100644 index 570e99d40a73..000000000000 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.hbm.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - user - - - - - - - - - - - - - - - - - - - - diff --git a/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.java b/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.java index 222a52577e73..9be4e65a8f10 100644 --- a/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.java +++ b/java/code/src/com/redhat/rhn/domain/user/legacy/UserInfo.java @@ -20,24 +20,67 @@ import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.Table; + /** * UserInfo represents the bean version of the DB table * RHNUSERINFO */ +@Entity +@Table(name = "RHNUSERINFO") public class UserInfo extends AbstractUserChild { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long webUserId; + + @Column(name = "page_size") private int pageSize; + + @Column(name = "use_pam_authentication") + private boolean usePamAuthentication; + + @Column(name = "email_notify") private int emailNotify; + + @Column(name = "tasko_notify", nullable = false) private boolean taskoNotify; - private boolean usePamAuthentication; + + @Column(name = "show_system_group_list") private String showSystemGroupList; + + @Column(name = "last_logged_in") + private Date lastLoggedIn; + + @Column(name = "preferred_locale") private String preferredLocale; + + @Column(name = "preferred_docs_locale") private String preferredDocsLocale; - private Date lastLoggedIn; - private RhnTimeZone timeZone; - private User user; + + @Column(name = "csv_separator") private char csvSeparator; + + @Column(name = "web_theme") private String webTheme; + @ManyToOne + @JoinColumn(name = "timezone_id") + private RhnTimeZone timeZone; + + @OneToOne + @JoinColumn(name = "user_id", referencedColumnName = "id", insertable = false, updatable = false) + private UserImpl user; /** * Create a new empty user */ @@ -45,10 +88,10 @@ protected UserInfo() { } protected void setUser(User u) { - user = u; + user = (UserImpl) u; } - protected User getUser() { + protected UserImpl getUser() { return user; } @@ -230,4 +273,15 @@ public String getWebTheme() { public void setWebTheme(String webThemeIn) { this.webTheme = webThemeIn; } + + @Override + public Long getWebUserId() { + return webUserId; + } + + @Override + public void setWebUserId(Long webUserIdIn) { + webUserId = webUserIdIn; + } + } 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..cf454b936f78 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 @@ -63,8 +63,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) + .setParameter("org_id", user.getOrg().getId()) .uniqueResult(); } } diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/channel/software/ChannelSoftwareHandler.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/channel/software/ChannelSoftwareHandler.java index 810ce53f19ce..92164934286b 100644 --- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/channel/software/ChannelSoftwareHandler.java +++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/channel/software/ChannelSoftwareHandler.java @@ -102,6 +102,9 @@ import java.util.Map; import java.util.Set; +import javax.persistence.NoResultException; + + /** * ChannelSoftwareHandler * @apidoc.namespace channel.software @@ -1588,13 +1591,17 @@ private Channel lookupChannelByLabel(User user, String label) private Channel lookupChannelByLabel(Org org, String label) throws NoSuchChannelException { - Channel channel = ChannelManager.lookupByLabel( - org, label); - if (channel == null) { + try { + Channel channel = ChannelManager.lookupByLabel( + org, label); + if (channel == null) { + throw new NoSuchChannelException(label); + } + return channel; + } + catch (NoResultException e) { throw new NoSuchChannelException(label); } - - return channel; } private Channel lookupChannelById(User user, Long id) 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 8484128d0442..70d6a4d7e578 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; @@ -1084,8 +1085,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 9fa3062ae598..82b59d445f8a 100644 --- a/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java +++ b/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java @@ -2099,7 +2099,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; } @@ -2432,7 +2432,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); @@ -2454,7 +2454,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); @@ -2479,7 +2479,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/errata/test/ErrataManagerTest.java b/java/code/src/com/redhat/rhn/manager/errata/test/ErrataManagerTest.java index 2fb643cbf53b..6e9e9f6592e2 100644 --- a/java/code/src/com/redhat/rhn/manager/errata/test/ErrataManagerTest.java +++ b/java/code/src/com/redhat/rhn/manager/errata/test/ErrataManagerTest.java @@ -76,7 +76,6 @@ import com.redhat.rhn.testing.UserTestUtils; import org.apache.commons.lang3.time.StopWatch; -import org.hibernate.criterion.Restrictions; import org.jmock.Expectations; import org.jmock.imposters.ByteBuddyClassImposteriser; import org.junit.jupiter.api.BeforeEach; @@ -1525,8 +1524,11 @@ public void testApplyErrataMultipleErrataActionChainYum() throws Exception { * @return the errata action */ private ErrataAction errataActionFromAction(Action action) { - return (ErrataAction) HibernateFactory.getSession().createCriteria(ErrataAction.class) - .add(Restrictions.idEq(action.getId())).uniqueResult(); + String sql = "SELECT * FROM rhnAction WHERE id = :id"; + return HibernateFactory.getSession() + .createNativeQuery(sql, ErrataAction.class) + .setParameter("id", action.getId()) + .getSingleResult(); } /** 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..14573be6609a 100644 --- a/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java +++ b/java/code/src/com/redhat/rhn/manager/rhnpackage/PackageManager.java @@ -636,7 +636,7 @@ public static PackageName lookupPackageName(String name) { try { session = HibernateFactory.getSession(); return (PackageName)session.getNamedQuery("PackageName.findByName") - .setString("name", name) + .setParameter("name", name) .uniqueResult(); } catch (HibernateException e) { diff --git a/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java b/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java index 5944914f0161..b0b96ad81f2a 100644 --- a/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java +++ b/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java @@ -31,6 +31,7 @@ import com.redhat.rhn.domain.server.ServerGroupFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; +import com.redhat.rhn.domain.user.legacy.UserImpl; import com.suse.manager.webui.services.SaltStateGeneratorService; import com.suse.manager.webui.services.iface.SaltApi; @@ -41,6 +42,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -53,7 +55,7 @@ /** * ServerGroupManager */ -public class ServerGroupManager { +public class ServerGroupManager implements Serializable { private static final Logger LOG = LogManager.getLogger(ServerGroupManager.class); @@ -213,7 +215,7 @@ public ManagedServerGroup create(User user, String name, String description) { user.getOrg()); SaltStateGeneratorService.INSTANCE.createServerGroup(sg); if (!user.hasRole(RoleFactory.ORG_ADMIN)) { - sg.getAssociatedAdminsFor(user).add(user); + sg.getAssociatedAdminsFor(user).add((UserImpl) user); ServerGroupFactory.save(sg); UserFactory.save(user); } diff --git a/java/code/src/com/redhat/rhn/manager/system/SystemManager.java b/java/code/src/com/redhat/rhn/manager/system/SystemManager.java index ae0d39eb520b..6e42e925d166 100644 --- a/java/code/src/com/redhat/rhn/manager/system/SystemManager.java +++ b/java/code/src/com/redhat/rhn/manager/system/SystemManager.java @@ -3616,12 +3616,13 @@ public static void giveCapability(Long sid, String capability, Long version) { * @param minionId the Salt minion id */ public static void addMinionInfoToServer(Long sid, String minionId) { - WriteMode m = ModeFactory.getWriteMode("System_queries", - "add_minion_info"); - Map params = new HashMap<>(); - params.put("sid", sid); - params.put("minion_id", minionId); - m.executeUpdate(params); + HibernateFactory.getSession().createNativeQuery(""" + insert into suseMinionInfo (server_id, minion_id) + values (:sid, :minion_id) + """) + .setParameter("sid", sid) + .setParameter("minion_id", minionId) + .executeUpdate(); } /** diff --git a/java/code/src/com/redhat/rhn/manager/system/VirtualInstanceManager.java b/java/code/src/com/redhat/rhn/manager/system/VirtualInstanceManager.java index a8fb624b5bad..36db3a4d96b5 100644 --- a/java/code/src/com/redhat/rhn/manager/system/VirtualInstanceManager.java +++ b/java/code/src/com/redhat/rhn/manager/system/VirtualInstanceManager.java @@ -14,8 +14,8 @@ */ package com.redhat.rhn.manager.system; +import com.redhat.rhn.domain.server.MinionServerFactory; import com.redhat.rhn.domain.server.Server; -import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.server.VirtualInstance; import com.redhat.rhn.domain.server.VirtualInstanceFactory; import com.redhat.rhn.domain.server.VirtualInstanceState; @@ -240,7 +240,7 @@ public static void addGuestVirtualInstance(String vmGuid, String name, // Do we have a System with machineid matching the GUID that has no // virtual instance? if (guest == null) { - ServerFactory.findByMachineId(vmGuid) + MinionServerFactory.findByMachineId(vmGuid) .ifPresent(system -> { if (system.getVirtualInstance() == null) { virtualInstance.setGuestSystem(system); diff --git a/java/code/src/com/redhat/rhn/taskomatic/TaskoFactory.java b/java/code/src/com/redhat/rhn/taskomatic/TaskoFactory.java index b2ff8fe0bf96..45f2d9b13e2f 100644 --- a/java/code/src/com/redhat/rhn/taskomatic/TaskoFactory.java +++ b/java/code/src/com/redhat/rhn/taskomatic/TaskoFactory.java @@ -14,7 +14,6 @@ */ package com.redhat.rhn.taskomatic; - import com.redhat.rhn.common.hibernate.HibernateFactory; import com.redhat.rhn.taskomatic.domain.TaskoBunch; import com.redhat.rhn.taskomatic.domain.TaskoRun; @@ -24,11 +23,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.criterion.DetachedCriteria; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; -import org.hibernate.criterion.Subqueries; +import org.hibernate.query.Query; import org.quartz.SchedulerException; import java.util.Date; @@ -36,6 +31,7 @@ import java.util.List; import java.util.Map; +import javax.persistence.NoResultException; /** * TaskoFactory @@ -430,28 +426,42 @@ public static List listRunsByBunch(String bunchName) { * @return the latest run or null if none exists */ public static TaskoRun getLatestRun(String bunchName) { - DetachedCriteria bunchIds = DetachedCriteria.forClass(TaskoBunch.class) - .add(Restrictions.eq("name", bunchName)) - .setProjection(Projections.id()); - - DetachedCriteria templateIds = DetachedCriteria.forClass(TaskoTemplate.class) - .add(Subqueries.propertyIn("bunch", bunchIds)) - .setProjection(Projections.id()); - - return (TaskoRun) getSession() - .createCriteria(TaskoRun.class) - .add(Subqueries.propertyIn("template.id", templateIds)) - .add(Restrictions.in("status", - new Object[] { - TaskoRun.STATUS_RUNNING, - TaskoRun.STATUS_FINISHED, - TaskoRun.STATUS_INTERRUPTED - })) - .addOrder(Order.desc("startTime")) - .addOrder(Order.desc("id")) - .setFirstResult(0) - .setMaxResults(1) - .uniqueResult(); + String sql = + """ + SELECT tr.id, tr.created, tr.end_time, tr.modified, tr.org_id, tr.schedule_id, tr.start_time, + tr.status, tr.template_id + FROM rhnTaskoRun tr + WHERE tr.template_id IN ( + SELECT tt.id + FROM rhnTaskoTemplate tt + WHERE tt.bunch_id = ( + SELECT tb.id + FROM rhnTaskoBunch tb + WHERE tb.name = :bunchName + ) + ) + AND tr.status IN (:status1, :status2, :status3) + ORDER BY tr.start_time DESC, tr.id DESC + LIMIT 1 + """; + + // Create the native query + Query query = getSession().createNativeQuery(sql, TaskoRun.class); + + // Set the parameters for bunchName and status + query.setParameter("bunchName", bunchName); + query.setParameter("status1", TaskoRun.STATUS_RUNNING); + query.setParameter("status2", TaskoRun.STATUS_FINISHED); + query.setParameter("status3", TaskoRun.STATUS_INTERRUPTED); + + // Execute the query and return the result (or null if no result is found) + try { + return (TaskoRun) query.getSingleResult(); + } + catch (NoResultException e) { + // Handle the case where no result is found + return null; + } } /** 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/ChannelRepodataTest.java b/java/code/src/com/redhat/rhn/taskomatic/task/test/ChannelRepodataTest.java index df29ee81c48e..24758b9e9a42 100644 --- a/java/code/src/com/redhat/rhn/taskomatic/task/test/ChannelRepodataTest.java +++ b/java/code/src/com/redhat/rhn/taskomatic/task/test/ChannelRepodataTest.java @@ -32,7 +32,6 @@ import com.redhat.rhn.taskomatic.task.RhnJob; import com.redhat.rhn.testing.JMockBaseTestCaseWithUser; -import org.hibernate.type.IntegerType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -101,9 +100,9 @@ public void canProcessRepositoriesDataForChannel() throws Exception { } private static boolean isChannelProcessed(Channel channel) { - Integer items = (Integer) HibernateFactory.getSession() - .createSQLQuery("SELECT COUNT(*) AS count FROM rhnRepoRegenQueue WHERE channel_label = :label") - .addScalar("count", IntegerType.INSTANCE) + Integer items = HibernateFactory.getSession() + .createNativeQuery("SELECT COUNT(*) AS count FROM rhnRepoRegenQueue WHERE channel_label = :label", + Integer.class) .setParameter("label", channel.getLabel()) .getSingleResult(); 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..57c0c92515b8 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 @@ -156,7 +156,7 @@ private static KickstartSessionState lookupByLabel(String label) { Session session = HibernateFactory.getSession(); return (KickstartSessionState) session .getNamedQuery("KickstartSessionState.findByLabel") - .setString("label", label) + .setParameter("label", label) .uniqueResult(); } diff --git a/java/code/src/com/redhat/rhn/testing/ChannelTestUtils.java b/java/code/src/com/redhat/rhn/testing/ChannelTestUtils.java index 83aa7d007cf8..b7fe0740d63b 100644 --- a/java/code/src/com/redhat/rhn/testing/ChannelTestUtils.java +++ b/java/code/src/com/redhat/rhn/testing/ChannelTestUtils.java @@ -23,9 +23,6 @@ import com.redhat.rhn.manager.channel.ChannelManager; import com.redhat.rhn.manager.rhnpackage.test.PackageManagerTest; -import java.util.HashSet; -import java.util.Set; - /** * ChannelTestUtils @@ -45,7 +42,7 @@ private ChannelTestUtils() { */ public static Channel createBaseChannel(User creator) throws Exception { Channel retval = ChannelFactoryTest.createBaseChannel(creator); - retval = (Channel) TestUtils.reload(retval); + retval = TestUtils.reload(retval); return retval; } @@ -129,11 +126,9 @@ public static void addDistMapToChannel(Channel c, String os, String release) { dcm.setChannelArch(c.getChannelArch()); dcm.setOs(os); dcm.setRelease(release); - Set maps = new HashSet<>(); - maps.add(dcm); - c.setDistChannelMaps(maps); - ChannelFactory.save(c); - TestUtils.saveAndFlush(dcm); + ChannelFactory.save(dcm); + + c.getDistChannelMaps().add(dcm); } /** diff --git a/java/code/src/com/redhat/rhn/testing/ErrataTestUtils.java b/java/code/src/com/redhat/rhn/testing/ErrataTestUtils.java index c1b3c91497af..dfceda34ebf0 100644 --- a/java/code/src/com/redhat/rhn/testing/ErrataTestUtils.java +++ b/java/code/src/com/redhat/rhn/testing/ErrataTestUtils.java @@ -350,8 +350,9 @@ public static Package createTestPackage(User user, Errata errata, Channel channe if (errata != null) { errata.addPackage(result); - result.setErrata(Set.of(errata)); + HibernateFactory.getSession().flush(); HibernateFactory.getSession().refresh(errata); + HibernateFactory.getSession().refresh(result); } return result; diff --git a/java/code/src/com/redhat/rhn/testing/TestUtils.java b/java/code/src/com/redhat/rhn/testing/TestUtils.java index 7c8dbf06e35e..0b8830d3a9f2 100644 --- a/java/code/src/com/redhat/rhn/testing/TestUtils.java +++ b/java/code/src/com/redhat/rhn/testing/TestUtils.java @@ -267,7 +267,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) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -284,7 +284,7 @@ public static Object lookupFromCacheByLabel(String label, String queryname) { Session session = HibernateFactory.getSession(); return session.getNamedQuery(queryname) - .setString("label", label) + .setParameter("label", label) //Retrieve from cache if there .setCacheable(true) .uniqueResult(); @@ -367,7 +367,7 @@ public static T reload(T obj) throws HibernateException { */ public static void saveAndFlush(Object obj) throws HibernateException { Session session = HibernateFactory.getSession(); - session.save(obj); + session.merge(obj); session.flush(); } diff --git a/java/code/src/com/suse/cloud/domain/PaygDimensionResult.java b/java/code/src/com/suse/cloud/domain/PaygDimensionResult.java index 5393f113bd6b..da7ebe6a594a 100644 --- a/java/code/src/com/suse/cloud/domain/PaygDimensionResult.java +++ b/java/code/src/com/suse/cloud/domain/PaygDimensionResult.java @@ -91,7 +91,7 @@ public Long getComputationId() { } @Column(name = "dimension") - @Type(type = "com.suse.cloud.domain.BillingDimensionEnumType") + @Type(type = "yes_no") public BillingDimension getDimension() { return dimension; } 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 b156751c4238..dc08aa811eb6 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; @@ -342,7 +343,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()) @@ -364,7 +365,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(); @@ -385,7 +386,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/log4j2.xml b/java/code/src/log4j2.xml index 9dc9c87e7f97..3d7c158a9bd2 100644 --- a/java/code/src/log4j2.xml +++ b/java/code/src/log4j2.xml @@ -99,9 +99,8 @@ --> - + + - - - - - - - - - - - - - - - - - - - - diff --git a/java/spacewalk-java.changes.mbussolotto.hibernate_upgrade b/java/spacewalk-java.changes.mbussolotto.hibernate_upgrade new file mode 100644 index 000000000000..b6dec5484c70 --- /dev/null +++ b/java/spacewalk-java.changes.mbussolotto.hibernate_upgrade @@ -0,0 +1 @@ +- Hibernate 6 upgrade diff --git a/java/spacewalk-java.spec b/java/spacewalk-java.spec index 92fb54738d01..cf4b2f2fb81a 100644 --- a/java/spacewalk-java.spec +++ b/java/spacewalk-java.spec @@ -95,11 +95,11 @@ BuildRequires: cglib BuildRequires: classmate BuildRequires: dom4j BuildRequires: glassfish-activation -BuildRequires: glassfish-jaxb-api +BuildRequires: jaxb-api BuildRequires: glassfish-jaxb-runtime BuildRequires: glassfish-jaxb-txw2 -BuildRequires: hibernate-commons-annotations -BuildRequires: hibernate-types +BuildRequires: hibernate-commons-annotations >= 6 +BuildRequires: hypersistence-utils >= 3.8.2 BuildRequires: httpcomponents-asyncclient BuildRequires: httpcomponents-client BuildRequires: ical4j @@ -114,7 +114,7 @@ BuildRequires: jboss-logging BuildRequires: jdom BuildRequires: joda-time BuildRequires: jose4j -BuildRequires: jpa-api +BuildRequires: jpa-api >= 3.1 BuildRequires: jsch BuildRequires: jta BuildRequires: libxml2 @@ -147,9 +147,9 @@ BuildRequires: xalan-j2 BuildRequires: xmlsec BuildRequires: (google-gson >= 2.2.4 with google-gson < 2.10.0) BuildRequires: mvn(org.apache.velocity:velocity-engine-core) >= 2.2 -BuildRequires: mvn(org.hibernate:hibernate-c3p0) -BuildRequires: mvn(org.hibernate:hibernate-core) -BuildRequires: mvn(org.hibernate:hibernate-ehcache) +BuildRequires: mvn(org.hibernate:hibernate-c3p0) >= 6 +BuildRequires: mvn(org.hibernate:hibernate-core) >= 6 +BuildRequires: mvn(org.hibernate:hibernate-ehcache) >= 6 %if 0%{?suse_version} BuildRequires: ant-nodeps BuildRequires: libxml2-tools @@ -183,8 +183,8 @@ Requires: glassfish-activation Requires: glassfish-jaxb-api Requires: glassfish-jaxb-runtime Requires: glassfish-jaxb-txw2 -Requires: hibernate-commons-annotations -Requires: hibernate-types +Requires: hibernate-commons-annotations >= 6 +Requires: hypersistence-utils >= 3.8.2 Requires: httpcomponents-client Requires: ical4j Requires: istack-commons-runtime @@ -198,7 +198,7 @@ Requires: jboss-logging Requires: jdom Requires: joda-time Requires: jose4j -Requires: jpa-api +Requires: jpa-api >= 3.1 Requires: jta Requires: libsolv-tools Requires: log4j @@ -235,9 +235,9 @@ Requires: xmlsec Requires: (/sbin/unix2_chkpwd or /usr/sbin/unix2_chkpwd) Requires: (google-gson >= 2.2.4 with google-gson < 2.10.0) Requires: mvn(org.apache.tomcat:tomcat-servlet-api) > 8 -Requires: mvn(org.hibernate:hibernate-c3p0) -Requires: mvn(org.hibernate:hibernate-core) -Requires: mvn(org.hibernate:hibernate-ehcache) +Requires: mvn(org.hibernate:hibernate-c3p0) >= 6 +Requires: mvn(org.hibernate:hibernate-core) >= 6 +Requires: mvn(org.hibernate:hibernate-ehcache) >= 6 Requires: openssl # libtcnative-1-0 is only recommended in tomcat. # We want it always to prevent warnings about openssl cannot be used @@ -357,7 +357,8 @@ Requires: c3p0 >= 0.9.1 Requires: cglib Requires: classmate Requires: cobbler -Requires: hibernate-commons-annotations +Requires: concurrent +Requires: hibernate-commons-annotations >= 6 Requires: httpcomponents-client Requires: httpcomponents-core Requires: java-%{java_version}-openjdk @@ -378,9 +379,9 @@ Requires: tomcat-taglibs-standard Requires: xalan-j2 >= 2.6.0 Requires: xerces-j2 Requires: (/sbin/unix2_chkpwd or /usr/sbin/unix2_chkpwd) -Requires: mvn(org.hibernate:hibernate-c3p0) -Requires: mvn(org.hibernate:hibernate-core) -Requires: mvn(org.hibernate:hibernate-ehcache) +Requires: mvn(org.hibernate:hibernate-c3p0) >= 6 +Requires: mvn(org.hibernate:hibernate-core) >= 6 +Requires: mvn(org.hibernate:hibernate-ehcache) >= 6 Conflicts: quartz < 2.0 diff --git a/spacewalk/setup/share/tomcat_java_opts.conf b/spacewalk/setup/share/tomcat_java_opts.conf index 510e0d9f4bf7..e26502369a99 100644 --- a/spacewalk/setup/share/tomcat_java_opts.conf +++ b/spacewalk/setup/share/tomcat_java_opts.conf @@ -1 +1 @@ -JAVA_OPTS="$JAVA_OPTS -ea -Xms256m -Xmx1G -Djava.awt.headless=true -Dorg.xml.sax.driver=com.redhat.rhn.frontend.xmlrpc.util.RhnSAXParser -Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=1024 -Dnet.sf.ehcache.skipUpdateCheck=true" +JAVA_OPTS="$JAVA_OPTS -ea -Xms256m -Xmx1G -Djava.awt.headless=true -Dorg.xml.sax.driver=com.redhat.rhn.frontend.xmlrpc.util.RhnSAXParser -Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=1024" diff --git a/spacewalk/setup/spacewalk-setup.changes.mbussolotto.hibernate_upgrade b/spacewalk/setup/spacewalk-setup.changes.mbussolotto.hibernate_upgrade new file mode 100644 index 000000000000..b6dec5484c70 --- /dev/null +++ b/spacewalk/setup/spacewalk-setup.changes.mbussolotto.hibernate_upgrade @@ -0,0 +1 @@ +- Hibernate 6 upgrade