From 2a476d1268c38e657c8a5b51828c00b86295774d Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Fri, 6 Dec 2024 13:03:48 +0200 Subject: [PATCH] Small JPA improvements & test code style (#2122) Signed-off-by: Avgustin Marinov --- .../repository/model/TenantMetaData.java | 9 +- .../management/JpaControllerManagement.java | 4 +- .../JpaDistributionSetManagement.java | 4 +- .../jpa/management/JpaSystemManagement.java | 7 +- .../jpa/management/JpaTargetManagement.java | 8 +- .../jpa/model/AbstractJpaBaseEntity.java | 18 +- .../AbstractJpaTenantAwareBaseEntity.java | 7 +- .../repository/jpa/model/JpaAction.java | 87 +++----- .../repository/jpa/model/JpaTarget.java | 2 +- .../jpa/repository/BaseEntityRepository.java | 32 ++- .../specifications/TargetSpecifications.java | 20 +- .../management/ControllerManagementTest.java | 61 +++--- .../management/DeploymentManagementTest.java | 202 +++++++----------- ...ributionSetInvalidationManagementTest.java | 3 +- .../DistributionSetManagementTest.java | 95 ++++---- .../repository/test/util/TestdataFactory.java | 4 +- .../security/SpringSecurityAuditorAware.java | 4 + 17 files changed, 243 insertions(+), 324 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index f4ef89266..7c9464bb2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -14,14 +14,7 @@ package org.eclipse.hawkbit.repository.model; */ public interface TenantMetaData extends BaseEntity { - /** - * @return default {@link DistributionSetType}. - */ DistributionSetType getDefaultDsType(); - /** - * @return tenant name - */ String getTenant(); - -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java index bcfbffab6..0ffbcd6bd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java @@ -553,7 +553,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont @Override public void deleteExistingTarget(@NotEmpty final String controllerId) { - targetRepository.deleteById(targetRepository.getByControllerId(controllerId).getId()); + final JpaTarget target = targetRepository.getByControllerId(controllerId); + targetRepository.deleteById(target.getId()); + entityManager.flush(); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java index d8997c024..b66449e6d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java @@ -421,7 +421,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public Optional getWithDetails(final long id) { - return distributionSetRepository.findById(id).map(DistributionSet.class::cast); + return distributionSetRepository + .findOne(distributionSetRepository.byIdSpec(id), JpaDistributionSet_.GRAPH_DISTRIBUTION_SET_DETAIL) + .map(DistributionSet.class::cast); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSystemManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSystemManagement.java index 56dfd7b69..b0efbf12e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSystemManagement.java @@ -128,12 +128,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst * @param properties properties to get the underlying database */ public JpaSystemManagement(final JpaProperties properties) { - final String isDeleted = isPostgreSql(properties) ? "false" : "0"; - countArtifactQuery = "SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " - + isDeleted; - countSoftwareModulesQuery = "select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " - + isDeleted; + countArtifactQuery = "SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " + isDeleted; + countSoftwareModulesQuery = "select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " + isDeleted; } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java index 9ebaa042c..43235e82c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java @@ -198,8 +198,8 @@ public class JpaTargetManagement implements TargetManagement { @Override public long countByRsqlAndCompatible(final String targetFilterQuery, final Long distributionSetIdTypeId) { - final List> specList = List.of(RSQLUtility.buildRsqlSpecification(targetFilterQuery, - TargetFields.class, virtualPropertyReplacer, database), + final List> specList = List.of(RSQLUtility.buildRsqlSpecification( + targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database), TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId)); return JpaManagementHelper.countBySpec(targetRepository, specList); @@ -207,8 +207,8 @@ public class JpaTargetManagement implements TargetManagement { @Override public long countByRsqlAndCompatibleAndUpdatable(String targetFilterQuery, Long distributionSetIdTypeId) { - final List> specList = List.of(RSQLUtility.buildRsqlSpecification(targetFilterQuery, - TargetFields.class, virtualPropertyReplacer, database), + final List> specList = List.of(RSQLUtility.buildRsqlSpecification( + targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database), TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId)); return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList)); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 2753f2bf1..90bb9ede7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -58,6 +58,12 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @Column(name = "id") private Long id; + @Version + @Column(name = "optlock_revision") + private int optLockRevision; + + // Audit fields. use property access to ensure that setters will be called and checked for modification + // (touch implementation depends on setLastModifiedAt(0). @Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH) private String createdBy; @Column(name = "created_at", updatable = false, nullable = false) @@ -67,10 +73,6 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @Column(name = "last_modified_at", nullable = false) private long lastModifiedAt; - @Version - @Column(name = "optlock_revision") - private int optLockRevision; - @CreatedBy public void setCreatedBy(final String createdBy) { if (isController()) { @@ -170,14 +172,16 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { return false; } final AbstractJpaBaseEntity other = (AbstractJpaBaseEntity) obj; + final Long id = getId(); + final Long otherId = other.getId(); if (id == null) { - if (other.id != null) { + if (otherId != null) { return false; } - } else if (!id.equals(other.id)) { + } else if (!id.equals(otherId)) { return false; } - return optLockRevision == other.optLockRevision; + return getOptLockRevision() == other.getOptLockRevision(); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index b6b7e24d7..e40782226 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serial; +import java.util.Objects; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; @@ -76,11 +77,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn return false; } final AbstractJpaTenantAwareBaseEntity other = (AbstractJpaTenantAwareBaseEntity) obj; - if (tenant == null) { - return other.tenant == null; - } else { - return tenant.equals(other.tenant); - } + return Objects.equals(getTenant(), other.getTenant()); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 87f59e9ec..5acadac92 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serial; import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -36,11 +37,13 @@ import jakarta.persistence.NamedEntityGraph; import jakarta.persistence.NamedEntityGraphs; import jakarta.persistence.NamedSubgraph; import jakarta.persistence.OneToMany; +import jakarta.persistence.PostUpdate; import jakarta.persistence.Table; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; +import lombok.Setter; import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper; import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent; @@ -96,42 +99,65 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio @Column(name = "active") private boolean active; + @Column(name = "action_type", nullable = false) @Convert(converter = ActionTypeConverter.class) @NotNull private ActionType actionType; + @Column(name = "forced_time") private long forcedTime; + + @Setter @Column(name = "weight") @Min(Action.WEIGHT_MIN) @Max(Action.WEIGHT_MAX) private Integer weight; + @Column(name = "status", nullable = false) @Convert(converter = StatusConverter.class) @NotNull private Status status; + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }) - private List actionStatus; + private List actionStatus = new ArrayList<>(); + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( name = "rolloutgroup", updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) private JpaRolloutGroup rolloutGroup; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( name = "rollout", updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) private JpaRollout rollout; + + // a cron expression to be used for scheduling. + @Setter @Column(name = "maintenance_cron_schedule", updatable = false, length = Action.MAINTENANCE_WINDOW_SCHEDULE_LENGTH) private String maintenanceWindowSchedule; + + // the duration of an available maintenance schedule indexes HH:mm:ss format + @Setter @Column(name = "maintenance_duration", updatable = false, length = Action.MAINTENANCE_WINDOW_DURATION_LENGTH) private String maintenanceWindowDuration; + + // the time zone specified as +/-hh:mm offset from UTC for example +02:00 for CET summer time and +00:00 for UTC. The + // start time of a maintenance window calculated based on the cron expression is relative to this time zone. + @Setter @Column(name = "maintenance_time_zone", updatable = false, length = Action.MAINTENANCE_WINDOW_TIMEZONE_LENGTH) private String maintenanceWindowTimeZone; + @Column(name = "external_ref", length = Action.EXTERNAL_REF_MAX_LENGTH) private String externalRef; + + @Setter @Column(name = "initiated_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH) private String initiatedBy; + + @Setter @Column(name = "last_action_status_code", nullable = true, updatable = true) private Integer lastActionStatusCode; @@ -194,10 +220,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio return Optional.ofNullable(weight); } - public void setWeight(final Integer weight) { - this.weight = weight; - } - @Override public RolloutGroup getRolloutGroup() { return rolloutGroup; @@ -221,47 +243,16 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio return maintenanceWindowSchedule; } - /** - * Sets the maintenance schedule. - * - * @param maintenanceWindowSchedule is a cron expression to be used for scheduling. - */ - public void setMaintenanceWindowSchedule(final String maintenanceWindowSchedule) { - this.maintenanceWindowSchedule = maintenanceWindowSchedule; - } - @Override public String getMaintenanceWindowDuration() { return maintenanceWindowDuration; } - /** - * Sets the maintenance window duration. - * - * @param maintenanceWindowDuration is the duration of an available maintenance schedule in - * HH:mm:ss format. - */ - public void setMaintenanceWindowDuration(final String maintenanceWindowDuration) { - this.maintenanceWindowDuration = maintenanceWindowDuration; - } - @Override public String getMaintenanceWindowTimeZone() { return maintenanceWindowTimeZone; } - /** - * Sets the time zone to be used for maintenance window. - * - * @param maintenanceWindowTimeZone is the time zone specified as +/-hh:mm offset from UTC for - * example +02:00 for CET summer time and +00:00 for UTC. The - * start time of a maintenance window calculated based on the - * cron expression is relative to this time zone. - */ - public void setMaintenanceWindowTimeZone(final String maintenanceWindowTimeZone) { - this.maintenanceWindowTimeZone = maintenanceWindowTimeZone; - } - @Override public String getExternalRef() { return externalRef; @@ -277,20 +268,15 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio return initiatedBy; } - public void setInitiatedBy(final String initiatedBy) { - this.initiatedBy = initiatedBy; - } - @Override public Optional getLastActionStatusCode() { return Optional.ofNullable(lastActionStatusCode); } - @Override public Optional getMaintenanceWindowStartTime() { - return MaintenanceScheduleHelper.getNextMaintenanceWindow(maintenanceWindowSchedule, maintenanceWindowDuration, - maintenanceWindowTimeZone); + return MaintenanceScheduleHelper.getNextMaintenanceWindow( + maintenanceWindowSchedule, maintenanceWindowDuration, maintenanceWindowTimeZone); } @Override @@ -330,24 +316,15 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio return status == Status.WAIT_FOR_CONFIRMATION; } - public void setLastActionStatusCode(final Integer lastActionStatusCode) { - this.lastActionStatusCode = lastActionStatusCode; - } - public List getActionStatus() { - if (actionStatus == null) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(actionStatus); } @Override public String toString() { - return "JpaAction [distributionSet=" + distributionSet.getId() + ", version=" + getOptLockRevision() + ", id=" - + getId() + ", actionType=" + getActionType() + ", weight=" + getWeight() + ", isActive=" + isActive() - + ", createdAt=" + getCreatedAt() + ", lastModifiedAt=" + getLastModifiedAt() + ", status=" - + getStatus().name() + "]"; + return "JpaAction [distributionSet=" + distributionSet.getId() + ", version=" + getOptLockRevision() + ", id=" + getId() + + ", actionType=" + getActionType() + ", weight=" + getWeight() + ", isActive=" + isActive() + + ", createdAt=" + getCreatedAt() + ", lastModifiedAt=" + getLastModifiedAt() + ", status=" + getStatus().name() + "]"; } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 31eaefa87..f66239273 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -132,7 +132,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw @Setter @Getter - @ManyToOne(optional = true, fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "installed_distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) private JpaDistributionSet installedDistributionSet; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/BaseEntityRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/BaseEntityRepository.java index c71a26a42..7f59a127f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/BaseEntityRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/BaseEntityRepository.java @@ -10,20 +10,18 @@ package org.eclipse.hawkbit.repository.jpa.repository; import java.util.Collection; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Optional; -import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.acm.AccessController; import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_; import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaTenantAwareBaseEntity; +import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; @@ -43,6 +41,10 @@ public interface BaseEntityRepository, CrudRepository, JpaSpecificationExecutor, JpaSpecificationEntityGraphExecutor, NoCountSliceRepository, ACMRepository { + default T getById(final Long id) { + return findOne(byIdSpec(id)).orElseThrow(() -> new EntityNotFoundException(getManagementClass(), id)); + } + /** * Overrides {@link org.springframework.data.repository.CrudRepository#saveAll(Iterable)} to return a list of created entities instead * of an instance of {@link Iterable} to be able to work with it directly in further code processing instead of converting the @@ -133,4 +135,26 @@ public interface BaseEntityRepository> getAccessController() { return Optional.empty(); } + + @SuppressWarnings("uchecked") + default Class getManagementClass() { + final Class domainClass = getDomainClass(); + final String domainClassSimpleName = domainClass.getSimpleName(); + if (!domainClassSimpleName.toLowerCase().startsWith("jpa")) { + return domainClass; + } + final String managementClassSimpleName = domainClassSimpleName.substring(3); + final Class superClass = domainClass.getSuperclass(); + if (superClass != null) { + if (superClass.getSimpleName().equals(managementClassSimpleName) && BaseEntity.class.isAssignableFrom(superClass)) { + return (Class)superClass; + } + } + for (final Class interfaceClass : domainClass.getInterfaces()) { + if (interfaceClass.getSimpleName().equals(managementClassSimpleName) && BaseEntity.class.isAssignableFrom(interfaceClass)) { + return (Class)interfaceClass; + } + } + return domainClass; + } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java index 5a9f23866..f5506a08a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java @@ -290,9 +290,7 @@ public final class TargetSpecifications { public static Specification hasNotDistributionSetInActions(final Long distributionSetId) { return (targetRoot, query, cb) -> { final ListJoin actionsJoin = targetRoot.join(JpaTarget_.actions, JoinType.LEFT); - actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), - distributionSetId)); - + actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), distributionSetId)); return cb.isNull(actionsJoin.get(JpaAction_.id)); }; } @@ -308,10 +306,8 @@ public final class TargetSpecifications { */ public static Specification isCompatibleWithDistributionSetType(final Long distributionSetTypeId) { return (targetRoot, query, cb) -> { - // Since the targetRoot is changed by joining we need to get the - // isNull predicate first + // Since the targetRoot is changed by joining we need to get the isNull predicate first final Predicate targetTypeIsNull = getTargetTypeIsNullPredicate(targetRoot); - return cb.or(targetTypeIsNull, cb.equal(getDsTypeIdPath(targetRoot), distributionSetTypeId)); }; } @@ -328,15 +324,15 @@ public final class TargetSpecifications { */ public static Specification notCompatibleWithDistributionSetType(final Long distributionSetTypeId) { return (targetRoot, query, cb) -> { - // Since the targetRoot is changed by joining we need to get the - // isNotNull predicate first + // Since the targetRoot is changed by joining we need to get the isNotNull predicate first final Predicate targetTypeNotNull = targetRoot.get(JpaTarget_.targetType).isNotNull(); final Subquery compatibilitySubQuery = query.subquery(Long.class); final Root subQueryTargetRoot = compatibilitySubQuery.from(JpaTarget.class); compatibilitySubQuery.select(subQueryTargetRoot.get(JpaTarget_.id)) - .where(cb.and(cb.equal(targetRoot.get(JpaTarget_.id), subQueryTargetRoot.get(JpaTarget_.id)), + .where(cb.and( + cb.equal(targetRoot.get(JpaTarget_.id), subQueryTargetRoot.get(JpaTarget_.id)), cb.equal(getDsTypeIdPath(subQueryTargetRoot), distributionSetTypeId))); return cb.and(targetTypeNotNull, cb.not(cb.exists(compatibilitySubQuery))); @@ -599,10 +595,6 @@ public final class TargetSpecifications { private static Path getDsTypeIdPath(final Root root) { final Join targetTypeJoin = root.join(JpaTarget_.targetType, JoinType.LEFT); - targetTypeJoin.fetch(JpaTargetType_.distributionSetTypes); - final SetJoin dsTypeTargetTypeJoin = targetTypeJoin - .join(JpaTargetType_.distributionSetTypes, JoinType.LEFT); - - return dsTypeTargetTypeJoin.get(JpaDistributionSetType_.id); + return targetTypeJoin.join(JpaTargetType_.distributionSetTypes, JoinType.LEFT).get(JpaDistributionSetType_.id); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java index df813df60..2a8de88c5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java @@ -68,7 +68,6 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaAction_; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository; import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications; @@ -173,7 +172,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) public void controllerProvidesIntermediateFeedbackFailsIfQuotaHit() { @@ -181,12 +180,12 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final Long actionId = createTargetAndAssignDs(); // Fails as one entry is already in there from the assignment - assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> SecurityContextSwitch - .runAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { - writeStatus(actionId, allowStatusEntries); - return null; - })).withMessageContaining("" + allowStatusEntries); - + assertThatExceptionOfType(AssignmentQuotaExceededException.class) + .isThrownBy(() -> SecurityContextSwitch + .runAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { + writeStatus(actionId, allowStatusEntries); + return null; + })).withMessageContaining("" + allowStatusEntries); } @Test @@ -223,7 +222,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 2), + @Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 2) }) public void addActionStatusUpdatesUntilQuotaIsExceeded() { @@ -263,7 +262,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) public void createActionStatusWithTooManyMessages() { @@ -295,7 +294,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) public void controllerReportsDownloadForDownloadOnlyAction() { @@ -380,7 +379,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @@ -407,7 +406,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) void controllerConfirmationFailsWithInvalidMessages() { @@ -439,7 +438,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = CancelTargetAssignmentEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @@ -466,7 +465,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) void cancellationFeedbackRejectedIfActionIsNotInCanceling() { @@ -492,7 +491,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = CancelTargetAssignmentEvent.class, count = 1), @@ -523,7 +522,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = CancelTargetAssignmentEvent.class, count = 1), @@ -555,7 +554,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = CancelTargetAssignmentEvent.class, count = 1), @@ -587,7 +586,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = CancelTargetAssignmentEvent.class, count = 1), @@ -619,7 +618,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 5), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() { @@ -860,7 +859,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Description("Register a controller which does not exist, then update the controller twice, first time by providing a name property and second time without a new name") @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetPollEvent.class, count = 3), + @Expect(type = TargetPollEvent.class, count = 3), @Expect(type = TargetUpdatedEvent.class, count = 1) }) void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() { final String controllerId = "12345"; @@ -959,7 +958,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) @@ -1000,7 +999,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @@ -1041,7 +1040,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @@ -1178,7 +1177,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetAttributesRequestedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 2), @@ -1234,7 +1233,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @Expect(type = TargetAttributesRequestedEvent.class, count = 9), @@ -1258,7 +1257,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 1), + @Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetAttributesRequestedEvent.class, count = 10), @Expect(type = ActionUpdatedEvent.class, count = 2), @@ -1444,7 +1443,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 12), @Expect(type = DistributionSetUpdatedEvent.class, count = 4), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 4), + @Expect(type = ActionCreatedEvent.class, count = 4), @Expect(type = TargetUpdatedEvent.class, count = 12), @Expect(type = TargetAssignDistributionSetEvent.class, count = 4), @Expect(type = TargetAttributesRequestedEvent.class, count = 6), @@ -1489,7 +1488,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = ActionCreatedEvent.class, count = 2), + @Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 5), @Expect(type = TargetAttributesRequestedEvent.class, count = 3), @Expect(type = ActionUpdatedEvent.class, count = 3), @@ -1558,7 +1557,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Description("Delete a target on requested target deletion from client side") @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetPollEvent.class, count = 1), + @Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) }) void deleteTargetWithValidThingId() { final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST); @@ -1584,7 +1583,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { @Description("Delete a target after it has been deleted already") @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetPollEvent.class, count = 1), + @Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) }) void deleteTargetAfterItWasDeleted() { final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java index c7920d9ca..d3ab371c2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java @@ -33,6 +33,7 @@ import jakarta.validation.ConstraintViolationException; import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; +import lombok.Getter; import org.assertj.core.api.Assertions; import org.eclipse.hawkbit.repository.ActionStatusFields; import org.eclipse.hawkbit.repository.DeploymentManagement; @@ -114,7 +115,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThatExceptionOfType(IncompleteDistributionSetException.class) .as("Incomplete distributionSet should throw an exception") .isThrownBy(() -> assignDistributionSet(distributionSet, target)); - } @Test @@ -126,27 +126,12 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThatExceptionOfType(InvalidDistributionSetException.class) .as("Invalid distributionSet should throw an exception") .isThrownBy(() -> assignDistributionSet(distributionSet, target)); - - } - - protected List createAssignmentRequests(final Collection distributionSets, - final Collection targets, final int weight) { - return createAssignmentRequests(distributionSets, targets, weight, false); - } - - protected List createAssignmentRequests(final Collection distributionSets, - final Collection targets, final int weight, final boolean confirmationRequired) { - final List deploymentRequests = new ArrayList<>(); - distributionSets.forEach(ds -> targets.forEach(target -> deploymentRequests - .add(DeploymentManagement.deploymentRequest(target.getControllerId(), ds.getId()).setWeight(weight) - .setConfirmationRequired(confirmationRequired).build()))); - return deploymentRequests; } @Test @Description("Verifies that management get access react as specified on calls for non existing entities by means " + "of Optional not present.") - @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) }) + @ExpectEvents({ @Expect(type = TargetCreatedEvent.class) }) void nonExistingEntityAccessReturnsNotPresent() { assertThat(deploymentManagement.findAction(1234L)).isNotPresent(); assertThat(deploymentManagement.findActionWithDetails(NOT_EXIST_IDL)).isNotPresent(); @@ -190,22 +175,20 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThat(action.getDistributionSet()).as("DistributionSet in action").isNotNull(); assertThat(action.getTarget()).as("Target in action").isNotNull(); assertThat(deploymentManagement.getAssignedDistributionSet(action.getTarget().getControllerId()).get()) - .as("AssignedDistributionSet of target in action").isNotNull(); - + .as("AssignedDistributionSet of target in action") + .isNotNull(); } @Test @Description("Test verifies that actions of a target are found by using id-based search.") void findActionByTargetId() { - final DistributionSet testDs = testdataFactory.createDistributionSet("TestDs", "1.0", - new ArrayList<>()); + final DistributionSet testDs = testdataFactory.createDistributionSet("TestDs", "1.0", new ArrayList<>()); final List testTarget = testdataFactory.createTargets(1); // one action with one action status is generated final Long actionId = getFirstAssignedActionId(assignDistributionSet(testDs, testTarget)); // act - final Slice actions = deploymentManagement.findActionsByTarget(testTarget.get(0).getControllerId(), - PAGE); + final Slice actions = deploymentManagement.findActionsByTarget(testTarget.get(0).getControllerId(), PAGE); final Long count = deploymentManagement.countActionsByTarget(testTarget.get(0).getControllerId()); assertThat(count).as("One Action for target").isEqualTo(1L).isEqualTo(actions.getContent().size()); @@ -215,7 +198,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Test verifies that the 'max actions per target' quota is enforced.") void assertMaxActionsPerTargetQuotaIsEnforced() { - final int maxActions = quotaManagement.getMaxActionsPerTarget(); final Target testTarget = testdataFactory.createTarget(); final DistributionSet ds1 = testdataFactory.createDistributionSet("ds1"); @@ -223,7 +205,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { enableMultiAssignments(); for (int i = 0; i < maxActions; i++) { deploymentManagement.offlineAssignedDistributionSets(Collections - .singletonList(new SimpleEntry(testTarget.getControllerId(), ds1.getId()))); + .singletonList(new SimpleEntry<>(testTarget.getControllerId(), ds1.getId()))); } assertThatExceptionOfType(AssignmentQuotaExceededException.class) @@ -241,8 +223,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assignDistributionSet(ds1, targets); targets.add(testdataFactory.createTarget("assignmentTest2")); - assertThatExceptionOfType(AssignmentQuotaExceededException.class) - .isThrownBy(() -> assignDistributionSet(ds2, targets)); + assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> assignDistributionSet(ds2, targets)); } @Test @@ -266,8 +247,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Test verifies that messages of an action-status are found by using id-based search.") void findMessagesByActionStatusId() { - final DistributionSet testDs = testdataFactory.createDistributionSet("TestDs", "1.0", - new ArrayList()); + final DistributionSet testDs = testdataFactory.createDistributionSet("TestDs", "1.0", new ArrayList<>()); final List testTarget = testdataFactory.createTargets(1); // one action with one action status is generated final Long actionId = getFirstAssignedActionId(assignDistributionSet(testDs, testTarget)); @@ -277,8 +257,10 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final Page actionStates = deploymentManagement.findActionStatusByAction(PAGE, actionId); // find newly created action-status entry with message - final JpaActionStatus actionStatusWithMessage = actionStates.getContent().stream().map(c -> (JpaActionStatus) c) - .filter(entry -> entry.getMessages() != null && entry.getMessages().size() > 0).findFirst().get(); + final JpaActionStatus actionStatusWithMessage = actionStates.getContent().stream() + .map(JpaActionStatus.class::cast) + .filter(entry -> entry.getMessages() != null && !entry.getMessages().isEmpty()) + .findFirst().get(); final String expectedMsg = actionStatusWithMessage.getMessages().get(0); // act @@ -302,7 +284,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThatExceptionOfType(EntityNotFoundException.class) .isThrownBy(() -> distributionSetManagement.assignTag(assignDS, tag.getId())) - .withMessageContaining("DistributionSet").withMessageContaining(String.valueOf(100L)); + .withMessageContaining("DistributionSet") + .withMessageContaining(String.valueOf(100L)); } @Test @@ -320,13 +303,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) }) // implicit lock }) void multiAssigmentHistoryOverMultiplePagesResultsInTwoActiveAction() { - - final DistributionSet cancelDs = testdataFactory.createDistributionSet("Canceled DS", "1.0", - Collections.emptyList()); - - final DistributionSet cancelDs2 = testdataFactory.createDistributionSet("Canceled DS", "1.2", - Collections.emptyList()); - + final DistributionSet cancelDs = testdataFactory.createDistributionSet("Canceled DS", "1.0", Collections.emptyList()); + final DistributionSet cancelDs2 = testdataFactory.createDistributionSet("Canceled DS", "1.2", Collections.emptyList()); final List targets = testdataFactory.createTargets(quotaManagement.getMaxTargetsPerAutoAssignment()); assertThat(deploymentManagement.countActionsAll()).isZero(); @@ -334,14 +312,13 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assignDistributionSet(cancelDs, targets).getAssignedEntity(); assertThat(deploymentManagement.countActionsAll()).isEqualTo(quotaManagement.getMaxTargetsPerAutoAssignment()); assignDistributionSet(cancelDs2, targets).getAssignedEntity(); - assertThat(deploymentManagement.countActionsAll()) - .isEqualTo(2L * quotaManagement.getMaxTargetsPerAutoAssignment()); + assertThat(deploymentManagement.countActionsAll()).isEqualTo(2L * quotaManagement.getMaxTargetsPerAutoAssignment()); } @Test - @Description("Cancels multiple active actions on a target. Expected behaviour is that with two active " - + "actions after canceling the second active action the first one is still running as it is not touched by the cancelation. After canceling the first one " - + "also the target goes back to IN_SYNC as no open action is left.") + @Description("Cancels multiple active actions on a target. Expected behaviour is that with two active " + + "actions after canceling the second active action the first one is still running as it is not touched by the cancelation. " + + "After canceling the first one also the target goes back to IN_SYNC as no open action is left.") void manualCancelWithMultipleAssignmentsCancelLastOneFirst() { final Action action = prepareFinishedUpdate("4712", "installed", true); final Target target = action.getTarget(); @@ -350,7 +327,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final DistributionSet dsInstalled = action.getDistributionSet(); // check initial status - assertThat(targetManagement.getByControllerID("4712").get().getUpdateStatus()).as("target has update status") + assertThat(targetManagement.getByControllerID("4712").get().getUpdateStatus()) + .as("target has update status") .isEqualTo(TargetUpdateStatus.IN_SYNC); // assign the two sets in a row @@ -364,11 +342,11 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { deploymentManagement.cancelAction(secondAction.getId()); secondAction = (JpaAction) deploymentManagement.findActionWithDetails(secondAction.getId()).get(); // confirm cancellation - controllerManagement.addCancelActionStatus( - entityFactory.actionStatus().create(secondAction.getId()).status(Status.CANCELED)); + controllerManagement.addCancelActionStatus(entityFactory.actionStatus().create(secondAction.getId()).status(Status.CANCELED)); assertThat(actionStatusRepository.findAll()).as("wrong size of actions status").hasSize(7); assertThat(deploymentManagement.getAssignedDistributionSet("4712")).as("wrong ds").contains(dsFirst); - assertThat(targetManagement.getByControllerID("4712").get().getUpdateStatus()).as("wrong update status") + assertThat(targetManagement.getByControllerID("4712").get().getUpdateStatus()) + .as("wrong update status") .isEqualTo(TargetUpdateStatus.PENDING); // we cancel first -> back to installed @@ -434,7 +412,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Force Quit an Assignment. Expected behaviour is that the action is canceled and is marked as deleted. The assigned Software module") - void forceQuitSetActionToInactive() throws InterruptedException { + void forceQuitSetActionToInactive() { final Action action = prepareFinishedUpdate("4712", "installed", true); final Target target = action.getTarget(); final DistributionSet dsInstalled = action.getDistributionSet(); @@ -506,7 +484,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final List controllerIds = testdataFactory.createTargets(10).stream().map(Target::getControllerId) .collect(Collectors.toList()); final List onlineAssignedTargets = testdataFactory.createTargets(10, "2"); - controllerIds.addAll(onlineAssignedTargets.stream().map(Target::getControllerId).collect(Collectors.toList())); + controllerIds.addAll(onlineAssignedTargets.stream().map(Target::getControllerId).toList()); final DistributionSet ds = testdataFactory.createDistributionSet(); assignDistributionSet(testdataFactory.createDistributionSet("2"), onlineAssignedTargets); @@ -514,7 +492,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final long current = System.currentTimeMillis(); final List> offlineAssignments = controllerIds.stream() - .map(targetId -> new SimpleEntry(targetId, ds.getId())).collect(Collectors.toList()); + .map(targetId -> new SimpleEntry<>(targetId, ds.getId())).collect(Collectors.toList()); final List assignmentResults = deploymentManagement .offlineAssignedDistributionSets(offlineAssignments); assertThat(assignmentResults).hasSize(1); @@ -548,15 +526,12 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void multiOfflineAssignment() { - final List targetIds = testdataFactory.createTargets(1).stream().map(Target::getControllerId) - .collect(Collectors.toList()); - final List dsIds = testdataFactory.createDistributionSets(4).stream().map(DistributionSet::getId) - .collect(Collectors.toList()); + final List targetIds = testdataFactory.createTargets(1).stream().map(Target::getControllerId).toList(); + final List dsIds = testdataFactory.createDistributionSets(4).stream().map(DistributionSet::getId).toList(); enableMultiAssignments(); final List> offlineAssignments = new ArrayList<>(); - targetIds.forEach(targetId -> dsIds - .forEach(dsId -> offlineAssignments.add(new SimpleEntry(targetId, dsId)))); + targetIds.forEach(targetId -> dsIds.forEach(dsId -> offlineAssignments.add(new SimpleEntry<>(targetId, dsId)))); final List assignmentResults = deploymentManagement .offlineAssignedDistributionSets(offlineAssignments); @@ -565,7 +540,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final List assignedDsIds = deploymentManagement.findActionsByTarget(controllerId, PAGE).stream() .map(a -> { // don't use peek since it is by documentation mainly for debugging and could be skipped in some cases - assertThat(a.getInitiatedBy()).as("Actions should be initiated by current user") + assertThat(a.getInitiatedBy()) + .as("Actions should be initiated by current user") .isEqualTo(tenantAware.getCurrentUsername()); return a; }) @@ -628,8 +604,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = MultiActionCancelEvent.class, count = 0), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void previousAssignmentsAreNotCanceledInMultiAssignMode() { enableMultiAssignments(); @@ -661,7 +635,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = DistributionSetUpdatedEvent.class, count = 4), // implicit lock @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock @Expect(type = MultiActionAssignEvent.class, count = 1), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void multiAssignmentInOneRequest() { final List targets = testdataFactory.createTargets(1); @@ -701,7 +674,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = MultiActionAssignEvent.class, count = 1), @Expect(type = MultiActionCancelEvent.class, count = 4), @Expect(type = ActionUpdatedEvent.class, count = 4), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void cancelMultiAssignmentActions() { final List targets = testdataFactory.createTargets(1); @@ -716,14 +688,13 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThat(getResultingActionCount(results)).isEqualTo(deploymentRequests.size()); final List dsIds = distributionSets.stream().map(DistributionSet::getId).collect(Collectors.toList()); - targets.forEach(target -> { + targets.forEach(target -> deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).forEach(action -> { assertThat(action.getDistributionSet().getId()).isIn(dsIds); assertThat(action.getInitiatedBy()).as("Should be Initiated by current user") .isEqualTo(tenantAware.getCurrentUsername()); deploymentManagement.cancelAction(action.getId()); - }); - }); + })); } @Test @@ -785,7 +756,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThat(getResultingActionCount(results)).isEqualTo(controllerIds.size()); - controllerIds.forEach(controllerId -> { + controllerIds.forEach(controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).forEach(action -> { assertThat(action.getDistributionSet().getId()).isIn(distributionSet.getId()); assertThat(action.getInitiatedBy()).as("Should be Initiated by current user") @@ -795,8 +766,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { } else { assertThat(action.getStatus()).isEqualTo(RUNNING); } - }); - }); + })); } @ParameterizedTest @@ -831,9 +801,12 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { // auto-confirmation will perform the confirmation assertThat(actionStatus.getMessages()) .contains("Assignment initiated by user 'bumlux'") - .contains("Assignment automatically confirmed by initiator 'not_bumlux'. \n" - + "\n" + "Auto confirmation activated by system user: 'bumlux' \n" - + "\n" + "Remark: my personal remark"); + .contains(""" + Assignment automatically confirmed by initiator 'not_bumlux'.\s + + Auto confirmation activated by system user: 'bumlux'\s + + Remark: my personal remark"""); } else { // assignment never required confirmation, auto-confirmation will not be // applied. @@ -896,19 +869,17 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assignDistributionSetToTargets(distributionSet, targets2, false).stream()) // .collect(Collectors.toList()); - final List controllerIds = Stream.concat(targets1.stream(), targets2.stream()) - .collect(Collectors.toList()); + final List controllerIds = Stream.concat(targets1.stream(), targets2.stream()).toList(); assertThat(getResultingActionCount(results)).isEqualTo(controllerIds.size()); - controllerIds.forEach(controllerId -> { + controllerIds.forEach(controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).forEach(action -> { assertThat(action.getDistributionSet().getId()).isIn(distributionSet.getId()); assertThat(action.getInitiatedBy()).as("Should be Initiated by current user") .isEqualTo(tenantAware.getCurrentUsername()); assertThat(action.getStatus()).isEqualTo(RUNNING); - }); - }); + })); } @Test @@ -947,7 +918,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = TargetCreatedEvent.class, count = 1), @Expect(type = DistributionSetCreatedEvent.class, count = 21), // max actions per target are 20 for test @Expect(type = SoftwareModuleCreatedEvent.class, count = 3 * 21), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void maxActionsPerTargetIsCheckedBeforeAssignmentExecution() { final int maxActions = quotaManagement.getMaxActionsPerTarget(); @@ -1165,9 +1135,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThat(page.getTotalElements()).as("wrong size of actions") .isEqualTo(noOfDeployedTargets * noOfDistributionSets); - // only records retrieved from the DB can be evaluated to be sure that - // all fields are - // populated; + // only records retrieved from the DB can be evaluated to be sure that all fields are populated; final List allFoundTargets = targetRepository.findAll(); final List deployedTargetsFromDB = targetRepository.findAllById(deployedTargetIDs); @@ -1210,9 +1178,9 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { final JpaDistributionSet dsC = (JpaDistributionSet) deployResWithDsC.getDistributionSets().get(0); // retrieving the UpdateActions created by the assignments - findActionsByDistributionSet(pageRequest, dsA.getId()).getContent().get(0); - findActionsByDistributionSet(pageRequest, dsB.getId()).getContent().get(0); - findActionsByDistributionSet(pageRequest, dsC.getId()).getContent().get(0); + assertThat(findActionsByDistributionSet(pageRequest, dsA.getId()).getContent()).isNotEmpty(); + assertThat(findActionsByDistributionSet(pageRequest, dsB.getId()).getContent()).isNotEmpty(); + assertThat(findActionsByDistributionSet(pageRequest, dsC.getId()).getContent()).isNotEmpty(); // verifying the correctness of the assignments for (final Target t : deployResWithDsA.getDeployedTargets()) { @@ -1531,8 +1499,9 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { assertThat(assignmentResult.getAssigned()).as("Total count of assigned targets").isEqualTo(1); assertThat(assignmentResult.getAlreadyAssigned()).as("Total count of already assigned targets").isEqualTo(1); assertThat(assignmentResult.getAssignedEntity()).isNotEmpty(); + final DistributionSet actionDistributionSet = distributionSetRepository.getById(action.getDistributionSet().getId()); assertThat(assignmentResult.getAssignedEntity()).allMatch( - a -> a.getTarget().equals(target3) && a.getDistributionSet().equals(action.getDistributionSet())); + a -> a.getTarget().equals(target3) && a.getDistributionSet().equals(actionDistributionSet)); assertThat(assignmentResult.getAssignedEntity()) .noneMatch(a -> a.getTarget().getControllerId().equals("target1")); } @@ -1642,6 +1611,20 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { .isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests)); } + private List createAssignmentRequests( + final Collection distributionSets, final Collection targets, final int weight) { + return createAssignmentRequests(distributionSets, targets, weight, false); + } + + private List createAssignmentRequests(final Collection distributionSets, + final Collection targets, final int weight, final boolean confirmationRequired) { + final List deploymentRequests = new ArrayList<>(); + distributionSets.forEach(ds -> targets.forEach(target -> deploymentRequests + .add(DeploymentManagement.deploymentRequest(target.getControllerId(), ds.getId()).setWeight(weight) + .setConfirmationRequired(confirmationRequired).build()))); + return deploymentRequests; + } + private JpaAction assignSet(final Target target, final DistributionSet ds) { assignDistributionSet(ds.getId(), target.getControllerId()); implicitLock(ds); @@ -1715,10 +1698,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { "first description"); // creating 10 DistributionSets - final Collection dsList = testdataFactory.createDistributionSets(distributionSetPrefix, - noOfDistributionSets); - String time = String.valueOf(System.currentTimeMillis()); - time = time.substring(time.length() - 5); + final Collection dsList = testdataFactory.createDistributionSets(distributionSetPrefix, noOfDistributionSets); // assigning all DistributionSet to the Target in the list // deployedTargets @@ -1728,66 +1708,36 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { implicitLock(ds); } - return new DeploymentResult(deployedTargets, nakedTargets, dsList, deployedTargetPrefix, undeployedTargetPrefix, - distributionSetPrefix); + return new DeploymentResult(deployedTargets, nakedTargets, dsList); } private Slice findActionsByDistributionSet(final Pageable pageable, final long distributionSetId) { - distributionSetManagement.get(distributionSetId).orElseThrow(() -> new EntityNotFoundException( - DistributionSet.class, distributionSetId)); + distributionSetManagement.get(distributionSetId).orElseThrow(() -> + new EntityNotFoundException(DistributionSet.class, distributionSetId)); return actionRepository .findAll(ActionSpecifications.byDistributionSetId(distributionSetId), pageable) .map(Action.class::cast); } + @Getter private static class DeploymentResult { - final List deployedTargetIDs = new ArrayList<>(); - final List undeployedTargetIDs = new ArrayList<>(); - final List distributionSetIDs = new ArrayList<>(); + private final List deployedTargetIDs = new ArrayList<>(); + private final List undeployedTargetIDs = new ArrayList<>(); + private final List distributionSetIDs = new ArrayList<>(); private final List undeployedTargets = new ArrayList<>(); private final List deployedTargets = new ArrayList<>(); private final List distributionSets = new ArrayList<>(); - public DeploymentResult(final Iterable deployedTs, final Iterable undeployedTs, - final Iterable dss, final String deployedTargetPrefix, - final String undeployedTargetPrefix, final String distributionSetPrefix) { - + private DeploymentResult(final Iterable deployedTs, final Iterable undeployedTs, final Iterable dss) { deployedTargets.addAll(toList(deployedTs)); undeployedTargets.addAll(toList(undeployedTs)); distributionSets.addAll(toList(dss)); deployedTargets.forEach(t -> deployedTargetIDs.add(t.getId())); - undeployedTargets.forEach(t -> undeployedTargetIDs.add(t.getId())); - distributionSets.forEach(ds -> distributionSetIDs.add(ds.getId())); - - } - - public List getDistributionSetIDs() { - return distributionSetIDs; - } - - public List getDeployedTargetIDs() { - return deployedTargetIDs; - } - - public List getUndeployedTargets() { - return undeployedTargets; - } - - public List getDistributionSets() { - return distributionSets; - } - - public List getDeployedTargets() { - return deployedTargets; - } - - public List getUndeployedTargetIDs() { - return undeployedTargetIDs; } } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java index b5f94575e..f7d9ff3fd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java @@ -49,8 +49,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe @Test @Description("Verify invalidation of distribution sets that only removes distribution sets from auto assignments") void verifyInvalidateDistributionSetStopAutoAssignment() { - final InvalidationTestData invalidationTestData = createInvalidationTestData( - "verifyInvalidateDistributionSetStopAutoAssignment"); + final InvalidationTestData invalidationTestData = createInvalidationTestData("verifyInvalidateDistributionSetStopAutoAssignment"); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.NONE, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java index 27925b7b6..cb9ab8e7d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java @@ -85,13 +85,13 @@ import org.springframework.data.domain.Sort.Direction; @Story("DistributionSet Management") class DistributionSetManagementTest extends AbstractJpaIntegrationTest { - public static final String TAG1_NAME = "Tag1"; + private static final String TAG1_NAME = "Tag1"; + @Autowired RepositoryProperties repositoryProperties; @Test - @Description("Verifies that management get access react as specified on calls for non existing entities by means " - + "of Optional not present.") + @Description("Verifies that management get access react as specified on calls for non existing entities by means of Optional not present.") @ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = SoftwareModuleCreatedEvent.class, count = 3) }) @@ -104,8 +104,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { } @Test - @Description("Verifies that management queries react as specfied on calls for non existing entities " - + " by means of throwing EntityNotFoundException.") + @Description("Verifies that management queries react as specified on calls for non existing entities by means of " + + "throwing EntityNotFoundException.") @ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), @@ -116,52 +116,36 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { final SoftwareModule module = testdataFactory.createSoftwareModuleApp(); verifyThrownExceptionBy( - () -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, singletonList(module.getId())), - "DistributionSet"); + () -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, singletonList(module.getId())), "DistributionSet"); verifyThrownExceptionBy( - () -> distributionSetManagement.assignSoftwareModules(set.getId(), singletonList(NOT_EXIST_IDL)), - "SoftwareModule"); + () -> distributionSetManagement.assignSoftwareModules(set.getId(), singletonList(NOT_EXIST_IDL)), "SoftwareModule"); verifyThrownExceptionBy(() -> distributionSetManagement.countByTypeId(NOT_EXIST_IDL), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(NOT_EXIST_IDL, module.getId()), - "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL), - "SoftwareModule"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(NOT_EXIST_IDL, module.getId()), "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL), "SoftwareModule"); - verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(set.getId()), NOT_EXIST_IDL), - "DistributionSetTag"); - - verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), - "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(set.getId()), NOT_EXIST_IDL), "DistributionSetTag"); + verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.findByTag(PAGE, NOT_EXIST_IDL), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetManagement.findByRsqlAndTag(PAGE, "name==*", NOT_EXIST_IDL), - "DistributionSetTag"); + verifyThrownExceptionBy(() -> distributionSetManagement.findByRsqlAndTag(PAGE, "name==*", NOT_EXIST_IDL), "DistributionSetTag"); - verifyThrownExceptionBy( - () -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), - "DistributionSet"); - verifyThrownExceptionBy( - () -> distributionSetManagement.assignTag(singletonList(set.getId()), Long.parseLong(NOT_EXIST_ID)), - "DistributionSetTag"); + verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), "DistributionSet"); + verifyThrownExceptionBy(() -> + distributionSetManagement.assignTag(singletonList(set.getId()), Long.parseLong(NOT_EXIST_ID)), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(set.getId(), NOT_EXIST_IDL), - "DistributionSetTag"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(set.getId(), NOT_EXIST_IDL), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(NOT_EXIST_IDL, dsTag.getId()), - "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(NOT_EXIST_IDL, dsTag.getId()), "DistributionSet"); - verifyThrownExceptionBy( - () -> distributionSetManagement - .create(entityFactory.distributionSet().create().name("xxx").type(NOT_EXIST_ID)), - "DistributionSetType"); + verifyThrownExceptionBy(() -> distributionSetManagement.create( + entityFactory.distributionSet().create().name("xxx").type(NOT_EXIST_ID)), "DistributionSetType"); - verifyThrownExceptionBy(() -> distributionSetManagement.createMetaData(NOT_EXIST_IDL, - singletonList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.createMetaData( + NOT_EXIST_IDL, singletonList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.delete(singletonList(NOT_EXIST_IDL)), - "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.delete(singletonList(NOT_EXIST_IDL)), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.delete(NOT_EXIST_IDL), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"), "DistributionSet"); @@ -249,22 +233,20 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.") void createMultipleDistributionSetsWithImplicitType() { - final List creates = new ArrayList<>(10); for (int i = 0; i < 10; i++) { creates.add(entityFactory.distributionSet().create().name("newtypesoft" + i).version("1" + i)); } - final List sets = distributionSetManagement.create(creates); - - assertThat(sets).as("Type should be equal to default type of tenant").are(new Condition() { - - @Override - public boolean matches(final DistributionSet value) { - return value.getType().equals(systemManagement.getTenantMetadata().getDefaultDsType()); - } - }); + assertThat(distributionSetManagement.create(creates)) + .as("Type should be equal to default type of tenant") + .are(new Condition<>() { + @Override + public boolean matches(final DistributionSet value) { + return value.getType().equals(systemManagement.getTenantMetadata().getDefaultDsType()); + } + }); } @Test @@ -338,13 +320,13 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { assignDS.add(testdataFactory.createDistributionSet("DS" + i, "1.0", Collections.emptyList()).getId()); } - final DistributionSetTag tag = distributionSetTagManagement - .create(entityFactory.tag().create().name(TAG1_NAME)); + final DistributionSetTag tag = distributionSetTagManagement.create(entityFactory.tag().create().name(TAG1_NAME)); final List assignedDS = distributionSetManagement.assignTag(assignDS, tag.getId()); assertThat(assignedDS.size()).as("assigned ds has wrong size").isEqualTo(4); - assignedDS.stream().map(c -> (JpaDistributionSet) c) - .forEach(ds -> assertThat(ds.getTags().size()).as("ds has wrong tag size").isEqualTo(1)); + assignedDS.stream().map(JpaDistributionSet.class::cast).forEach(ds -> assertThat(ds.getTags().size()) + .as("ds has wrong tag size") + .isEqualTo(1)); final DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.getByName(TAG1_NAME)); @@ -1046,16 +1028,15 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Get the Rollouts count by status statistics for a specific Distribution Set") void getActionsCountStatisticsForDistributionSet() { - DistributionSet ds = testdataFactory.createDistributionSet("DS"); - DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); + final DistributionSet ds = testdataFactory.createDistributionSet("DS"); + final DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); testdataFactory.createTargets("targets", 4); - Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description", - 1, "name==targets*", ds, "50", "5", false); + final Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description", 1, "name==targets*", ds, "50", "5", false); rolloutManagement.start(rollout.getId()); rolloutHandler.handleAll(); - List statistics = distributionSetManagement.countActionsByStatusForDistributionSet(ds.getId()); + final List statistics = distributionSetManagement.countActionsByStatusForDistributionSet(ds.getId()); assertThat(statistics).hasSize(1); assertThat(distributionSetManagement.countActionsByStatusForDistributionSet(ds2.getId())).isEmpty(); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java index 365de6d9b..cdabb6305 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java @@ -296,9 +296,7 @@ public class TestdataFactory { * @param isRequiredMigrationStep for {@link DistributionSet#isRequiredMigrationStep()} * @return {@link DistributionSet} entity. */ - public DistributionSet createDistributionSet(final String prefix, final String version, - final boolean isRequiredMigrationStep) { - + public DistributionSet createDistributionSet(final String prefix, final String version, final boolean isRequiredMigrationStep) { final SoftwareModule appMod = softwareModuleManagement.create(entityFactory.softwareModule().create() .type(findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE)).name(prefix + SM_TYPE_APP) .version(version + "." + new SecureRandom().nextInt(100)).description(randomDescriptionLong()) diff --git a/hawkbit-security/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java b/hawkbit-security/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java index 9795c2858..b7615c20f 100644 --- a/hawkbit-security/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java +++ b/hawkbit-security/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.security; import java.util.Optional; +import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.springframework.data.domain.AuditorAware; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -58,6 +59,9 @@ public class SpringSecurityAuditorAware implements AuditorAware { } protected String getCurrentAuditor(final Authentication authentication) { + if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails && tenantAwareDetails.isController()) { + return "CONTROLLER_PLUG_AND_PLAY"; + } if (authentication.getPrincipal() instanceof UserDetails) { return ((UserDetails) authentication.getPrincipal()).getUsername(); }