JPA Refactoring (#2107)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-11-29 14:07:37 +02:00
committed by GitHub
parent ebcb6a0b29
commit 2a95adc562
29 changed files with 356 additions and 919 deletions

View File

@@ -86,8 +86,7 @@ public final class JpaManagementHelper {
public static <J extends AbstractJpaBaseEntity> J touch(final EntityManager entityManager, public static <J extends AbstractJpaBaseEntity> J touch(final EntityManager entityManager,
final CrudRepository<J, ?> repository, final J entity) { final CrudRepository<J, ?> repository, final J entity) {
// merge base entity so optLockRevision gets updated and audit // merge base entity so optLockRevision gets updated and auditing log written because modifying e.g. metadata is modifying the base
// log written because modifying e.g. metadata is modifying the base
// entity itself for auditing purposes. // entity itself for auditing purposes.
final J result = entityManager.merge(entity); final J result = entityManager.merge(entity);
result.setLastModifiedAt(0L); result.setLastModifiedAt(0L);

View File

@@ -592,13 +592,11 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
backoff = @Backoff(delay = Constants.TX_RT_DELAY)) backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetMetadata updateMetaData(final long id, final MetaData md) { public DistributionSetMetadata updateMetaData(final long id, final MetaData md) {
// check if exists otherwise throw entity not found exception // check if exists otherwise throw entity not found exception
final JpaDistributionSetMetadata toUpdate = (JpaDistributionSetMetadata) getMetaDataByDistributionSetId(id, final JpaDistributionSetMetadata toUpdate = (JpaDistributionSetMetadata) getMetaDataByDistributionSetId(id, md.getKey())
md.getKey())
.orElseThrow(() -> new EntityNotFoundException(DistributionSetMetadata.class, id, md.getKey())); .orElseThrow(() -> new EntityNotFoundException(DistributionSetMetadata.class, id, md.getKey()));
toUpdate.setValue(md.getValue()); toUpdate.setValue(md.getValue());
// touch it to update the lock revision because we are modifying the // touch it to update the lock revision because we are modifying the DS indirectly, it will, also check UPDATE access
// DS indirectly, it will, also check UPDATE access
JpaManagementHelper.touch(entityManager, distributionSetRepository, (JpaDistributionSet) getValid(id)); JpaManagementHelper.touch(entityManager, distributionSetRepository, (JpaDistributionSet) getValid(id));
return distributionSetMetadataRepository.save(toUpdate); return distributionSetMetadataRepository.save(toUpdate);
} }

View File

@@ -25,6 +25,7 @@ import jakarta.persistence.PostUpdate;
import jakarta.persistence.Version; import jakarta.persistence.Version;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
@@ -38,11 +39,12 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
/** /**
* Holder of the base attributes common to all entities. * Base hawkBit entity class containing the common attributes.
*/ */
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities. @NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
@Setter
@Getter
@MappedSuperclass @MappedSuperclass
@Access(AccessType.FIELD)
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class }) @EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class })
public abstract class AbstractJpaBaseEntity implements BaseEntity { public abstract class AbstractJpaBaseEntity implements BaseEntity {
@@ -51,62 +53,53 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Setter
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id") @Column(name = "id")
private Long id; private Long id;
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
private String createdBy; private String createdBy;
@Column(name = "created_at", updatable = false, nullable = false)
private long createdAt; private long createdAt;
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH)
private String lastModifiedBy; private String lastModifiedBy;
@Column(name = "last_modified_at", nullable = false)
private long lastModifiedAt; private long lastModifiedAt;
@Setter
@Version @Version
@Column(name = "optlock_revision") @Column(name = "optlock_revision")
private int optLockRevision; private int optLockRevision;
@Override @CreatedBy
public void setCreatedBy(final String createdBy) {
if (isController()) {
this.createdBy = "CONTROLLER_PLUG_AND_PLAY";
// In general modification audit entry is not changed by the controller.
// However, we want to stay consistent with EnableJpaAuditing#modifyOnCreate=true.
this.lastModifiedBy = this.createdBy;
return;
}
this.createdBy = createdBy;
}
// maybe needed to have correct createdBy value in the database
@Access(AccessType.PROPERTY) @Access(AccessType.PROPERTY)
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
public String getCreatedBy() { public String getCreatedBy() {
return createdBy; return createdBy;
} }
@Override @CreatedDate
@Access(AccessType.PROPERTY) public void setCreatedAt(final long createdAt) {
@Column(name = "created_at", updatable = false, nullable = false) this.createdAt = createdAt;
public long getCreatedAt() {
return createdAt;
}
@Override // In general modification audit entry is not changed by the controller.
@Access(AccessType.PROPERTY) // However, we want to stay consistent with EnableJpaAuditing#modifyOnCreate=true.
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH)
public String getLastModifiedBy() {
return lastModifiedBy;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_at", nullable = false)
public long getLastModifiedAt() {
return lastModifiedAt;
}
@Override
public int getOptLockRevision() {
return optLockRevision;
}
@LastModifiedDate
public void setLastModifiedAt(final long lastModifiedAt) {
if (isController()) { if (isController()) {
return; this.lastModifiedAt = createdAt;
} }
this.lastModifiedAt = lastModifiedAt;
} }
@LastModifiedBy @LastModifiedBy
@@ -118,44 +111,36 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
this.lastModifiedBy = lastModifiedBy; this.lastModifiedBy = lastModifiedBy;
} }
@CreatedDate // maybe needed to have correct createdAt value in the database
public void setCreatedAt(final long createdAt) { @Access(AccessType.PROPERTY)
this.createdAt = createdAt; public long getCreatedAt() {
return createdAt;
// In general modification audit entry is not changed by the controller.
// However, we want to stay consistent with
// EnableJpaAuditing#modifyOnCreate=true.
if (isController()) {
this.lastModifiedAt = createdAt;
}
} }
@CreatedBy // seems needed to have correct lastModifiedBy value in the database
public void setCreatedBy(final String createdBy) { @Access(AccessType.PROPERTY)
if (isController()) { public String getLastModifiedBy() {
this.createdBy = "CONTROLLER_PLUG_AND_PLAY"; return lastModifiedBy;
}
// In general modification audit entry is not changed by the @LastModifiedDate
// controller. However, we want to stay consistent with public void setLastModifiedAt(final long lastModifiedAt) {
// EnableJpaAuditing#modifyOnCreate=true. if (isController()) {
this.lastModifiedBy = this.createdBy;
return; return;
} }
this.createdBy = createdBy; this.lastModifiedAt = lastModifiedAt;
} }
@Override // property access to make entity manager to detect touch
public Long getId() { @Access(AccessType.PROPERTY)
return id; public long getLastModifiedAt() {
return lastModifiedAt;
} }
/** /**
* Defined equals/hashcode strategy for the repository in general is that an * Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class. * {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#hashCode()
*/ */
@Override @Override
// Exception squid:S864 - generated code // Exception squid:S864 - generated code
@@ -170,11 +155,8 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
} }
/** /**
* Defined equals/hashcode strategy for the repository in general is that an * Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class. * {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#equals(java.lang.Object)
*/ */
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {

View File

@@ -33,7 +33,10 @@ import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
* Holder of the base attributes common to all tenant aware entities. * Holder of the base attributes common to all tenant aware entities.
*/ */
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities. @NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
@Setter
@Getter
@MappedSuperclass @MappedSuperclass
// Eclipse link MultiTenant support
@TenantDiscriminatorColumn(name = "tenant", length = 40) @TenantDiscriminatorColumn(name = "tenant", length = 40)
@Multitenant(MultitenantType.SINGLE_TABLE) @Multitenant(MultitenantType.SINGLE_TABLE)
public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEntity implements TenantAwareBaseEntity { public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEntity implements TenantAwareBaseEntity {
@@ -41,8 +44,6 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Setter
@Getter
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40) @Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40)
@Size(min = 1, max = 40) @Size(min = 1, max = 40)
@NotNull @NotNull
@@ -74,13 +75,10 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
} }
final AbstractJpaTenantAwareBaseEntity other = (AbstractJpaTenantAwareBaseEntity) obj; final AbstractJpaTenantAwareBaseEntity other = (AbstractJpaTenantAwareBaseEntity) obj;
if (tenant == null) { if (tenant == null) {
if (other.tenant != null) { return other.tenant == null;
return false; } else {
return tenant.equals(other.tenant);
} }
} else if (!tenant.equals(other.tenant)) {
return false;
}
return true;
} }
@Override @Override

View File

@@ -25,6 +25,10 @@ import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact; import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -32,7 +36,12 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
/** /**
* JPA implementation of {@link Artifact}. * JPA implementation of {@link Artifact}.
*/ */
@Table(name = "sp_artifact", indexes = { @Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"), @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Setter
@Getter
@Table(name = "sp_artifact",
indexes = {
@Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"),
@Index(name = "sp_idx_artifact_02", columnList = "tenant,sha1_hash"), @Index(name = "sp_idx_artifact_02", columnList = "tenant,sha1_hash"),
@Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") }) @Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") })
@Entity @Entity
@@ -43,36 +52,31 @@ public class JpaArtifact extends AbstractJpaTenantAwareBaseEntity implements Art
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "sha1_hash", length = 40, nullable = false, updatable = false) @ManyToOne(optional = false, cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY)
@Size(min = 1, max = 40) @JoinColumn(
@NotNull name = "software_module", nullable = false, updatable = false,
private String sha1Hash; foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm"))
private JpaSoftwareModule softwareModule;
@Column(name = "provided_file_name", length = 256, updatable = false) @Column(name = "provided_file_name", length = 256, updatable = false)
@Size(min = 1, max = 256) @Size(min = 1, max = 256)
@NotNull @NotNull
private String filename; private String filename;
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY)
@JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm"))
private JpaSoftwareModule softwareModule;
@Column(name = "md5_hash", length = 32, updatable = false, nullable = true) @Column(name = "md5_hash", length = 32, updatable = false, nullable = true)
private String md5Hash; private String md5Hash;
@Column(name = "sha1_hash", length = 40, nullable = false, updatable = false)
@Size(min = 1, max = 40)
@NotNull
private String sha1Hash;
@Column(name = "sha256_hash", length = 64, updatable = false, nullable = true) @Column(name = "sha256_hash", length = 64, updatable = false, nullable = true)
private String sha256Hash; private String sha256Hash;
@Column(name = "file_size", updatable = false) @Column(name = "file_size", updatable = false)
private long size; private long size;
/**
* Default constructor needed for JPA entities..
*/
public JpaArtifact() {
// Default constructor needed for JPA entities.
}
/** /**
* Constructs artifact. * Constructs artifact.
* *
@@ -80,57 +84,10 @@ public class JpaArtifact extends AbstractJpaTenantAwareBaseEntity implements Art
* @param filename that is used by {@link AbstractDbArtifact} store. * @param filename that is used by {@link AbstractDbArtifact} store.
* @param softwareModule of this artifact * @param softwareModule of this artifact
*/ */
public JpaArtifact(@NotEmpty final String sha1Hash, @NotNull final String filename, public JpaArtifact(@NotEmpty final String sha1Hash, @NotNull final String filename, final SoftwareModule softwareModule) {
final SoftwareModule softwareModule) {
this.sha1Hash = sha1Hash; this.sha1Hash = sha1Hash;
this.filename = filename; this.filename = filename;
this.softwareModule = (JpaSoftwareModule) softwareModule; this.softwareModule = (JpaSoftwareModule) softwareModule;
this.softwareModule.addArtifact(this); this.softwareModule.addArtifact(this);
} }
@Override
public String getFilename() {
return filename;
}
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
@Override
public String getMd5Hash() {
return md5Hash;
}
@Override
public String getSha1Hash() {
return sha1Hash;
}
@Override
public String getSha256Hash() {
return sha256Hash;
}
public void setSha256Hash(final String sha256Hash) {
this.sha256Hash = sha256Hash;
}
@Override
public long getSize() {
return size;
}
public void setSize(final long size) {
this.size = size;
}
public void setSha1Hash(final String sha1Hash) {
this.sha1Hash = sha1Hash;
}
public void setMd5Hash(final String md5Hash) {
this.md5Hash = md5Hash;
}
} }

View File

@@ -19,11 +19,17 @@ import jakarta.persistence.OneToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus; import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Getter
@Entity @Entity
@Table(name = "sp_target_conf_status") @Table(name = "sp_target_conf_status")
public class JpaAutoConfirmationStatus extends AbstractJpaTenantAwareBaseEntity implements AutoConfirmationStatus { public class JpaAutoConfirmationStatus extends AbstractJpaTenantAwareBaseEntity implements AutoConfirmationStatus {
@@ -40,39 +46,17 @@ public class JpaAutoConfirmationStatus extends AbstractJpaTenantAwareBaseEntity
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) @Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String remark; private String remark;
/**
* Default constructor needed for JPA entities.
*/
public JpaAutoConfirmationStatus() {
// Default constructor needed for JPA entities.
}
public JpaAutoConfirmationStatus(final String initiator, final String remark, final Target target) { public JpaAutoConfirmationStatus(final String initiator, final String remark, final Target target) {
this.target = (JpaTarget) target; this.target = (JpaTarget) target;
this.initiator = StringUtils.isEmpty(initiator) ? null : initiator; this.initiator = StringUtils.isEmpty(initiator) ? null : initiator;
this.remark = StringUtils.isEmpty(remark) ? null : remark; this.remark = StringUtils.isEmpty(remark) ? null : remark;
} }
@Override
public Target getTarget() {
return target;
}
@Override
public String getInitiator() {
return initiator;
}
@Override @Override
public long getActivatedAt() { public long getActivatedAt() {
return getCreatedAt(); return getCreatedAt();
} }
@Override
public String getRemark() {
return remark;
}
@Override @Override
public String constructActionMessage() { public String constructActionMessage() {
final String remarkMessage = StringUtils.hasText(remark) ? remark : "n/a"; final String remarkMessage = StringUtils.hasText(remark) ? remark : "n/a";
@@ -90,8 +74,8 @@ public class JpaAutoConfirmationStatus extends AbstractJpaTenantAwareBaseEntity
@Override @Override
public String toString() { public String toString() {
return "AutoConfirmationStatus [id=" + getId() + ", target=" + target.getControllerId() + ", initiator=" return "AutoConfirmationStatus [id=" + getId() + ", target=" + target.getControllerId() +
+ initiator + ", bosch_user=" + getCreatedBy() + ", activatedAt=" + getCreatedAt() + ", remark=" ", initiator=" + initiator + ", bosch_user=" + getCreatedBy() + ", activatedAt=" + getCreatedAt() +
+ remark + "]"; ", remark=" + remark + "]";
} }
} }

View File

@@ -37,6 +37,7 @@ import jakarta.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
@@ -60,12 +61,13 @@ import org.springframework.context.ApplicationEvent;
@Getter @Getter
@ToString(callSuper = true) @ToString(callSuper = true)
@Entity @Entity
@Table(name = "sp_distribution_set", uniqueConstraints = { @Table(name = "sp_distribution_set",
@UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { uniqueConstraints = { @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") },
indexes = {
@Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,complete"), @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,complete"),
@Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), @NamedEntityGraph(name = "DistributionSet.detail",
@NamedAttributeNode("tags"), @NamedAttributeNode("type") }) attributeNodes = { @NamedAttributeNode("modules"), @NamedAttributeNode("tags"), @NamedAttributeNode("type") })
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet, EventAwareEntity { public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet, EventAwareEntity {
@@ -75,6 +77,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
private static final String DELETED_PROPERTY = "deleted"; private static final String DELETED_PROPERTY = "deleted";
@Setter
@ManyToOne(fetch = FetchType.LAZY, optional = false, targetEntity = JpaDistributionSetType.class) @ManyToOne(fetch = FetchType.LAZY, optional = false, targetEntity = JpaDistributionSetType.class)
@JoinColumn(name = "ds_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) @JoinColumn(name = "ds_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
@NotNull @NotNull
@@ -117,12 +120,14 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Column(name = "locked") @Column(name = "locked")
private boolean locked; private boolean locked;
@Setter
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@Column(name = "valid") @Column(name = "valid")
private boolean valid; private boolean valid;
@Setter
@Column(name = "required_migration_step") @Column(name = "required_migration_step")
private boolean requiredMigrationStep; private boolean requiredMigrationStep;
@@ -155,10 +160,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
this(name, version, description, type, moduleList, false); this(name, version, description, type, moduleList, false);
} }
public void setType(final DistributionSetType type) {
this.type = type;
}
@Override @Override
public Set<SoftwareModule> getModules() { public Set<SoftwareModule> getModules() {
if (modules == null) { if (modules == null) {
@@ -168,7 +169,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return Collections.unmodifiableSet(modules); return Collections.unmodifiableSet(modules);
} }
public boolean addModule(final SoftwareModule softwareModule) { public void addModule(final SoftwareModule softwareModule) {
if (isLocked()) { if (isLocked()) {
throw new LockedException(JpaDistributionSet.class, getId(), "ADD_SOFTWARE_MODULE"); throw new LockedException(JpaDistributionSet.class, getId(), "ADD_SOFTWARE_MODULE");
} }
@@ -183,7 +184,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
.filter(module -> module.getId().equals(softwareModule.getId())).findAny(); .filter(module -> module.getId().equals(softwareModule.getId())).findAny();
if (found.isPresent()) { if (found.isPresent()) {
return false; return;
} }
final long already = modules.stream() final long already = modules.stream()
@@ -196,10 +197,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
if (modules.add(softwareModule)) { if (modules.add(softwareModule)) {
complete = type.checkComplete(this); complete = type.checkComplete(this);
return true;
} }
return false;
} }
public void removeModule(final SoftwareModule softwareModule) { public void removeModule(final SoftwareModule softwareModule) {
@@ -255,18 +253,10 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
locked = false; locked = false;
} }
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
public void invalidate() { public void invalidate() {
this.valid = false; this.valid = false;
} }
public void setRequiredMigrationStep(final boolean isRequiredMigrationStep) {
requiredMigrationStep = isRequiredMigrationStep;
}
@Override @Override
public void fireCreateEvent() { public void fireCreateEvent() {
publishEventWithEventPublisher( publishEventWithEventPublisher(

View File

@@ -21,12 +21,18 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
/** /**
* Meta data for {@link DistributionSet}. * Meta data for {@link DistributionSet}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Getter
@IdClass(DsMetadataCompositeKey.class) @IdClass(DsMetadataCompositeKey.class)
@Entity @Entity
@Table(name = "sp_ds_metadata") @Table(name = "sp_ds_metadata")
@@ -40,10 +46,6 @@ public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements D
@JoinColumn(name = "ds_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds")) @JoinColumn(name = "ds_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds"))
private JpaDistributionSet distributionSet; private JpaDistributionSet distributionSet;
public JpaDistributionSetMetadata() {
// default public constructor for JPA
}
public JpaDistributionSetMetadata(final String key, final String value) { public JpaDistributionSetMetadata(final String key, final String value) {
super(key, value); super(key, value);
} }
@@ -57,11 +59,6 @@ public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements D
return new DsMetadataCompositeKey(distributionSet.getId(), getKey()); return new DsMetadataCompositeKey(distributionSet.getId(), getKey());
} }
@Override
public DistributionSet getDistributionSet() {
return distributionSet;
}
public void setDistributionSet(final DistributionSet distributionSet) { public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet; this.distributionSet = (JpaDistributionSet) distributionSet;
} }
@@ -83,12 +80,9 @@ public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements D
} }
final JpaDistributionSetMetadata other = (JpaDistributionSetMetadata) obj; final JpaDistributionSetMetadata other = (JpaDistributionSetMetadata) obj;
if (distributionSet == null) { if (distributionSet == null) {
if (other.distributionSet != null) { return other.distributionSet == null;
return false; } else {
return distributionSet.equals(other.distributionSet);
} }
} else if (!distributionSet.equals(other.distributionSet)) {
return false;
}
return true;
} }
} }

View File

@@ -19,6 +19,8 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
@@ -27,9 +29,9 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* A {@link DistributionSetTag} is used to describe DistributionSet attributes * A {@link DistributionSetTag} is used to describe DistributionSet attributes and use them also for filtering the DistributionSet list.
* and use them also for filtering the DistributionSet list.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Entity @Entity
@Table(name = "sp_distributionset_tag", @Table(name = "sp_distributionset_tag",
indexes = { indexes = {
@@ -55,13 +57,6 @@ public class JpaDistributionSetTag extends JpaTag implements DistributionSetTag,
super(name, description, colour); super(name, description, colour);
} }
/**
* Default constructor for JPA.
*/
public JpaDistributionSetTag() {
// Default constructor for JPA.
}
@Override @Override
public void fireCreateEvent() { public void fireCreateEvent() {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(

View File

@@ -27,6 +27,10 @@ import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTypeDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetTypeDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeUpdatedEvent;
@@ -39,9 +43,9 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* A distribution set type defines which software module types can or have to be * A distribution set type defines which software module types can or have to be {@link DistributionSet}.
* {@link DistributionSet}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Entity @Entity
@Table(name = "sp_distribution_set_type", indexes = { @Table(name = "sp_distribution_set_type", indexes = {
@Index(name = "sp_idx_distribution_set_type_01", columnList = "tenant,deleted"), @Index(name = "sp_idx_distribution_set_type_01", columnList = "tenant,deleted"),
@@ -57,68 +61,34 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
@OneToMany(mappedBy = "dsType", targetEntity = DistributionSetTypeElement.class, fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, @OneToMany(mappedBy = "dsType", targetEntity = DistributionSetTypeElement.class, fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST,
CascadeType.REMOVE }, orphanRemoval = true) CascadeType.REMOVE }, orphanRemoval = true)
private Set<DistributionSetTypeElement> elements; private Set<DistributionSetTypeElement> elements = new HashSet<>();
@Setter
@Getter
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@ManyToMany(mappedBy = "distributionSetTypes", targetEntity = JpaTargetType.class, fetch = FetchType.LAZY) @ManyToMany(mappedBy = "distributionSetTypes", targetEntity = JpaTargetType.class, fetch = FetchType.LAZY)
private List<TargetType> compatibleToTargetTypes; private List<TargetType> compatibleToTargetTypes;
public JpaDistributionSetType() {
// default public constructor for JPA
}
/**
* Standard constructor.
*
* @param key of the type (unique)
* @param name of the type (unique)
* @param description of the type
*/
public JpaDistributionSetType(final String key, final String name, final String description) { public JpaDistributionSetType(final String key, final String name, final String description) {
this(key, name, description, null); this(key, name, description, null);
} }
/**
* Constructor.
*
* @param key of the type
* @param name of the type
* @param description of the type
* @param colour of the type. It will be null by default
*/
public JpaDistributionSetType(final String key, final String name, final String description, final String colour) { public JpaDistributionSetType(final String key, final String name, final String description, final String colour) {
super(name, description, key, colour); super(name, description, key, colour);
} }
@Override
public boolean isDeleted() {
return deleted;
}
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Override @Override
public Set<SoftwareModuleType> getMandatoryModuleTypes() { public Set<SoftwareModuleType> getMandatoryModuleTypes() {
if (elements == null) {
return Collections.emptySet();
}
return elements.stream().filter(DistributionSetTypeElement::isMandatory) return elements.stream().filter(DistributionSetTypeElement::isMandatory)
.map(DistributionSetTypeElement::getSmType).collect(Collectors.toSet()); .map(DistributionSetTypeElement::getSmType).collect(Collectors.toSet());
} }
@Override @Override
public Set<SoftwareModuleType> getOptionalModuleTypes() { public Set<SoftwareModuleType> getOptionalModuleTypes() {
if (elements == null) { return elements.stream().filter(element -> !element.isMandatory())
return Collections.emptySet(); .map(DistributionSetTypeElement::getSmType).collect(Collectors.toSet());
}
return elements.stream().filter(element -> !element.isMandatory()).map(DistributionSetTypeElement::getSmType)
.collect(Collectors.toSet());
} }
@Override @Override
@@ -134,12 +104,11 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
@Override @Override
public boolean checkComplete(final DistributionSet distributionSet) { public boolean checkComplete(final DistributionSet distributionSet) {
final List<SoftwareModuleType> smTypes = distributionSet.getModules().stream().map(SoftwareModule::getType) final List<SoftwareModuleType> smTypes = distributionSet.getModules().stream()
.distinct().toList(); .map(SoftwareModule::getType)
if (smTypes.isEmpty()) { .distinct()
return false; .toList();
} return !smTypes.isEmpty() && new HashSet<>(smTypes).containsAll(getMandatoryModuleTypes());
return new HashSet<>(smTypes).containsAll(getMandatoryModuleTypes());
} }
public JpaDistributionSetType addOptionalModuleType(final SoftwareModuleType smType) { public JpaDistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
@@ -151,22 +120,14 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
} }
public JpaDistributionSetType removeModuleType(final Long smTypeId) { public JpaDistributionSetType removeModuleType(final Long smTypeId) {
if (elements == null) { // we search by id (standard equals compares also revision)
return this; elements.stream().filter(element -> element.getSmType().getId().equals(smTypeId))
} .findAny()
// we search by id (standard equals compares also revison)
elements.stream().filter(element -> element.getSmType().getId().equals(smTypeId)).findAny()
.ifPresent(elements::remove); .ifPresent(elements::remove);
return this; return this;
} }
public Set<DistributionSetTypeElement> getElements() { public Set<DistributionSetTypeElement> getElements() {
if (elements == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(elements); return Collections.unmodifiableSet(elements);
} }
@@ -194,10 +155,8 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
} }
private boolean isOneModuleListEmpty(final DistributionSetType dsType) { private boolean isOneModuleListEmpty(final DistributionSetType dsType) {
return (!CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements) return (!CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements) && CollectionUtils.isEmpty(elements)) ||
&& CollectionUtils.isEmpty(elements)) (CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements) && !CollectionUtils.isEmpty(elements));
|| (CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements)
&& !CollectionUtils.isEmpty(elements));
} }
private boolean areBothModuleListsEmpty(final DistributionSetType dsType) { private boolean areBothModuleListsEmpty(final DistributionSetType dsType) {
@@ -205,21 +164,18 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
} }
private JpaDistributionSetType setModuleType(final SoftwareModuleType smType, final boolean mandatory) { private JpaDistributionSetType setModuleType(final SoftwareModuleType smType, final boolean mandatory) {
if (elements == null) { if (elements.isEmpty()) {
elements = new HashSet<>();
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory)); elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory));
return this; return this;
} }
// check if this was in the list before before // check if this was in the list before
final Optional<DistributionSetTypeElement> existing = elements.stream() elements.stream()
.filter(element -> element.getSmType().getKey().equals(smType.getKey())).findAny(); .filter(element -> element.getSmType().getKey().equals(smType.getKey()))
.findAny()
if (existing.isPresent()) { .ifPresentOrElse(
existing.get().setMandatory(mandatory); element -> element.setMandatory(mandatory),
} else { () -> elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory)));
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory));
}
return this; return this;
} }

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serial; import java.io.Serial;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -34,6 +35,10 @@ import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
@@ -50,6 +55,7 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* JPA implementation of a {@link Rollout}. * JPA implementation of a {@link Rollout}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Entity @Entity
@Table(name = "sp_rollout", uniqueConstraints = @UniqueConstraint(columnNames = { "name", @Table(name = "sp_rollout", uniqueConstraints = @UniqueConstraint(columnNames = { "name",
"tenant" }, name = "uk_rollout")) "tenant" }, name = "uk_rollout"))
@@ -61,80 +67,134 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@OneToMany(targetEntity = JpaRolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "rollout") @OneToMany(targetEntity = JpaRolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "rollout")
private List<JpaRolloutGroup> rolloutGroups; private List<JpaRolloutGroup> rolloutGroups = new ArrayList<>();
@Setter
@Getter
@Column(name = "target_filter", length = TargetFilterQuery.QUERY_MAX_SIZE, nullable = false) @Column(name = "target_filter", length = TargetFilterQuery.QUERY_MAX_SIZE, nullable = false)
@Size(min = 1, max = TargetFilterQuery.QUERY_MAX_SIZE) @Size(min = 1, max = TargetFilterQuery.QUERY_MAX_SIZE)
@NotNull @NotNull
private String targetFilterQuery; private String targetFilterQuery;
@Getter
@ManyToOne(fetch = FetchType.LAZY, optional = false) @ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "distribution_set", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) @JoinColumn(name = "distribution_set", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds"))
@NotNull @NotNull
private JpaDistributionSet distributionSet; private JpaDistributionSet distributionSet;
@Setter
@Getter
@Column(name = "status", nullable = false) @Column(name = "status", nullable = false)
@Convert(converter = RolloutStatusConverter.class) @Convert(converter = RolloutStatusConverter.class)
@NotNull @NotNull
private RolloutStatus status = RolloutStatus.CREATING; private RolloutStatus status = RolloutStatus.CREATING;
@Setter
@Getter
@Column(name = "last_check") @Column(name = "last_check")
private long lastCheck; private long lastCheck;
@Setter
@Getter
@Column(name = "action_type", nullable = false) @Column(name = "action_type", nullable = false)
@Convert(converter = JpaAction.ActionTypeConverter.class) @Convert(converter = JpaAction.ActionTypeConverter.class)
@NotNull @NotNull
private ActionType actionType = ActionType.FORCED; private ActionType actionType = ActionType.FORCED;
@Setter
@Getter
@Column(name = "forced_time") @Column(name = "forced_time")
private long forcedTime; private long forcedTime;
@Setter
@Getter
@Column(name = "total_targets") @Column(name = "total_targets")
private long totalTargets; private long totalTargets;
@Setter
@Getter
@Column(name = "rollout_groups_created") @Column(name = "rollout_groups_created")
private int rolloutGroupsCreated; private int rolloutGroupsCreated;
@Setter
@Getter
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@Setter
@Getter
@Column(name = "start_at") @Column(name = "start_at")
private Long startAt; private Long startAt;
@Setter
@Getter
@Column(name = "approval_decided_by") @Column(name = "approval_decided_by")
@Size(min = 1, max = Rollout.APPROVED_BY_MAX_SIZE) @Size(min = 1, max = Rollout.APPROVED_BY_MAX_SIZE)
private String approvalDecidedBy; private String approvalDecidedBy;
@Setter
@Getter
@Column(name = "approval_remark") @Column(name = "approval_remark")
@Size(max = Rollout.APPROVAL_REMARK_MAX_SIZE) @Size(max = Rollout.APPROVAL_REMARK_MAX_SIZE)
private String approvalRemark; private String approvalRemark;
@Setter
@Column(name = "weight") @Column(name = "weight")
@Min(Action.WEIGHT_MIN) @Min(Action.WEIGHT_MIN)
@Max(Action.WEIGHT_MAX) @Max(Action.WEIGHT_MAX)
private Integer weight; private Integer weight;
@Setter
@Column(name = "is_dynamic") // dynamic is reserved keyword in some databases @Column(name = "is_dynamic") // dynamic is reserved keyword in some databases
private Boolean dynamic; private Boolean dynamic;
@Setter
@Column(name = "access_control_context", nullable = true) @Column(name = "access_control_context", nullable = true)
private String accessControlContext; private String accessControlContext;
@Setter
@Transient @Transient
private transient TotalTargetCountStatus totalTargetCountStatus; private transient TotalTargetCountStatus totalTargetCountStatus;
public List<RolloutGroup> getRolloutGroups() { public List<RolloutGroup> getRolloutGroups() {
if (rolloutGroups == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(rolloutGroups); return Collections.unmodifiableList(rolloutGroups);
} }
public long getLastCheck() { // dynamic is null only for old rollouts - could be used for distinguishing old once from the other
return lastCheck;
}
public void setLastCheck(final long lastCheck) {
this.lastCheck = lastCheck;
}
// dynamic is null only for old rollouts - could be used for distinguishing
// old once from the other
public boolean isNewStyleTargetPercent() { public boolean isNewStyleTargetPercent() {
return dynamic != null; return dynamic != null;
} }
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@Override
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets, actionType);
}
return totalTargetCountStatus;
}
@Override
public Optional<Integer> getWeight() {
return Optional.ofNullable(weight);
}
@Override
public boolean isDynamic() {
return Boolean.TRUE.equals(dynamic);
}
public Optional<String> getAccessControlContext() {
return Optional.ofNullable(accessControlContext);
}
@Override @Override
public String toString() { public String toString() {
return "Rollout [ targetFilterQuery=" + targetFilterQuery + ", distributionSet=" + distributionSet + ", status=" return "Rollout [ targetFilterQuery=" + targetFilterQuery + ", distributionSet=" + distributionSet + ", status=" + status +
+ status + ", lastCheck=" + lastCheck + ", getName()=" + getName() + ", getId()=" + getId() + "]"; ", lastCheck=" + lastCheck + ", getName()=" + getName() + ", getId()=" + getId() + "]";
} }
@Override @Override
@@ -160,143 +220,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId())); getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId()));
} }
@Override
public boolean isDeleted() {
return deleted;
}
@Override
public DistributionSet getDistributionSet() {
return distributionSet;
}
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@Override
public String getTargetFilterQuery() {
return targetFilterQuery;
}
public void setTargetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
@Override
public RolloutStatus getStatus() {
return status;
}
public void setStatus(final RolloutStatus status) {
this.status = status;
}
@Override
public ActionType getActionType() {
return actionType;
}
public void setActionType(final ActionType actionType) {
this.actionType = actionType;
}
@Override
public long getForcedTime() {
return forcedTime;
}
@Override
public Long getStartAt() {
return startAt;
}
public void setStartAt(final Long startAt) {
this.startAt = startAt;
}
@Override
public long getTotalTargets() {
return totalTargets;
}
public void setTotalTargets(final long totalTargets) {
this.totalTargets = totalTargets;
}
@Override
public int getRolloutGroupsCreated() {
return rolloutGroupsCreated;
}
public void setRolloutGroupsCreated(final int rolloutGroupsCreated) {
this.rolloutGroupsCreated = rolloutGroupsCreated;
}
@Override
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets, actionType);
}
return totalTargetCountStatus;
}
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
this.totalTargetCountStatus = totalTargetCountStatus;
}
@Override
public String getApprovalDecidedBy() {
return approvalDecidedBy;
}
public void setApprovalDecidedBy(final String approvalDecidedBy) {
this.approvalDecidedBy = approvalDecidedBy;
}
@Override
public String getApprovalRemark() {
return approvalRemark;
}
@Override
public Optional<Integer> getWeight() {
return Optional.ofNullable(weight);
}
public void setWeight(final Integer weight) {
this.weight = weight;
}
@Override
public boolean isDynamic() {
return Boolean.TRUE.equals(dynamic);
}
public void setDynamic(final Boolean dynamic) {
this.dynamic = dynamic;
}
public Optional<String> getAccessControlContext() {
return Optional.ofNullable(accessControlContext);
}
public void setAccessControlContext(final String accessControlContext) {
this.accessControlContext = accessControlContext;
}
public void setApprovalRemark(final String approvalRemark) {
this.approvalRemark = approvalRemark;
}
public void setForcedTime(final long forcedTime) {
this.forcedTime = forcedTime;
}
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Converter @Converter
public static class RolloutStatusConverter extends MapAttributeConverter<RolloutStatus, Integer> { public static class RolloutStatusConverter extends MapAttributeConverter<RolloutStatus, Integer> {

View File

@@ -31,7 +31,9 @@ import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.RolloutGroupDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutGroupDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent;
@@ -44,6 +46,7 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* JPA entity definition of persisting a group of an rollout. * JPA entity definition of persisting a group of an rollout.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor needed for JPA entities.
@Entity @Entity
@Table(name = "sp_rolloutgroup", uniqueConstraints = @UniqueConstraint(columnNames = { "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) @Table(name = "sp_rolloutgroup", uniqueConstraints = @UniqueConstraint(columnNames = { "name", "rollout", "tenant" }, name = "uk_rolloutgroup"))
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
@@ -57,80 +60,97 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rollout", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) @JoinColumn(name = "rollout", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout"))
private JpaRollout rollout; private JpaRollout rollout;
@Setter @Setter
@Getter @Getter
@Column(name = "status", nullable = false) @Column(name = "status", nullable = false)
@Convert(converter = RolloutGroupStatusConverter.class) @Convert(converter = RolloutGroupStatusConverter.class)
private RolloutGroupStatus status = RolloutGroupStatus.CREATING; private RolloutGroupStatus status = RolloutGroupStatus.CREATING;
@OneToMany(mappedBy = "rolloutGroup", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, @OneToMany(mappedBy = "rolloutGroup", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,
CascadeType.REMOVE }, targetEntity = RolloutTargetGroup.class) CascadeType.REMOVE }, targetEntity = RolloutTargetGroup.class)
private List<RolloutTargetGroup> rolloutTargetGroup; private List<RolloutTargetGroup> rolloutTargetGroup;
// No foreign key to avoid to many nested cascades on delete which some DBs cannot handle // No foreign key to avoid to many nested cascades on delete which some DBs cannot handle
@Setter @Setter
@Getter @Getter
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "parent_id") @JoinColumn(name = "parent_id")
private JpaRolloutGroup parent; private JpaRolloutGroup parent;
@Setter @Setter
@Getter @Getter
@Column(name = "is_dynamic") // dynamic is reserved keyword in some databases @Column(name = "is_dynamic") // dynamic is reserved keyword in some databases
private boolean dynamic; private boolean dynamic;
@Setter @Setter
@Getter @Getter
@Column(name = "success_condition", nullable = false) @Column(name = "success_condition", nullable = false)
@NotNull @NotNull
private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD;
@Setter @Setter
@Getter @Getter
@Column(name = "success_condition_exp", length = 512, nullable = false) @Column(name = "success_condition_exp", length = 512, nullable = false)
@Size(max = 512) @Size(max = 512)
@NotNull @NotNull
private String successConditionExp; private String successConditionExp;
@Setter @Setter
@Getter @Getter
@Column(name = "success_action", nullable = false) @Column(name = "success_action", nullable = false)
@NotNull @NotNull
private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP;
@Setter @Setter
@Getter @Getter
@Column(name = "success_action_exp", length = 512) @Column(name = "success_action_exp", length = 512)
@Size(max = 512) @Size(max = 512)
private String successActionExp; private String successActionExp;
@Setter @Setter
@Getter @Getter
@Column(name = "error_condition") @Column(name = "error_condition")
private RolloutGroupErrorCondition errorCondition; private RolloutGroupErrorCondition errorCondition;
@Setter @Setter
@Getter @Getter
@Column(name = "error_condition_exp", length = 512) @Column(name = "error_condition_exp", length = 512)
@Size(max = 512) @Size(max = 512)
private String errorConditionExp; private String errorConditionExp;
@Setter @Setter
@Getter @Getter
@Column(name = "error_action") @Column(name = "error_action")
private RolloutGroupErrorAction errorAction; private RolloutGroupErrorAction errorAction;
@Setter @Setter
@Getter @Getter
@Column(name = "error_action_exp", length = 512) @Column(name = "error_action_exp", length = 512)
@Size(max = 512) @Size(max = 512)
private String errorActionExp; private String errorActionExp;
@Setter @Setter
@Getter @Getter
@Column(name = "total_targets") @Column(name = "total_targets")
private int totalTargets; private int totalTargets;
@Setter @Setter
@Getter @Getter
@Column(name = "target_filter", length = 1024) @Column(name = "target_filter", length = 1024)
@Size(max = 1024) @Size(max = 1024)
private String targetFilterQuery = ""; private String targetFilterQuery = "";
@Setter @Setter
@Getter @Getter
@Column(name = "target_percentage") @Column(name = "target_percentage")
private float targetPercentage = 100; private float targetPercentage = 100;
@Setter @Setter
@Getter @Getter
@Column(name = "confirmation_required") @Column(name = "confirmation_required")
private boolean confirmationRequired; private boolean confirmationRequired;
@Setter @Setter
@Transient @Transient
private transient TotalTargetCountStatus totalTargetCountStatus; private transient TotalTargetCountStatus totalTargetCountStatus;
@@ -150,14 +170,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return totalTargetCountStatus; return totalTargetCountStatus;
} }
public List<RolloutTargetGroup> getRolloutTargetGroup() {
if (rolloutTargetGroup == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(rolloutTargetGroup);
}
@Override @Override
public String toString() { public String toString() {
return "RolloutGroup [" + return "RolloutGroup [" +

View File

@@ -48,10 +48,10 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* Base Software Module that is supported by OS level provisioning mechanism on * Base Software Module that is supported by OS level provisioning mechanism on the edge controller, e.g. OS, JVM, AgentHub.
* the edge controller, e.g. OS, JVM, AgentHub.
*/ */
@NoArgsConstructor // Default constructor for JPA @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter @Getter
@ToString(callSuper = true) @ToString(callSuper = true)
@Entity @Entity
@@ -73,12 +73,14 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@Setter @Setter
@ManyToOne @ManyToOne
@JoinColumn(name = "module_type", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_module_type")) @JoinColumn(name = "module_type", nullable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_module_type"))
@NotNull @NotNull
private JpaSoftwareModuleType type; private JpaSoftwareModuleType type;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "softwareModule", cascade = { CascadeType.PERSIST, @OneToMany(fetch = FetchType.LAZY, mappedBy = "softwareModule",
CascadeType.REMOVE }, targetEntity = JpaArtifact.class, orphanRemoval = true) cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE },
targetEntity = JpaArtifact.class, orphanRemoval = true)
private List<JpaArtifact> artifacts; private List<JpaArtifact> artifacts;
@Setter @Setter
@@ -91,8 +93,9 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
private boolean encrypted; private boolean encrypted;
@ToString.Exclude @ToString.Exclude
@OneToMany(mappedBy = "softwareModule", fetch = FetchType.LAZY, cascade = { @OneToMany(mappedBy = "softwareModule", fetch = FetchType.LAZY,
CascadeType.REMOVE }, targetEntity = JpaSoftwareModuleMetadata.class) cascade = { CascadeType.REMOVE },
targetEntity = JpaSoftwareModuleMetadata.class)
private List<JpaSoftwareModuleMetadata> metadata; private List<JpaSoftwareModuleMetadata> metadata;
@Column(name = "locked") @Column(name = "locked")
@@ -146,9 +149,6 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
} }
} }
/**
* @param artifact is removed from the assigned {@link Artifact}s.
*/
public void removeArtifact(final Artifact artifact) { public void removeArtifact(final Artifact artifact) {
if (isLocked()) { if (isLocked()) {
throw new LockedException(JpaSoftwareModule.class, getId(), "REMOVE_ARTIFACT"); throw new LockedException(JpaSoftwareModule.class, getId(), "REMOVE_ARTIFACT");

View File

@@ -22,12 +22,21 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
/** /**
* Metadata for {@link SoftwareModule}. * Metadata for {@link SoftwareModule}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@IdClass(SwMetadataCompositeKey.class) @IdClass(SwMetadataCompositeKey.class)
@Entity @Entity
@Table(name = "sp_sw_metadata") @Table(name = "sp_sw_metadata")
@@ -44,73 +53,19 @@ public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements So
@Column(name = "target_visible") @Column(name = "target_visible")
private boolean targetVisible; private boolean targetVisible;
public JpaSoftwareModuleMetadata() {
// default public constructor for JPA
}
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) { public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) {
super(key, value); super(key, value);
this.softwareModule = (JpaSoftwareModule) softwareModule; this.softwareModule = (JpaSoftwareModule) softwareModule;
} }
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value, public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value, final boolean targetVisible) {
final boolean targetVisible) {
super(key, value); super(key, value);
this.softwareModule = (JpaSoftwareModule) softwareModule; this.softwareModule = (JpaSoftwareModule) softwareModule;
this.targetVisible = targetVisible; this.targetVisible = targetVisible;
} }
public JpaSoftwareModuleMetadata(final String key, final String value, final boolean targetVisible) {
super(key, value);
this.targetVisible = targetVisible;
}
public SwMetadataCompositeKey getId() { public SwMetadataCompositeKey getId() {
return new SwMetadataCompositeKey(softwareModule.getId(), getKey()); return new SwMetadataCompositeKey(softwareModule.getId(), getKey());
} }
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
public void setSoftwareModule(final JpaSoftwareModule softwareModule) {
this.softwareModule = softwareModule;
}
@Override
public boolean isTargetVisible() {
return targetVisible;
}
public void setTargetVisible(final boolean targetVisible) {
this.targetVisible = targetVisible;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((softwareModule == null) ? 0 : softwareModule.hashCode());
return result;
}
@Override
// exception squid:S2259 - obj is checked for null in super
@SuppressWarnings("squid:S2259")
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
final JpaSoftwareModuleMetadata other = (JpaSoftwareModuleMetadata) obj;
if (softwareModule == null) {
if (other.softwareModule != null) {
return false;
}
} else if (!softwareModule.equals(other.softwareModule)) {
return false;
}
return true;
}
} }

View File

@@ -18,6 +18,10 @@ import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.SoftwareModuleTypeDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.SoftwareModuleTypeDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeUpdatedEvent;
@@ -25,8 +29,9 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* Type of a software modules. * Type of software modules.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Entity @Entity
@Table(name = "sp_software_module_type", indexes = { @Table(name = "sp_software_module_type", indexes = {
@Index(name = "sp_idx_software_module_type_01", columnList = "tenant,deleted"), @Index(name = "sp_idx_software_module_type_01", columnList = "tenant,deleted"),
@@ -40,66 +45,25 @@ public class JpaSoftwareModuleType extends AbstractJpaTypeEntity implements Soft
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Getter
@Column(name = "max_ds_assignments", nullable = false) @Column(name = "max_ds_assignments", nullable = false)
@Min(1) @Min(1)
private int maxAssignments; private int maxAssignments;
@Setter
@Getter
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
/** public JpaSoftwareModuleType(final String key, final String name, final String description, final int maxAssignments) {
* Constructor.
*
* @param key of the type
* @param name of the type
* @param description of the type
* @param maxAssignments assignments to a DS
*/
public JpaSoftwareModuleType(final String key, final String name, final String description,
final int maxAssignments) {
this(key, name, description, maxAssignments, null); this(key, name, description, maxAssignments, null);
} }
/** public JpaSoftwareModuleType(final String key, final String name, final String description, final int maxAssignments, final String colour) {
* Constructor.
*
* @param key of the type
* @param name of the type
* @param description of the type
* @param maxAssignments assignments to a DS
* @param colour of the type. It will be null by default
*/
public JpaSoftwareModuleType(final String key, final String name, final String description,
final int maxAssignments, final String colour) {
super(name, description, key, colour); super(name, description, key, colour);
this.maxAssignments = maxAssignments; this.maxAssignments = maxAssignments;
} }
/**
* Default Constructor for JPA.
*/
public JpaSoftwareModuleType() {
// Default Constructor for JPA.
}
@Override
public int getMaxAssignments() {
return maxAssignments;
}
public void setMaxAssignments(final int maxAssignments) {
this.maxAssignments = maxAssignments;
}
@Override
public boolean isDeleted() {
return deleted;
}
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Override @Override
public String toString() { public String toString() {
return "SoftwareModuleType [key=" + getKey() + ", getName()=" + getName() + ", getId()=" + getId() + "]"; return "SoftwareModuleType [key=" + getKey() + ", getName()=" + getName() + ", getId()=" + getId() + "]";

View File

@@ -12,6 +12,4 @@ package org.eclipse.hawkbit.repository.jpa.model;
import org.eclipse.hawkbit.repository.model.Statistic; import org.eclipse.hawkbit.repository.model.Statistic;
public interface JpaStatistic extends Statistic { public interface JpaStatistic extends Statistic {}
}

View File

@@ -15,12 +15,18 @@ import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Tag;
/** /**
* A Tag can be used as describing and organizational meta information for any * A Tag can be used as describing and organizational meta information for any kind of entity.
* kind of entity.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter
@MappedSuperclass @MappedSuperclass
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
@@ -33,31 +39,11 @@ public class JpaTag extends AbstractJpaNamedEntity implements Tag {
@Size(max = Tag.COLOUR_MAX_SIZE) @Size(max = Tag.COLOUR_MAX_SIZE)
private String colour; private String colour;
protected JpaTag() {
// Default constructor needed for JPA entities
}
/**
* Public constructor.
*
* @param name of the {@link Tag}
* @param description of the {@link Tag}
* @param colour of tag in UI
*/
public JpaTag(final String name, final String description, final String colour) { public JpaTag(final String name, final String description, final String colour) {
super(name, description); super(name, description);
this.colour = colour; this.colour = colour;
} }
@Override
public String getColour() {
return colour;
}
public void setColour(final String colour) {
this.colour = colour;
}
@Override @Override
public String toString() { public String toString() {
return "Tag [getOptLockRevision()=" + getOptLockRevision() + ", getId()=" + getId() + "]"; return "Tag [getOptLockRevision()=" + getOptLockRevision() + ", getId()=" + getId() + "]";

View File

@@ -74,7 +74,7 @@ import org.eclipse.persistence.queries.UpdateObjectQuery;
/** /**
* JPA implementation of {@link Target}. * JPA implementation of {@link Target}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // empty constructor for JPA. @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Entity @Entity
@Table(name = "sp_target", @Table(name = "sp_target",
indexes = { indexes = {

View File

@@ -25,6 +25,10 @@ import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.TargetFilterQueryDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetFilterQueryDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryUpdatedEvent;
@@ -37,6 +41,9 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* Stored target filter. * Stored target filter.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter
@Entity @Entity
@Table( @Table(
name = "sp_target_filter_query", name = "sp_target_filter_query",
@@ -78,20 +85,6 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
@Column(name = "access_control_context", nullable = true) @Column(name = "access_control_context", nullable = true)
private String accessControlContext; private String accessControlContext;
public JpaTargetFilterQuery() {
// Default constructor for JPA.
}
/**
* Construct a Target filter query with auto assign distribution set
*
* @param name of the {@link TargetFilterQuery}.
* @param query of the {@link TargetFilterQuery}.
* @param autoAssignDistributionSet of the {@link TargetFilterQuery}.
* @param autoAssignActionType of the {@link TargetFilterQuery}.
* @param autoAssignWeight of the {@link TargetFilterQuery}.
* @param confirmationRequired of the {@link TargetFilterQuery}.
*/
public JpaTargetFilterQuery(final String name, final String query, final DistributionSet autoAssignDistributionSet, public JpaTargetFilterQuery(final String name, final String query, final DistributionSet autoAssignDistributionSet,
final ActionType autoAssignActionType, final Integer autoAssignWeight, final boolean confirmationRequired) { final ActionType autoAssignActionType, final Integer autoAssignWeight, final boolean confirmationRequired) {
this.name = name; this.name = name;
@@ -102,38 +95,6 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
this.confirmationRequired = confirmationRequired; this.confirmationRequired = confirmationRequired;
} }
@Override
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String getQuery() {
return query;
}
public void setQuery(final String query) {
this.query = query;
}
@Override
public DistributionSet getAutoAssignDistributionSet() {
return autoAssignDistributionSet;
}
public void setAutoAssignDistributionSet(final JpaDistributionSet distributionSet) {
this.autoAssignDistributionSet = distributionSet;
}
@Override
public ActionType getAutoAssignActionType() {
return autoAssignActionType;
}
public void setAutoAssignActionType(final ActionType actionType) { public void setAutoAssignActionType(final ActionType actionType) {
if (actionType == ActionType.TIMEFORCED) { if (actionType == ActionType.TIMEFORCED) {
throw new IllegalArgumentException("TIMEFORCED is not permitted in autoAssignment"); throw new IllegalArgumentException("TIMEFORCED is not permitted in autoAssignment");
@@ -146,35 +107,11 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
return Optional.ofNullable(autoAssignWeight); return Optional.ofNullable(autoAssignWeight);
} }
public void setAutoAssignWeight(final Integer weight) {
this.autoAssignWeight = weight;
}
public String getAutoAssignInitiatedBy() {
return autoAssignInitiatedBy;
}
public void setAutoAssignInitiatedBy(final String autoAssignInitiatedBy) {
this.autoAssignInitiatedBy = autoAssignInitiatedBy;
}
@Override @Override
public boolean isConfirmationRequired() {
return confirmationRequired;
}
public void setConfirmationRequired(final boolean confirmationRequired) {
this.confirmationRequired = confirmationRequired;
}
public Optional<String> getAccessControlContext() { public Optional<String> getAccessControlContext() {
return Optional.ofNullable(accessControlContext); return Optional.ofNullable(accessControlContext);
} }
public void setAccessControlContext(final String accessControlContext) {
this.accessControlContext = accessControlContext;
}
@Override @Override
public void fireCreateEvent() { public void fireCreateEvent() {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
@@ -192,5 +129,4 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new TargetFilterQueryDeletedEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new TargetFilterQueryDeletedEvent(
getTenant(), getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId())); getTenant(), getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId()));
} }
} }

View File

@@ -21,12 +21,19 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetMetadata; import org.eclipse.hawkbit.repository.model.TargetMetadata;
/** /**
* Meta data for {@link Target}. * Meta data for {@link Target}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter
@IdClass(TargetMetadataCompositeKey.class) @IdClass(TargetMetadataCompositeKey.class)
@Entity @Entity
@Table(name = "sp_target_metadata") @Table(name = "sp_target_metadata")
@@ -40,15 +47,11 @@ public class JpaTargetMetadata extends AbstractJpaMetaData implements TargetMeta
@JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_target")) @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_target"))
private JpaTarget target; private JpaTarget target;
public JpaTargetMetadata() {
// default public constructor for JPA
}
/** /**
* Creates a single metadata entry with the given key and value. * Creates a single metadata entry with the given key and value.
* *
* @param key of the meta data entry * @param key of the meta-data entry
* @param value of the meta data entry * @param value of the meta-data entry
*/ */
public JpaTargetMetadata(final String key, final String value) { public JpaTargetMetadata(final String key, final String value) {
super(key, value); super(key, value);
@@ -58,9 +61,9 @@ public class JpaTargetMetadata extends AbstractJpaMetaData implements TargetMeta
* Creates a single metadata entry with the given key and value for the * Creates a single metadata entry with the given key and value for the
* given {@link Target}. * given {@link Target}.
* *
* @param key of the meta data entry * @param key of the meta-data entry
* @param value of the meta data entry * @param value of the meta-data entry
* @param target the meta data entry is associated with * @param target the meta-data entry is associated with
*/ */
public JpaTargetMetadata(final String key, final String value, final Target target) { public JpaTargetMetadata(final String key, final String value, final Target target) {
super(key, value); super(key, value);
@@ -71,15 +74,6 @@ public class JpaTargetMetadata extends AbstractJpaMetaData implements TargetMeta
return new TargetMetadataCompositeKey(target.getId(), getKey()); return new TargetMetadataCompositeKey(target.getId(), getKey());
} }
@Override
public Target getTarget() {
return target;
}
public void setTarget(final Target target) {
this.target = (JpaTarget) target;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@@ -97,12 +91,9 @@ public class JpaTargetMetadata extends AbstractJpaMetaData implements TargetMeta
} }
final JpaTargetMetadata other = (JpaTargetMetadata) obj; final JpaTargetMetadata other = (JpaTargetMetadata) obj;
if (target == null) { if (target == null) {
if (other.target != null) { return other.target == null;
return false; } else {
return target.equals(other.target);
} }
} else if (!target.equals(other.target)) {
return false;
}
return true;
} }
} }

View File

@@ -16,6 +16,7 @@ import jakarta.persistence.Index;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.ToString; import lombok.ToString;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
@@ -27,7 +28,7 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* A {@link TargetTag} is used to describe Target attributes and use them also for filtering the target list. * A {@link TargetTag} is used to describe Target attributes and use them also for filtering the target list.
*/ */
@NoArgsConstructor // Default constructor for JPA. @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@ToString(callSuper = true) @ToString(callSuper = true)
@Entity @Entity
@Table(name = "sp_target_tag", indexes = { @Index(name = "sp_idx_target_tag_prim", columnList = "tenant,id"), @Table(name = "sp_target_tag", indexes = { @Index(name = "sp_idx_target_tag_prim", columnList = "tenant,id"),

View File

@@ -24,6 +24,7 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.ToString; import lombok.ToString;
import org.eclipse.hawkbit.repository.event.remote.TargetTypeDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetTypeDeletedEvent;
@@ -35,10 +36,9 @@ import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* A target type defines which distribution set types can or have to be * A target type defines which distribution set types can or have to be {@link Target}.
* {@link Target}.
*/ */
@NoArgsConstructor // default public constructor for JPA @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@ToString(callSuper = true) @ToString(callSuper = true)
@Entity @Entity
@Table(name = "sp_target_type", indexes = { @Table(name = "sp_target_type", indexes = {
@@ -60,7 +60,7 @@ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType,
@JoinColumn( @JoinColumn(
name = "distribution_set_type", nullable = false, insertable = false, updatable = false, name = "distribution_set_type", nullable = false, insertable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_type_relation_ds_type")) }) foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_type_relation_ds_type")) })
private Set<DistributionSetType> distributionSetTypes; private Set<DistributionSetType> distributionSetTypes = new HashSet<>();
public JpaTargetType(final String key, final String name, final String description, final String colour) { public JpaTargetType(final String key, final String name, final String description, final String colour) {
super(name, description, key, colour); super(name, description, key, colour);
@@ -73,21 +73,12 @@ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType,
* @return Target type * @return Target type
*/ */
public JpaTargetType addCompatibleDistributionSetType(final DistributionSetType dsSetType) { public JpaTargetType addCompatibleDistributionSetType(final DistributionSetType dsSetType) {
if (distributionSetTypes == null) {
distributionSetTypes = new HashSet<>();
}
distributionSetTypes.add(dsSetType); distributionSetTypes.add(dsSetType);
return this; return this;
} }
@Override @Override
public Set<DistributionSetType> getCompatibleDistributionSetTypes() { public Set<DistributionSetType> getCompatibleDistributionSetTypes() {
if (distributionSetTypes == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(distributionSetTypes); return Collections.unmodifiableSet(distributionSetTypes);
} }
@@ -98,15 +89,10 @@ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType,
* @return Target type * @return Target type
*/ */
public JpaTargetType removeDistributionSetType(final Long dsTypeId) { public JpaTargetType removeDistributionSetType(final Long dsTypeId) {
if (distributionSetTypes == null) {
return this;
}
distributionSetTypes.stream() distributionSetTypes.stream()
.filter(element -> element.getId().equals(dsTypeId)) .filter(element -> element.getId().equals(dsTypeId))
.findAny() .findAny()
.ifPresent(distributionSetTypes::remove); .ifPresent(distributionSetTypes::remove);
return this; return this;
} }

View File

@@ -19,6 +19,10 @@ import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.event.remote.TenantConfigurationDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TenantConfigurationDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent;
@@ -28,6 +32,9 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
/** /**
* A JPA entity which stores the tenant specific configuration. * A JPA entity which stores the tenant specific configuration.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter
@Entity @Entity
@Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key", @Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key",
"tenant" }, name = "uk_tenant_key")) "tenant" }, name = "uk_tenant_key"))
@@ -49,39 +56,9 @@ public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity imp
@NotNull @NotNull
private String value; private String value;
/**
* JPA default constructor.
*/
public JpaTenantConfiguration() {
// JPA default constructor.
}
/**
* @param key the key of this configuration
* @param value the value of this configuration
*/
public JpaTenantConfiguration(final String key, final String value) { public JpaTenantConfiguration(final String key, final String value) {
this.key = key; this.key = key;
this.value = value; this.value = value;
}
@Override
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
@Override
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
} }
@Override @Override

View File

@@ -25,6 +25,10 @@ import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.TenantMetaData;
@@ -36,6 +40,9 @@ import org.eclipse.hawkbit.repository.model.TenantMetaData;
* *
* Entities owned by the tenant are based on {@link TenantAwareBaseEntity}. * Entities owned by the tenant are based on {@link TenantAwareBaseEntity}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Setter
@Getter
@Table(name = "sp_tenant", indexes = { @Table(name = "sp_tenant", indexes = {
@Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = { @Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") }) @UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") })
@@ -56,39 +63,8 @@ public class JpaTenantMetaData extends AbstractJpaBaseEntity implements TenantMe
@JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type")) @JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type"))
private JpaDistributionSetType defaultDsType; private JpaDistributionSetType defaultDsType;
/**
* Default constructor needed for JPA entities.
*/
public JpaTenantMetaData() {
// Default constructor needed for JPA entities.
}
/**
* Standard constructor.
*
* @param defaultDsType of this tenant
* @param tenant
*/
public JpaTenantMetaData(final DistributionSetType defaultDsType, final String tenant) { public JpaTenantMetaData(final DistributionSetType defaultDsType, final String tenant) {
this.defaultDsType = (JpaDistributionSetType) defaultDsType; this.defaultDsType = (JpaDistributionSetType) defaultDsType;
this.tenant = tenant; this.tenant = tenant;
} }
@Override
public DistributionSetType getDefaultDsType() {
return defaultDsType;
}
public void setDefaultDsType(final JpaDistributionSetType defaultDsType) {
this.defaultDsType = defaultDsType;
}
@Override
public String getTenant() {
return tenant;
}
public void setTenant(final String tenant) {
this.tenant = tenant;
}
} }

View File

@@ -34,7 +34,7 @@ import org.eclipse.hawkbit.repository.model.Target;
/** /**
* Entity with JPA annotation to store the information which {@link Target} is in a specific {@link RolloutGroup}. * Entity with JPA annotation to store the information which {@link Target} is in a specific {@link RolloutGroup}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // JPA constructor @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@IdClass(RolloutTargetGroupId.class) @IdClass(RolloutTargetGroupId.class)
@Entity @Entity
@Table(name = "sp_rollouttargetgroup") @Table(name = "sp_rollouttargetgroup")

View File

@@ -12,12 +12,17 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
/** /**
* Combined unique key of the table {@link RolloutTargetGroup}. * Combined unique key of the table {@link RolloutTargetGroup}.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Getter
public class RolloutTargetGroupId implements Serializable { public class RolloutTargetGroupId implements Serializable {
@Serial @Serial
@@ -26,13 +31,6 @@ public class RolloutTargetGroupId implements Serializable {
private Long rolloutGroup; private Long rolloutGroup;
private Long target; private Long target;
/**
* default constructor necessary for JPA.
*/
public RolloutTargetGroupId() {
// default constructor necessary for JPA, empty.
}
/** /**
* Constructor. * Constructor.
* *
@@ -43,12 +41,4 @@ public class RolloutTargetGroupId implements Serializable {
this.rolloutGroup = rolloutGroup.getId(); this.rolloutGroup = rolloutGroup.getId();
this.target = target.getId(); this.target = target.getId();
} }
public Long getRolloutGroup() {
return rolloutGroup;
}
public Long getTarget() {
return target;
}
} }

View File

@@ -12,13 +12,15 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* The Software Module meta-data composite key which contains the meta-data key * The Software Module meta-data composite key which contains the meta-data key and the ID of the software module itself.
* and the ID of the software module itself.
*/ */
@NoArgsConstructor // Default constructor for JPA @NoArgsConstructor(access = AccessLevel.PUBLIC) // Default constructor for JPA
@Data
public final class SwMetadataCompositeKey implements Serializable { public final class SwMetadataCompositeKey implements Serializable {
@Serial @Serial
@@ -35,72 +37,4 @@ public final class SwMetadataCompositeKey implements Serializable {
this.softwareModule = moduleId; this.softwareModule = moduleId;
this.key = key; this.key = key;
} }
/**
* @return the key
*/
public String getKey() {
return key;
}
/**
* @param key the key to set
*/
public void setKey(final String key) {
this.key = key;
}
/**
* @return the softwareModule
*/
public Long getSoftwareModule() {
return softwareModule;
}
/**
* @param softwareModule the softwareModule to set
*/
public void setSoftwareModule(final Long softwareModule) {
this.softwareModule = softwareModule;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (key == null ? 0 : key.hashCode());
result = prime * result + (softwareModule == null ? 0 : softwareModule.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SwMetadataCompositeKey other = (SwMetadataCompositeKey) obj;
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
if (softwareModule == null) {
if (other.softwareModule != null) {
return false;
}
} else if (!softwareModule.equals(other.softwareModule)) {
return false;
}
return true;
}
} }

View File

@@ -13,12 +13,14 @@ import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* The Target Metadata composite key which contains the meta-data key and the ID of the Target itself. * The Target Metadata composite key which contains the meta-data key and the ID of the Target itself.
*/ */
@NoArgsConstructor // Default constructor for JPA @NoArgsConstructor // Default constructor for JPA
@Data
public final class TargetMetadataCompositeKey implements Serializable { public final class TargetMetadataCompositeKey implements Serializable {
@Serial @Serial
@@ -35,54 +37,4 @@ public final class TargetMetadataCompositeKey implements Serializable {
this.target = target; this.target = target;
this.key = key; this.key = key;
} }
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
public Long getTargetId() {
return target;
}
public void setTargetId(final Long target) {
this.target = target;
}
@Override
public int hashCode() {
return Objects.hash(target, key);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TargetMetadataCompositeKey other = (TargetMetadataCompositeKey) obj;
if (target == null) {
if (other.target != null) {
return false;
}
} else if (!target.equals(other.target)) {
return false;
}
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
return true;
}
} }

View File

@@ -312,8 +312,11 @@ public class TestdataFactory {
.description(randomDescriptionLong()).vendor(prefix + " vendor Limited Inc, California")); .description(randomDescriptionLong()).vendor(prefix + " vendor Limited Inc, California"));
return distributionSetManagement.create( return distributionSetManagement.create(
entityFactory.distributionSet().create().name(prefix != null && prefix.length() > 0 ? prefix : "DS") entityFactory.distributionSet().create()
.version(version).description(randomDescriptionShort()).type(findOrCreateDefaultTestDsType()) .type(findOrCreateDefaultTestDsType())
.name(prefix == null || prefix.isEmpty() ? "DS" : prefix)
.version(version)
.description(randomDescriptionShort())
.modules(Arrays.asList(osMod.getId(), runtimeMod.getId(), appMod.getId())) .modules(Arrays.asList(osMod.getId(), runtimeMod.getId(), appMod.getId()))
.requiredMigrationStep(isRequiredMigrationStep)); .requiredMigrationStep(isRequiredMigrationStep));
} }