diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java index 2f63a3122..0c33435d2 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java @@ -20,6 +20,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.jpa.TargetRepository; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; @@ -147,7 +148,7 @@ public class EntityChangeEventListener { } private static boolean isTargetInfoNew(final Object targetInfo) { - return ((TargetInfo) targetInfo).isNew(); + return ((JpaTargetInfo) targetInfo).isNew(); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index 4ee3b1275..47ff3c49f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -31,8 +31,6 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; /** * Service layer for all operations of the DDI API (with access permissions only @@ -248,7 +246,6 @@ public interface ControllerManagement { * */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) - @Transactional(isolation = Isolation.READ_UNCOMMITTED) TargetInfo updateLastTargetQuery(@NotNull TargetInfo target, @NotNull URI address); /** @@ -271,4 +268,11 @@ public interface ControllerManagement { TargetInfo updateTargetStatus(@NotNull TargetInfo targetInfo, TargetUpdateStatus status, Long lastTargetQuery, URI address); + /** + * Generates an empty {@link ActionStatus} without persisting it. + * + * @return {@link ActionStatus} object + */ + ActionStatus generateActionStatus(); + } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 754d66b65..070594d4e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -31,7 +31,6 @@ import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; /** @@ -179,7 +178,7 @@ public interface DeploymentManagement { * @return the count value of found actions associated to the target */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - Long countActionsByTarget(@NotNull Specification spec, @NotNull Target target); + Long countActionsByTarget(@NotNull String rsqlParam, @NotNull Target target); /** * counts all actions associated to a specific target. @@ -281,9 +280,9 @@ public interface DeploymentManagement { * @return a slice of actions assigned to the specific target and the * specification */ + // TODO fix this @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - Slice findActionsByTarget(@NotNull Specification specifiction, @NotNull Target target, - @NotNull Pageable pageable); + Slice findActionsByTarget(@NotNull String rsqlParam, @NotNull Target target, @NotNull Pageable pageable); /** * Retrieves all {@link Action}s of a specific target ordered by action ID. @@ -440,4 +439,10 @@ public interface DeploymentManagement { + SpringEvalExpressions.IS_SYSTEM_CODE) Action startScheduledAction(@NotNull Action action); + /** + * Generates an empty {@link Action} without persisting it. + * + * @return {@link Action} object + */ + Action generateAction(); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java index ad947879a..1393504ab 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java @@ -51,7 +51,7 @@ public class DistributionSetAssignmentResult extends AssignmentResult { this.actions = actions; this.targetManagement = targetManagement; } - + /** * @return the actionIds */ @@ -59,9 +59,10 @@ public class DistributionSetAssignmentResult extends AssignmentResult { return actions; } + @SuppressWarnings("unchecked") @Override public List getAssignedEntity() { - return targetManagement.findTargetByControllerID(assignedTargets); + return (List) targetManagement.findTargetByControllerID(assignedTargets); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index db737df4a..2574230b3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -21,14 +21,14 @@ import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMis import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.jpa.model.DistributionSetTypeElement; +import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.DistributionSetTypeElement; -import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.Tag; @@ -36,7 +36,6 @@ import org.eclipse.hawkbit.repository.model.Target; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; @@ -274,18 +273,7 @@ public interface DistributionSetManagement { * @return the found {@link DistributionSet}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Iterable findDistributionSetList(Collection dist); - - /** - * Retrieves {@link DistributionSet} List including details information, - * i.e. @link BaseSoftwareModule}s and {@link DistributionSetTag}s. - * - * @param distributionIdSet - * List of {@link DistributionSet} IDs to be found - * @return the found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetListWithDetails(Collection distributionIdSet); + List findDistributionSetsAll(Collection dist); /** * finds all meta data by the given distribution set id. @@ -315,7 +303,7 @@ public interface DistributionSetManagement { */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull Specification spec, @NotNull Pageable pageable); + @NotNull String rsqlParam, @NotNull Pageable pageable); // TODO discuss: use enum instead of the true,false,null switch ? /** @@ -357,8 +345,8 @@ public interface DistributionSetManagement { * @return all found {@link DistributionSet}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAll(@NotNull Specification spec, - @NotNull Pageable pageReq, Boolean deleted); + Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, + Boolean deleted); /** * method retrieves all {@link DistributionSet}s from the repository in the @@ -442,8 +430,7 @@ public interface DistributionSetManagement { * @return the found {@link SoftwareModuleType}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull Specification spec, - @NotNull Pageable pageable); + Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); /** * finds a single distribution set meta data by its id. @@ -580,4 +567,17 @@ public interface DistributionSetManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); + /** + * Generates an empty {@link DistributionSetType} without persisting it. + * + * @return {@link DistributionSetType} object + */ + DistributionSetType generateDistributionSetType(); + + /** + * Generates an empty {@link DistributionSet} without persisting it. + * + * @return {@link DistributionSet} object + */ + DistributionSet generateDistributionSet(); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java index baff4586c..efad0100c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java @@ -84,8 +84,8 @@ public interface RolloutGroupManagement { * @return a page of found {@link RolloutGroup}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) - Page findRolloutGroupsAll(@NotNull Rollout rollout, - @NotNull Specification specification, @NotNull Pageable page); + Page findRolloutGroupsAll(@NotNull Rollout rollout, @NotNull String rsqlParam, + @NotNull Pageable page); /** * Retrieves a page of {@link RolloutGroup}s filtered by a given @@ -128,8 +128,8 @@ public interface RolloutGroupManagement { * @return Page list of targets of a rollout group */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) - Page findRolloutGroupTargets(@NotNull RolloutGroup rolloutGroup, - @NotNull Specification specification, @NotNull Pageable page); + Page findRolloutGroupTargets(@NotNull RolloutGroup rolloutGroup, @NotNull String rsqlParam, + @NotNull Pageable page); /** * Get count of targets in different status in rollout group. @@ -141,4 +141,10 @@ public interface RolloutGroupManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) RolloutGroup findRolloutGroupWithDetailedStatus(@NotNull Long rolloutGroupId); + /** + * Generates an empty {@link RolloutGroup} without persisting it. + * + * @return {@link RolloutGroup} object + */ + RolloutGroup generateRolloutGroup(); } \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 118be12fa..140273439 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -13,16 +13,15 @@ import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.eventbus.event.RolloutGroupCreatedEvent; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditions; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditions; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; /** @@ -179,8 +178,7 @@ public interface RolloutManagement { * @return a page of found rollouts */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) - Page findAllWithDetailedStatusByPredicate(@NotNull Specification specification, - @NotNull Pageable page); + Page findAllWithDetailedStatusByPredicate(@NotNull String rsqlParam, @NotNull Pageable page); /** * Finds rollouts by given text in name or description. @@ -335,4 +333,11 @@ public interface RolloutManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) Rollout updateRollout(@NotNull Rollout rollout); + /** + * Generates an empty {@link Rollout} without persisting it. + * + * @return {@link Rollout} object + */ + Rollout generateRollout(); + } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index b3b9e7380..1802b1dcc 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -17,17 +17,16 @@ import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.CustomSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; /** @@ -290,7 +289,7 @@ public interface SoftwareManagement { */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, - @NotNull Specification spec, @NotNull Pageable pageable); + @NotNull String rsqlParam, @NotNull Pageable pageable); /** * Filter {@link SoftwareModule}s with given @@ -347,8 +346,7 @@ public interface SoftwareManagement { * @return the found {@link SoftwareModule}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModulesByPredicate(@NotNull Specification spec, - @NotNull Pageable pageable); + Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); /** * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} @@ -411,8 +409,7 @@ public interface SoftwareManagement { * @return the found {@link SoftwareModuleType}s */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesByPredicate(@NotNull Specification spec, - @NotNull Pageable pageable); + Page findSoftwareModuleTypesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); /** * Retrieves software module including details ( @@ -468,4 +465,17 @@ public interface SoftwareManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); + /** + * Generates an empty {@link SoftwareModuleType} without persisting it. + * + * @return {@link SoftwareModuleType} object + */ + SoftwareModuleType generateSoftwareModuleType(); + + /** + * Generates an empty {@link SoftwareModule} without persisting it. + * + * @return {@link SoftwareModule} object + */ + SoftwareModule generateSoftwareModule(); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java index 929bd745c..fa38e318b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java @@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.model.TargetTag; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; /** @@ -90,7 +89,7 @@ public interface TagManagement { * if given object has already an ID. */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) - List createTargetTags(@NotNull Iterable targetTags); + List createTargetTags(@NotNull Collection targetTags); /** * Deletes {@link DistributionSetTag} by given @@ -138,8 +137,7 @@ public interface TagManagement { * @return the found {@link DistributionSetTag}s, never {@code null} */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findAllDistributionSetTags(@NotNull Specification spec, - @NotNull Pageable pageable); + Page findAllDistributionSetTags(@NotNull String rsqlParam, @NotNull Pageable pageable); /** * @return all {@link TargetTag}s @@ -168,7 +166,7 @@ public interface TagManagement { * @return the found {@link Target}s, never {@code null} */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - Page findAllTargetTags(@NotNull Specification spec, @NotNull Pageable pageable); + Page findAllTargetTags(@NotNull String rsqlParam, @NotNull Pageable pageable); /** * Find {@link DistributionSet} based on given name. @@ -233,4 +231,18 @@ public interface TagManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) TargetTag updateTargetTag(@NotNull TargetTag targetTag); + /** + * Generates an empty {@link TargetTag} without persisting it. + * + * @return {@link TargetTag} object + */ + TargetTag generateTargetTag(); + + /** + * Generates an empty {@link DistributionSetTag} without persisting it. + * + * @return {@link DistributionSetTag} object + */ + DistributionSetTag generateDistributionSetTag(); + } \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index ae7724e31..f8e5e8a91 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -30,7 +30,6 @@ import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; /** @@ -290,8 +289,8 @@ public interface TargetManagement { * @return the found {@link Target}s, never {@code null} */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET) - Page findTargetByAssignedDistributionSet(@NotNull Long distributionSetID, - @NotNull Specification spec, @NotNull Pageable pageReq); + Page findTargetByAssignedDistributionSet(@NotNull Long distributionSetID, @NotNull String rsqlParam, + @NotNull Pageable pageReq); /** * Find {@link Target} based on given ID returns found Target without @@ -390,8 +389,8 @@ public interface TargetManagement { * @return the found {@link Target}s, never {@code null} */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET) - Page findTargetByInstalledDistributionSet(@NotNull Long distributionSetId, - @NotNull Specification spec, @NotNull Pageable pageable); + Page findTargetByInstalledDistributionSet(@NotNull Long distributionSetId, @NotNull String rsqlParam, + @NotNull Pageable pageable); /** * Retrieves the {@link Target} which have a certain @@ -418,18 +417,6 @@ public interface TargetManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) Slice findTargetsAll(@NotNull Pageable pageable); - /** - * Retrieves all targets based on the given specification. - * - * @param spec - * the specification for the query - * @param pageable - * pagination parameter - * @return the found {@link Target}s, never {@code null} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - Page findTargetsAll(@NotNull Specification spec, @NotNull Pageable pageable); - /** * Retrieves all targets without details, i.e. NO {@link Target#getTags()} * and {@link Target#getActions()} possible based on @@ -442,7 +429,7 @@ public interface TargetManagement { * @return the found {@link Target}s, never {@code null} */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - Slice findTargetsAll(@NotNull String targetFilterQuery, @NotNull Pageable pageable); + Page findTargetsAll(@NotNull String targetFilterQuery, @NotNull Pageable pageable); /** * Retrieves all targets without details, i.e. NO {@link Target#getTags()} @@ -599,6 +586,16 @@ public interface TargetManagement { */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) - List updateTargets(@NotNull Iterable targets); + List updateTargets(@NotNull Collection targets); + + /** + * Generates an empty {@link Target} without persisting it. + * + * @param controllerID + * of the {@link Target} + * + * @return {@link Target} object + */ + Target generateTarget(@NotEmpty String controllerID); } \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index d9647e610..9937084eb 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -142,5 +142,4 @@ public interface TenantConfigurationManagement { @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class propertyType); - } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java index 56ade85ff..0eebbced1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java @@ -11,6 +11,12 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.Collection; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -37,7 +43,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface ActionRepository extends BaseEntityRepository, JpaSpecificationExecutor { +public interface ActionRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** * Retrieves an Action with all lazy attributes. * @@ -46,7 +52,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return the found {@link Action} */ @EntityGraph(value = "Action.all", type = EntityGraphType.LOAD) - Action findById(Long actionId); + JpaAction findById(Long actionId); /** * Retrieves all {@link Action}s which are referring the given @@ -58,7 +64,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the {@link DistributionSet} on which will be filtered * @return the found {@link Action}s */ - Page findByDistributionSet(final Pageable pageable, final DistributionSet ds); + Page findByDistributionSet(final Pageable pageable, final JpaDistributionSet ds); /** * Retrieves all {@link Action}s which are referring the given @@ -70,7 +76,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the target to find assigned actions * @return the found {@link Action}s */ - Slice findByTarget(Pageable pageable, Target target); + Slice findByTarget(Pageable pageable, JpaTarget target); /** * Retrieves all {@link Action}s which are active and referring the given @@ -86,7 +92,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return the found {@link Action}s */ @EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD) - List findByTargetAndActiveOrderByIdAsc(final Target target, boolean active); + List findByTargetAndActiveOrderByIdAsc(final JpaTarget target, boolean active); /** * Retrieves latest {@link UpdateAction} for given target and @@ -99,9 +105,9 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return action if there is one with assigned target and module is part of * assigned {@link DistributionSet}. */ - @Query("Select a from Action a join a.distributionSet ds join ds.modules modul where a.target.controllerId = :target and modul = :module order by a.id desc") + @Query("Select a from JpaAction a join a.distributionSet ds join ds.modules modul where a.target.controllerId = :target and modul = :module order by a.id desc") List findActionByTargetAndSoftwareModule(@Param("target") final String targetId, - @Param("module") SoftwareModule module); + @Param("module") JpaSoftwareModule module); /** * Retrieves all {@link UpdateAction}s which are referring the given @@ -115,9 +121,9 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the {@link DistributionSet} on which will be filtered * @return the found {@link UpdateAction}s */ - @Query("Select a from Action a where a.target = :target and a.distributionSet = :ds order by a.id") - Page findByTargetAndDistributionSet(final Pageable pageable, @Param("target") final Target target, - @Param("ds") DistributionSet ds); + @Query("Select a from JpaAction a where a.target = :target and a.distributionSet = :ds order by a.id") + Page findByTargetAndDistributionSet(final Pageable pageable, @Param("target") final JpaTarget target, + @Param("ds") JpaDistributionSet ds); /** * Retrieves all {@link Action}s of a specific target, without pagination @@ -127,8 +133,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp * to search for * @return a list of actions according to the searched target */ - @Query("Select a from Action a where a.target = :target order by a.id") - List findByTarget(@Param("target") final Target target); + @Query("Select a from JpaAction a where a.target = :target order by a.id") + List findByTarget(@Param("target") final JpaTarget target); /** * Retrieves all {@link Action}s of a specific target and given active flag @@ -143,8 +149,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp * {@code false} for inactive * @return a paged list of actions ordered by action ID */ - @Query("Select a from Action a where a.target = :target and a.active= :active order by a.id") - Page findByActiveAndTarget(Pageable pageable, @Param("target") Target target, + @Query("Select a from JpaAction a where a.target = :target and a.active= :active order by a.id") + Page findByActiveAndTarget(Pageable pageable, @Param("target") JpaTarget target, @Param("active") boolean active); /** @@ -160,8 +166,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return a list of actions ordered by action ID */ @EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD) - @Query("Select a from Action a where a.target = :target and a.active= :active order by a.id") - List findByActiveAndTarget(@Param("target") Target target, @Param("active") boolean active); + @Query("Select a from JpaAction a where a.target = :target and a.active= :active order by a.id") + List findByActiveAndTarget(@Param("target") JpaTarget target, @Param("active") boolean active); /** * Updates all {@link Action} to inactive for all targets with given ID. @@ -174,8 +180,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE Action a SET a.active = false WHERE a IN :keySet AND a.target IN :targetsIds") - void setToInactive(@Param("keySet") List keySet, @Param("targetsIds") List targetsIds); + @Query("UPDATE JpaAction a SET a.active = false WHERE a IN :keySet AND a.target IN :targetsIds") + void setToInactive(@Param("keySet") List keySet, @Param("targetsIds") List targetsIds); /** * Switches the status of actions from one specific status into another, @@ -193,7 +199,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE Action a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false") + @Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false") void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List targetIds, @Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus); @@ -213,8 +219,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE Action a SET a.status = :statusToSet WHERE a.rollout = :rollout AND a.active = :active AND a.status = :currentStatus") - void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("rollout") Rollout rollout, + @Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.rollout = :rollout AND a.active = :active AND a.status = :currentStatus") + void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("rollout") JpaRollout rollout, @Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus); /** @@ -228,8 +234,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the status which the actions should not have * @return the found list of {@link Action}s */ - @Query("SELECT a FROM Action a WHERE a.active = true AND a.distributionSet.requiredMigrationStep = false AND a.target IN ?1 AND a.status != ?2") - List findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep( + @Query("SELECT a FROM JpaAction a WHERE a.active = true AND a.distributionSet.requiredMigrationStep = false AND a.target IN ?1 AND a.status != ?2") + List findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep( Collection targetIds, Action.Status notStatus); /** @@ -239,15 +245,15 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the target to count the {@link Action}s * @return the count of actions referring to the given target */ - Long countByTarget(Target target); + Long countByTarget(JpaTarget target); @Override @CacheEvict(value = "feedbackReceivedOverTime", allEntries = true) - List save(Iterable entities); + List save(Iterable entities); @Override @CacheEvict(value = "feedbackReceivedOverTime", allEntries = true) - S save(S entity); + S save(S entity); /** * Counts all {@link Action}s referring to the given DistributionSet. @@ -256,7 +262,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * DistributionSet to count the {@link Action}s from * @return the count of actions referring to the given distributionSet */ - Long countByDistributionSet(DistributionSet distributionSet); + Long countByDistributionSet(JpaDistributionSet distributionSet); /** * Counts all {@link Action}s referring to the given rollout. @@ -265,7 +271,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the rollout to count the {@link Action}s from * @return the count of actions referring to the given rollout */ - Long countByRollout(Rollout rollout); + Long countByRollout(JpaRollout rollout); /** * Counts all actions referring to a given rollout and rolloutgroup which @@ -286,8 +292,8 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return the count of actions referring the rollout and rolloutgroup and * are not in given states */ - Long countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(Rollout rollout, RolloutGroup rolloutGroup, - Status notStatus1, Status notStatus2, Status notStatus3); + Long countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(JpaRollout rollout, + JpaRolloutGroup rolloutGroup, Status notStatus1, Status notStatus2, Status notStatus3); /** * Counts all actions referring to a given rollout and rolloutgroup. @@ -298,7 +304,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the rolloutgroup the actions belong to * @return the count of actions referring to a rollout and rolloutgroup */ - Long countByRolloutAndRolloutGroup(Rollout rollout, RolloutGroup rolloutGroup); + Long countByRolloutAndRolloutGroup(JpaRollout rollout, JpaRolloutGroup rolloutGroup); /** * Counts all actions referring to a given rollout, rolloutgroup and status. @@ -329,7 +335,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * @return the actions referring a specific rollout and a specific parent * rolloutgroup in a specific status */ - List findByRolloutAndRolloutGroupParentAndStatus(Rollout rollout, RolloutGroup rolloutGroupParent, + List findByRolloutAndRolloutGroupParentAndStatus(JpaRollout rollout, JpaRolloutGroup rolloutGroupParent, Status actionStatus); /** @@ -341,7 +347,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the status of the actions * @return the actions referring a specific rollout an in a specific status */ - List findByRolloutAndStatus(Rollout rollout, Status actionStatus); + List findByRolloutAndStatus(JpaRollout rollout, Status actionStatus); /** * Get list of objects which has details of status and count of targets in @@ -351,7 +357,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * id of {@link Rollout} * @return list of objects with status and target count */ - @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status") + @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status") List getStatusCountByRolloutId(List rolloutId); /** @@ -362,7 +368,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * id of {@link Rollout} * @return list of objects with status and target count */ - @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status") + @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status") List getStatusCountByRolloutId(Long rolloutId); /** @@ -373,7 +379,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * id of {@link RolloutGroup} * @return list of objects with status and target count */ - @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status") + @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status") List getStatusCountByRolloutGroupId(Long rolloutGroupId); /** @@ -384,7 +390,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * list of id of {@link RolloutGroup} * @return list of objects with status and target count */ - @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status") + @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status") List getStatusCountByRolloutGroupId(List rolloutGroupId); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionStatusRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionStatusRepository.java index 61d95e15e..7a2c574df 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionStatusRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionStatusRepository.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -25,7 +27,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface ActionStatusRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Counts {@link ActionStatus} entries of given {@link Action} in @@ -35,7 +37,7 @@ public interface ActionStatusRepository * to count status entries * @return number of actions in repository */ - Long countByAction(Action action); + Long countByAction(JpaAction action); /** * Counts {@link ActionStatus} entries of given {@link Action} with given @@ -47,7 +49,7 @@ public interface ActionStatusRepository * to filter for * @return number of actions in repository */ - Long countByActionAndStatus(Action action, Status status); + Long countByActionAndStatus(JpaAction action, Status status); /** * Retrieves all {@link ActionStatus} entries from repository of given @@ -59,7 +61,7 @@ public interface ActionStatusRepository * of the status entries * @return pages list of {@link ActionStatus} entries */ - Page findByAction(Pageable pageReq, Action action); + Page findByAction(Pageable pageReq, JpaAction action); /** * Finds all status updates for the defined action and target including @@ -74,6 +76,6 @@ public interface ActionStatusRepository * @return Page with found targets */ @EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD) - Page getByAction(Pageable pageReq, Action action); + Page getByAction(Pageable pageReq, JpaAction action); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/BaseEntityRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/BaseEntityRepository.java index 693827803..92bec68a2 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/BaseEntityRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/BaseEntityRepository.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.io.Serializable; +import org.eclipse.hawkbit.repository.jpa.model.JpaTenantAwareBaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.repository.NoRepositoryBean; @@ -27,7 +28,7 @@ import org.springframework.transaction.annotation.Transactional; */ @NoRepositoryBean @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface BaseEntityRepository +public interface BaseEntityRepository extends PagingAndSortingRepository { /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DeploymentHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DeploymentHelper.java index f5123c792..f5d00862b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DeploymentHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DeploymentHelper.java @@ -15,10 +15,11 @@ import javax.persistence.EntityManager; import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; /** @@ -48,10 +49,10 @@ public final class DeploymentHelper { * * @return updated target */ - static Target updateTargetInfo(@NotNull final Target target, @NotNull final TargetUpdateStatus status, + static JpaTarget updateTargetInfo(@NotNull final JpaTarget target, @NotNull final TargetUpdateStatus status, final boolean setInstalledDate, final TargetInfoRepository targetInfoRepository, final EntityManager entityManager) { - final TargetInfo ts = target.getTargetInfo(); + final JpaTargetInfo ts = (JpaTargetInfo) target.getTargetInfo(); ts.setUpdateStatus(status); if (setInstalledDate) { @@ -77,7 +78,7 @@ public final class DeploymentHelper { * @param targetInfoRepository * for the operation */ - static void successCancellation(final Action action, final ActionRepository actionRepository, + static void successCancellation(final JpaAction action, final ActionRepository actionRepository, final TargetManagement targetManagement, final TargetInfoRepository targetInfoRepository, final EntityManager entityManager) { @@ -85,7 +86,7 @@ public final class DeploymentHelper { action.setActive(false); action.setStatus(Status.CANCELED); - final Target target = action.getTarget(); + final JpaTarget target = (JpaTarget) action.getTarget(); final List nextActiveActions = actionRepository.findByTargetAndActiveOrderByIdAsc(target, true).stream() .filter(a -> !a.getId().equals(action.getId())).collect(Collectors.toList()); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetMetadataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetMetadataRepository.java index 68cd380e5..7b8b1b20f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetMetadataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetMetadataRepository.java @@ -8,8 +8,9 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.transaction.annotation.Isolation; @@ -17,13 +18,10 @@ import org.springframework.transaction.annotation.Transactional; /** * {@link DistributionSetMetadata} repository. - * - * - * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetMetadataRepository - extends PagingAndSortingRepository, - JpaSpecificationExecutor { + extends PagingAndSortingRepository, + JpaSpecificationExecutor { } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetRepository.java index c7ab44145..1ab6cbe08 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetRepository.java @@ -11,10 +11,12 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.Collection; import java.util.List; -import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Tag; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -30,7 +32,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Finds {@link DistributionSet}s by assigned {@link Tag}. @@ -39,8 +41,8 @@ public interface DistributionSetRepository * to be found * @return list of found {@link DistributionSet}s */ - @Query(value = "Select Distinct ds from DistributionSet ds join ds.tags dst where dst = :tag") - List findByTag(@Param("tag") final DistributionSetTag tag); + @Query(value = "Select Distinct ds from JpaDistributionSet ds join ds.tags dst where dst = :tag") + List findByTag(@Param("tag") final JpaDistributionSetTag tag); /** * deletes the {@link DistributionSet}s with the given IDs. @@ -50,9 +52,12 @@ public interface DistributionSetRepository */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("update DistributionSet d set d.deleted = 1 where d.id in :ids") + @Query("update JpaDistributionSet d set d.deleted = 1 where d.id in :ids") void deleteDistributionSet(@Param("ids") Long... ids); + @Override + List findAll(Iterable ids); + /** * deletes {@link DistributionSet}s by the given IDs. * @@ -63,7 +68,7 @@ public interface DistributionSetRepository @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 - @Query("DELETE FROM DistributionSet d WHERE d.id IN ?1") + @Query("DELETE FROM JpaDistributionSet d WHERE d.id IN ?1") int deleteByIdIn(Collection ids); /** @@ -74,7 +79,7 @@ public interface DistributionSetRepository * to search for * @return {@link List} of found {@link DistributionSet}s */ - List findByModules(SoftwareModule module); + List findByModules(JpaSoftwareModule module); /** * Finds {@link DistributionSet}s based on given ID if they are not assigned @@ -84,7 +89,7 @@ public interface DistributionSetRepository * to search for * @return */ - @Query("select ac.distributionSet.id from Action ac where ac.distributionSet.id in :ids") + @Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids") List findAssignedDistributionSetsById(@Param("ids") Long... ids); /** @@ -98,7 +103,7 @@ public interface DistributionSetRepository * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable) */ @Override - List save(Iterable entities); + List save(Iterable entities); /** * Finds the distribution set for a specific action. @@ -107,8 +112,8 @@ public interface DistributionSetRepository * the action associated with the distribution set to find * @return the distribution set associated with the given action */ - @Query("select DISTINCT d from DistributionSet d join fetch d.modules m join d.actions a where a = :action") - DistributionSet findByAction(@Param("action") Action action); + @Query("select DISTINCT d from JpaDistributionSet d join fetch d.modules m join d.actions a where a = :action") + JpaDistributionSet findByAction(@Param("action") JpaAction action); /** * Counts {@link DistributionSet} instances of given type in the repository. @@ -117,7 +122,7 @@ public interface DistributionSetRepository * to search for * @return number of found {@link DistributionSet}s */ - long countByType(DistributionSetType type); + long countByType(JpaDistributionSetType type); /** * Counts {@link DistributionSet} with given diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java index 9e55a305b..d13316b91 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.TargetTag; @@ -24,7 +25,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetTagRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * deletes the {@link DistributionSet} with the given name. * @@ -43,7 +44,7 @@ public interface DistributionSetTagRepository * to filter on * @return the {@link DistributionSetTag} if found, otherwise null */ - DistributionSetTag findByNameEquals(final String tagName); + JpaDistributionSetTag findByNameEquals(final String tagName); /** * Returns all instances of the type. @@ -51,8 +52,8 @@ public interface DistributionSetTagRepository * @return all entities */ @Override - List findAll(); + List findAll(); @Override - List save(Iterable entities); + List save(Iterable entities); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java index 7c0d39b58..82754d7f8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java @@ -8,8 +8,9 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -23,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetTypeRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * @@ -34,7 +35,7 @@ public interface DistributionSetTypeRepository * false if undeleted ones * @return list of found {@link DistributionSetType}s */ - Page findByDeleted(Pageable pageable, boolean isDeleted); + Page findByDeleted(Pageable pageable, boolean isDeleted); /** * @param isDeleted @@ -54,5 +55,5 @@ public interface DistributionSetTypeRepository * @return the number of {@link DistributionSetType}s in the repository * assigned to the given software module type */ - Long countByElementsSmType(SoftwareModuleType softwareModuleType); + Long countByElementsSmType(JpaSoftwareModuleType softwareModuleType); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/EclipseLinkTargetInfoRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/EclipseLinkTargetInfoRepository.java index ca124f81c..93b861092 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/EclipseLinkTargetInfoRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/EclipseLinkTargetInfoRepository.java @@ -14,7 +14,7 @@ import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; -import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; @@ -40,7 +40,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void setTargetUpdateStatus(final TargetUpdateStatus status, final List targets) { final Query query = entityManager.createQuery( - "update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status"); + "update JpaTargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status"); query.setParameter("targets", targets); query.setParameter("status", status); @@ -50,7 +50,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) - public S save(final S entity) { + public S save(final S entity) { if (entity.isNew()) { entityManager.persist(entity); @@ -66,7 +66,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) public void deleteByTargetIdIn(final Collection targetIDs) { final javax.persistence.Query query = entityManager - .createQuery("DELETE FROM TargetInfo ti where ti.targetId IN :target"); + .createQuery("DELETE FROM JpaTargetInfo ti where ti.targetId IN :target"); query.setParameter("target", targetIDs); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactProviderRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactProviderRepository.java index 4a29afc4b..039c4917e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactProviderRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactProviderRepository.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider; import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; @@ -17,6 +18,6 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface ExternalArtifactProviderRepository extends BaseEntityRepository { +public interface ExternalArtifactProviderRepository extends BaseEntityRepository { } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactRepository.java index dfc8105dd..5845afbee 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/ExternalArtifactRepository.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact; import org.eclipse.hawkbit.repository.model.ExternalArtifact; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -19,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface ExternalArtifactRepository extends BaseEntityRepository { +public interface ExternalArtifactRepository extends BaseEntityRepository { /** * Searches for external artifact for a base software module. @@ -31,6 +32,6 @@ public interface ExternalArtifactRepository extends BaseEntityRepository */ - Page findBySoftwareModuleId(Pageable pageReq, final Long swId); + Page findBySoftwareModuleId(Pageable pageReq, final Long swId); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java index 7bae73a8b..93e0afc00 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java @@ -24,12 +24,16 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.GridFSDBFileNotFoundException; import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException; import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.ExternalArtifact; import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.specifications.SoftwareModuleSpecification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -88,7 +92,7 @@ public class JpaArtifactManagement implements ArtifactManagement { final String urlSuffix, final Long moduleId) { final SoftwareModule module = getModuleAndThrowExceptionIfThatFails(moduleId); - return externalArtifactRepository.save(new ExternalArtifact(externalRepository, urlSuffix, module)); + return externalArtifactRepository.save(new JpaExternalArtifact(externalRepository, urlSuffix, module)); } @Override @@ -97,7 +101,7 @@ public class JpaArtifactManagement implements ArtifactManagement { public ExternalArtifactProvider createExternalArtifactProvider(final String name, final String description, final String basePath, final String defaultUrlSuffix) { return externalArtifactProviderRepository - .save(new ExternalArtifactProvider(name, description, basePath, defaultUrlSuffix)); + .save(new JpaExternalArtifactProvider(name, description, basePath, defaultUrlSuffix)); } @Override @@ -142,7 +146,7 @@ public class JpaArtifactManagement implements ArtifactManagement { } existing.getSoftwareModule().removeArtifact(existing); - softwareModuleRepository.save(existing.getSoftwareModule()); + softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule()); externalArtifactRepository.delete(id); } @@ -156,7 +160,7 @@ public class JpaArtifactManagement implements ArtifactManagement { boolean artifactIsOnlyUsedByOneSoftwareModule = true; for (final LocalArtifact lArtifact : localArtifactRepository - .findByGridFsFileName(existing.getGridFsFileName())) { + .findByGridFsFileName(((JpaLocalArtifact) existing).getGridFsFileName())) { if (!lArtifact.getSoftwareModule().isDeleted() && Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) { artifactIsOnlyUsedByOneSoftwareModule = false; @@ -166,8 +170,8 @@ public class JpaArtifactManagement implements ArtifactManagement { if (artifactIsOnlyUsedByOneSoftwareModule) { try { - LOG.debug("deleting artifact from repository {}", existing.getGridFsFileName()); - artifactRepository.deleteBySha1(existing.getGridFsFileName()); + LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName()); + artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName()); } catch (final ArtifactStoreException e) { throw new ArtifactDeleteFailedException(e); } @@ -178,7 +182,7 @@ public class JpaArtifactManagement implements ArtifactManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void deleteLocalArtifact(final Long id) { - final LocalArtifact existing = localArtifactRepository.findOne(id); + final JpaLocalArtifact existing = localArtifactRepository.findOne(id); if (null == existing) { return; @@ -187,7 +191,7 @@ public class JpaArtifactManagement implements ArtifactManagement { deleteLocalArtifact(existing); existing.getSoftwareModule().removeArtifact(existing); - softwareModuleRepository.save(existing.getSoftwareModule()); + softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule()); localArtifactRepository.delete(id); } @@ -219,7 +223,7 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override public SoftwareModule findSoftwareModuleById(final Long id) { - final Specification spec = SoftwareModuleSpecification.byId(id); + final Specification spec = SoftwareModuleSpecification.byId(id); return softwareModuleRepository.findOne(spec); } @@ -246,9 +250,10 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override public DbArtifact loadLocalArtifactBinary(final LocalArtifact artifact) { - final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName()); + final DbArtifact result = artifactRepository + .getArtifactBySha1(((JpaLocalArtifact) artifact).getGridFsFileName()); if (result == null) { - throw new GridFSDBFileNotFoundException(artifact.getGridFsFileName()); + throw new GridFSDBFileNotFoundException(((JpaLocalArtifact) artifact).getGridFsFileName()); } return result; @@ -256,9 +261,9 @@ public class JpaArtifactManagement implements ArtifactManagement { private LocalArtifact storeArtifactMetadata(final SoftwareModule softwareModule, final String providedFilename, final DbArtifact result, final LocalArtifact existing) { - LocalArtifact artifact = existing; + JpaLocalArtifact artifact = (JpaLocalArtifact) existing; if (existing == null) { - artifact = new LocalArtifact(result.getHashes().getSha1(), providedFilename, softwareModule); + artifact = new JpaLocalArtifact(result.getHashes().getSha1(), providedFilename, softwareModule); } artifact.setMd5Hash(result.getHashes().getMd5()); artifact.setSha1Hash(result.getHashes().getSha1()); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index a7706440d..c7a229bf0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.net.URI; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -24,19 +25,25 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException; import org.eclipse.hawkbit.repository.exception.ToManyStatusEntriesException; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; +import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.ActionStatus_; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.model.Target_; import org.eclipse.hawkbit.repository.model.TenantConfiguration; -import org.eclipse.hawkbit.repository.specifications.ActionSpecifications; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; @@ -46,6 +53,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -116,7 +124,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override public Action getActionForDownloadByTargetAndSoftwareModule(final String controllerId, final SoftwareModule module) { - final List action = actionRepository.findActionByTargetAndSoftwareModule(controllerId, module); + final List action = actionRepository.findActionByTargetAndSoftwareModule(controllerId, + (JpaSoftwareModule) module); if (action.isEmpty() || action.get(0).isCancelingOrCanceled()) { throw new EntityNotFoundException( @@ -137,12 +146,12 @@ public class JpaControllerManagement implements ControllerManagement { @Override public List findActionByTargetAndActive(final Target target) { - return actionRepository.findByTargetAndActiveOrderByIdAsc(target, true); + return actionRepository.findByTargetAndActiveOrderByIdAsc((JpaTarget) target, true); } @Override public List findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) { - return softwareModuleRepository.findByAssignedTo(distributionSet); + return new ArrayList<>(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet)); } @Override @@ -154,13 +163,13 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) { - final Specification spec = (targetRoot, query, cb) -> cb.equal(targetRoot.get(Target_.controllerId), - controllerId); + final Specification spec = (targetRoot, query, cb) -> cb + .equal(targetRoot.get(JpaTarget_.controllerId), controllerId); - Target target = targetRepository.findOne(spec); + JpaTarget target = targetRepository.findOne(spec); if (target == null) { - target = new Target(controllerId); + target = new JpaTarget(controllerId); target.setDescription("Plug and Play target: " + controllerId); target.setName(controllerId); return targetManagement.createTarget(target, TargetUpdateStatus.REGISTERED, System.currentTimeMillis(), @@ -175,7 +184,7 @@ public class JpaControllerManagement implements ControllerManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) public TargetInfo updateTargetStatus(final TargetInfo targetInfo, final TargetUpdateStatus status, final Long lastTargetQuery, final URI address) { - final TargetInfo mtargetInfo = entityManager.merge(targetInfo); + final JpaTargetInfo mtargetInfo = (JpaTargetInfo) entityManager.merge(targetInfo); if (status != null) { mtargetInfo.setUpdateStatus(status); } @@ -192,7 +201,7 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Action addCancelActionStatus(final ActionStatus actionStatus) { - final Action action = actionStatus.getAction(); + final JpaAction action = (JpaAction) actionStatus.getAction(); checkForToManyStatusEntries(action); action.setStatus(actionStatus.getStatus()); @@ -217,7 +226,7 @@ public class JpaControllerManagement implements ControllerManagement { default: } actionRepository.save(action); - actionStatusRepository.save(actionStatus); + actionStatusRepository.save((JpaActionStatus) actionStatus); return action; } @@ -226,14 +235,14 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus) { - final Action action = actionStatus.getAction(); + final JpaAction action = (JpaAction) actionStatus.getAction(); if (!action.isActive()) { LOG.debug("Update of actionStatus {} for action {} not possible since action not active anymore.", actionStatus.getId(), action.getId()); return action; } - return handleAddUpdateActionStatus(actionStatus, action); + return handleAddUpdateActionStatus((JpaActionStatus) actionStatus, action); } /** @@ -243,11 +252,11 @@ public class JpaControllerManagement implements ControllerManagement { * @param action * @return */ - private Action handleAddUpdateActionStatus(final ActionStatus actionStatus, final Action action) { + private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) { LOG.debug("addUpdateActionStatus for action {}", action.getId()); - final Action mergedAction = entityManager.merge(action); - Target mergedTarget = mergedAction.getTarget(); + final JpaAction mergedAction = entityManager.merge(action); + JpaTarget mergedTarget = (JpaTarget) mergedAction.getTarget(); // check for a potential DOS attack checkForToManyStatusEntries(action); @@ -284,7 +293,7 @@ public class JpaControllerManagement implements ControllerManagement { targetManagement.updateTarget(mergedTarget); } - private void checkForToManyStatusEntries(final Action action) { + private void checkForToManyStatusEntries(final JpaAction action) { if (securityProperties.getDos().getMaxStatusEntriesPerAction() > 0) { final Long statusCount = actionStatusRepository.countByAction(action); @@ -299,11 +308,11 @@ public class JpaControllerManagement implements ControllerManagement { } } - private void handleFinishedAndStoreInTargetStatus(final Target target, final Action action) { + private void handleFinishedAndStoreInTargetStatus(final JpaTarget target, final JpaAction action) { action.setActive(false); action.setStatus(Status.FINISHED); - final TargetInfo targetInfo = target.getTargetInfo(); - final DistributionSet ds = entityManager.merge(action.getDistributionSet()); + final JpaTargetInfo targetInfo = (JpaTargetInfo) target.getTargetInfo(); + final JpaDistributionSet ds = (JpaDistributionSet) entityManager.merge(action.getDistributionSet()); targetInfo.setInstalledDistributionSet(ds); if (target.getAssignedDistributionSet() != null && targetInfo.getInstalledDistributionSet() != null && target .getAssignedDistributionSet().getId().equals(targetInfo.getInstalledDistributionSet().getId())) { @@ -321,15 +330,16 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Target updateControllerAttributes(final String controllerId, final Map data) { - final Target target = targetRepository.findByControllerId(controllerId); + final JpaTarget target = targetRepository.findByControllerId(controllerId); if (target == null) { throw new EntityNotFoundException(controllerId); } - target.getTargetInfo().getControllerAttributes().putAll(data); + final JpaTargetInfo targetInfo = (JpaTargetInfo) target.getTargetInfo(); + targetInfo.getControllerAttributes().putAll(data); - if (target.getTargetInfo().getControllerAttributes().size() > securityProperties.getDos() + if (targetInfo.getControllerAttributes().size() > securityProperties.getDos() .getMaxAttributeEntriesPerTarget()) { LOG_DOS.info("Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!", securityProperties.getDos().getMaxAttributeEntriesPerTarget()); @@ -337,8 +347,8 @@ public class JpaControllerManagement implements ControllerManagement { String.valueOf(securityProperties.getDos().getMaxAttributeEntriesPerTarget())); } - target.getTargetInfo().setLastTargetQuery(System.currentTimeMillis()); - target.getTargetInfo().setRequestControllerAttributes(false); + targetInfo.setLastTargetQuery(System.currentTimeMillis()); + targetInfo.setRequestControllerAttributes(false); return targetRepository.save(target); } @@ -346,7 +356,7 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Action registerRetrieved(final Action action, final String message) { - return handleRegisterRetrieved(action, message); + return handleRegisterRetrieved((JpaAction) action, message); } /** @@ -360,7 +370,7 @@ public class JpaControllerManagement implements ControllerManagement { * @return the updated action in case the status has been changed to * {@link Status#RETRIEVED} */ - private Action handleRegisterRetrieved(final Action action, final String message) { + private Action handleRegisterRetrieved(final JpaAction action, final String message) { // do a manual query with CriteriaBuilder to avoid unnecessary field // queries and an extra // count query made by spring-data when using pageable requests, we @@ -369,11 +379,11 @@ public class JpaControllerManagement implements ControllerManagement { // or not. final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery queryActionStatus = cb.createQuery(Object[].class); - final Root actionStatusRoot = queryActionStatus.from(ActionStatus.class); + final Root actionStatusRoot = queryActionStatus.from(JpaActionStatus.class); final CriteriaQuery query = queryActionStatus - .multiselect(actionStatusRoot.get(ActionStatus_.id), actionStatusRoot.get(ActionStatus_.status)) - .where(cb.equal(actionStatusRoot.get(ActionStatus_.action), action)) - .orderBy(cb.desc(actionStatusRoot.get(ActionStatus_.id))); + .multiselect(actionStatusRoot.get(JpaActionStatus_.id), actionStatusRoot.get(JpaActionStatus_.status)) + .where(cb.equal(actionStatusRoot.get(JpaActionStatus_.action), action)) + .orderBy(cb.desc(actionStatusRoot.get(JpaActionStatus_.id))); final List resultList = entityManager.createQuery(query).setFirstResult(0).setMaxResults(1) .getResultList(); @@ -387,14 +397,14 @@ public class JpaControllerManagement implements ControllerManagement { if (resultList.isEmpty() || resultList.get(0)[1] != Status.RETRIEVED) { // document that the status has been retrieved actionStatusRepository - .save(new ActionStatus(action, Status.RETRIEVED, System.currentTimeMillis(), message)); + .save(new JpaActionStatus(action, Status.RETRIEVED, System.currentTimeMillis(), message)); // don't change the action status itself in case the action is in // canceling state otherwise // we modify the action status and the controller won't get the // cancel job anymore. if (!action.isCancelingOrCanceled()) { - final Action actionMerge = entityManager.merge(action); + final JpaAction actionMerge = entityManager.merge(action); actionMerge.setStatus(Status.RETRIEVED); return actionRepository.save(actionMerge); } @@ -406,7 +416,7 @@ public class JpaControllerManagement implements ControllerManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void addInformationalActionStatus(final ActionStatus statusMessage) { - actionStatusRepository.save(statusMessage); + actionStatusRepository.save((JpaActionStatus) statusMessage); } @Override @@ -421,4 +431,10 @@ public class JpaControllerManagement implements ControllerManagement { public TargetInfo updateLastTargetQuery(final TargetInfo target, final URI address) { return updateTargetStatus(target, null, System.currentTimeMillis(), address); } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public ActionStatus generateActionStatus() { + return new JpaActionStatus(); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index 0c5df3b3f..3dea0e549 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -32,6 +33,7 @@ import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; +import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult; import org.eclipse.hawkbit.repository.TargetManagement; @@ -39,24 +41,32 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.ActionWithStatusCount; -import org.eclipse.hawkbit.repository.model.Action_; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.DistributionSet_; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Rollout_; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.specifications.TargetSpecifications; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,12 +74,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -126,7 +138,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { public DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset, final List targets) { - return assignDistributionSetByTargetId(pset, + return assignDistributionSetByTargetId((JpaDistributionSet) pset, targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), ActionType.FORCED, Action.NO_FORCE_TIME); @@ -159,7 +171,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final Collection targets) { - final DistributionSet set = distributoinSetRepository.findOne(dsID); + final JpaDistributionSet set = distributoinSetRepository.findOne(dsID); if (set == null) { throw new EntityNotFoundException( String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID)); @@ -174,13 +186,13 @@ public class JpaDeploymentManagement implements DeploymentManagement { @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final Collection targets, final Rollout rollout, final RolloutGroup rolloutGroup) { - final DistributionSet set = distributoinSetRepository.findOne(dsID); + final JpaDistributionSet set = distributoinSetRepository.findOne(dsID); if (set == null) { throw new EntityNotFoundException( String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID)); } - return assignDistributionSetToTargets(set, targets, rollout, rolloutGroup); + return assignDistributionSetToTargets(set, targets, (JpaRollout) rollout, (JpaRolloutGroup) rolloutGroup); } /** @@ -201,9 +213,9 @@ public class JpaDeploymentManagement implements DeploymentManagement { * {@link SoftwareModuleType} are not assigned as define by the * {@link DistributionSetType}. */ - private DistributionSetAssignmentResult assignDistributionSetToTargets(@NotNull final DistributionSet set, - final Collection targetsWithActionType, final Rollout rollout, - final RolloutGroup rolloutGroup) { + private DistributionSetAssignmentResult assignDistributionSetToTargets(@NotNull final JpaDistributionSet set, + final Collection targetsWithActionType, final JpaRollout rollout, + final JpaRolloutGroup rolloutGroup) { if (!set.isComplete()) { throw new IncompleteDistributionSetException( @@ -223,7 +235,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { // maximum 1000 elements, so we need to split the entries here and // execute multiple statements we take the target only into account if // the requested operation is no duplicate of a previous one - final List targets = Lists.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream() + final List targets = Lists.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream() .map(ids -> targetRepository .findAll(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, set.getId()))) .flatMap(t -> t.stream()).collect(Collectors.toList()); @@ -262,7 +274,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { targetIds.forEach(tIds -> targetRepository.setAssignedDistributionSet(set, System.currentTimeMillis(), currentUser, tIds)); targetIds.forEach(tIds -> targetInfoRepository.setTargetUpdateStatus(TargetUpdateStatus.PENDING, tIds)); - final Map targetIdsToActions = actionRepository + final Map targetIdsToActions = actionRepository .save(targets.stream().map(t -> createTargetAction(targetsWithActionMap, t, set, rollout, rolloutGroup)) .collect(Collectors.toList())) .stream().collect(Collectors.toMap(a -> a.getTarget().getControllerId(), Function.identity())); @@ -272,7 +284,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { // of the action itself and with this action status we have a nicer // action history. targetIdsToActions.values().forEach(action -> { - final ActionStatus actionStatus = new ActionStatus(); + final JpaActionStatus actionStatus = new JpaActionStatus(); actionStatus.setAction(action); actionStatus.setOccurredAt(action.getCreatedAt()); actionStatus.setStatus(Status.RUNNING); @@ -289,7 +301,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { LOG.debug("assignDistribution({}) finished {}", set, result); - final List softwareModules = softwareModuleRepository.findByAssignedTo(set); + final List softwareModules = softwareModuleRepository.findByAssignedTo(set); // detaching as it is not necessary to persist the set itself entityManager.detach(set); @@ -299,16 +311,17 @@ public class JpaDeploymentManagement implements DeploymentManagement { return result; } - private void sendDistributionSetAssignmentEvent(final List targets, final Set targetIdsCancellList, - final Map targetIdsToActions, final List softwareModules) { + private void sendDistributionSetAssignmentEvent(final List targets, final Set targetIdsCancellList, + final Map targetIdsToActions, final List softwareModules) { targets.stream().filter(t -> !!!targetIdsCancellList.contains(t.getId())) .forEach(t -> assignDistributionSetEvent(t, targetIdsToActions.get(t.getControllerId()).getId(), softwareModules)); } - private static Action createTargetAction(final Map targetsWithActionMap, - final Target target, final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) { - final Action actionForTarget = new Action(); + private static JpaAction createTargetAction(final Map targetsWithActionMap, + final JpaTarget target, final JpaDistributionSet set, final JpaRollout rollout, + final JpaRolloutGroup rolloutGroup) { + final JpaAction actionForTarget = new JpaAction(); final TargetWithActionType targetWithActionType = targetsWithActionMap.get(target.getControllerId()); actionForTarget.setActionType(targetWithActionType.getActionType()); actionForTarget.setForcedTime(targetWithActionType.getForceTime()); @@ -332,9 +345,12 @@ public class JpaDeploymentManagement implements DeploymentManagement { * @param softwareModules * the software modules which have been assigned */ - private void assignDistributionSetEvent(final Target target, final Long actionId, - final List softwareModules) { - target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING); + private void assignDistributionSetEvent(final JpaTarget target, final Long actionId, + final List modules) { + ((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection softwareModules = (Collection) modules; afterCommit.afterCommit(() -> { eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo())); eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), @@ -357,14 +373,14 @@ public class JpaDeploymentManagement implements DeploymentManagement { // Figure out if there are potential target/action combinations that // need to be considered // for cancelation - final List activeActions = actionRepository + final List activeActions = actionRepository .findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(targetsIds, Action.Status.CANCELING); activeActions.forEach(action -> { action.setStatus(Status.CANCELING); // document that the status has been retrieved - actionStatusRepository.save(new ActionStatus(action, Status.CANCELING, System.currentTimeMillis(), + actionStatusRepository.save(new JpaActionStatus(action, Status.CANCELING, System.currentTimeMillis(), "manual cancelation requested")); cancelAssignDistributionSetEvent(action.getTarget(), action.getId()); @@ -378,7 +394,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { } - private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final DistributionSet set, + private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final JpaDistributionSet set, @NotEmpty final List tIDs, final ActionType actionType, final long forcedTime) { return assignDistributionSetToTargets(set, tIDs.stream() @@ -394,14 +410,14 @@ public class JpaDeploymentManagement implements DeploymentManagement { if (action.isCancelingOrCanceled()) { throw new CancelActionNotAllowedException("Actions in canceling or canceled state cannot be canceled"); } - final Action myAction = entityManager.merge(action); + final JpaAction myAction = (JpaAction) entityManager.merge(action); if (myAction.isActive()) { LOG.debug("action ({}) was still active. Change to {}.", action, Status.CANCELING); myAction.setStatus(Status.CANCELING); // document that the status has been retrieved - actionStatusRepository.save(new ActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(), + actionStatusRepository.save(new JpaActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(), "manual cancelation requested")); final Action saveAction = actionRepository.save(myAction); cancelAssignDistributionSetEvent(target, myAction.getId()); @@ -431,7 +447,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Modifying @Transactional(isolation = Isolation.READ_COMMITTED) public Action forceQuitAction(final Action action) { - final Action mergedAction = entityManager.merge(action); + final JpaAction mergedAction = (JpaAction) entityManager.merge(action); if (!mergedAction.isCancelingOrCanceled()) { throw new ForceQuitActionNotAllowedException( @@ -446,7 +462,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { LOG.warn("action ({}) was still activ and has been force quite.", action); // document that the status has been retrieved - actionStatusRepository.save(new ActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(), + actionStatusRepository.save(new JpaActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(), "A force quit has been performed.")); DeploymentHelper.successCancellation(mergedAction, actionRepository, targetManagement, targetInfoRepository, @@ -468,7 +484,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { final List targetIds = targets.stream().map(t -> t.getId()).collect(Collectors.toList()); actionRepository.switchStatus(Action.Status.CANCELED, targetIds, false, Action.Status.SCHEDULED); targets.forEach(target -> { - final Action action = new Action(); + final JpaAction action = new JpaAction(); action.setTarget(target); action.setActive(false); action.setDistributionSet(distributionSet); @@ -486,8 +502,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Transactional(isolation = Isolation.READ_COMMITTED) public Action startScheduledAction(final Action action) { - final Action mergedAction = entityManager.merge(action); - final Target mergedTarget = entityManager.merge(action.getTarget()); + final JpaAction mergedAction = (JpaAction) entityManager.merge(action); + final JpaTarget mergedTarget = (JpaTarget) entityManager.merge(action.getTarget()); // check if we need to override running update actions final Set overrideObsoleteUpdateActions = overrideObsoleteUpdateActions( @@ -509,14 +525,14 @@ public class JpaDeploymentManagement implements DeploymentManagement { mergedAction.setStatus(Status.RUNNING); final Action savedAction = actionRepository.save(mergedAction); - final ActionStatus actionStatus = new ActionStatus(); + final JpaActionStatus actionStatus = new JpaActionStatus(); actionStatus.setAction(action); actionStatus.setOccurredAt(action.getCreatedAt()); actionStatus.setStatus(Status.RUNNING); actionStatusRepository.save(actionStatus); mergedTarget.setAssignedDistributionSet(action.getDistributionSet()); - final TargetInfo targetInfo = mergedTarget.getTargetInfo(); + final JpaTargetInfo targetInfo = (JpaTargetInfo) mergedTarget.getTargetInfo(); targetInfo.setUpdateStatus(TargetUpdateStatus.PENDING); targetRepository.save(mergedTarget); targetInfoRepository.save(targetInfo); @@ -524,11 +540,11 @@ public class JpaDeploymentManagement implements DeploymentManagement { // in case we canceled an action before for this target, then don't fire // assignment event if (!overrideObsoleteUpdateActions.contains(savedAction.getId())) { - final List softwareModules = softwareModuleRepository - .findByAssignedTo(action.getDistributionSet()); + final List softwareModules = softwareModuleRepository + .findByAssignedTo((JpaDistributionSet) action.getDistributionSet()); // send distribution set assignment event - assignDistributionSetEvent(mergedAction.getTarget(), mergedAction.getId(), softwareModules); + assignDistributionSetEvent((JpaTarget) mergedAction.getTarget(), mergedAction.getId(), softwareModules); } return savedAction; } @@ -545,84 +561,93 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override public Slice findActionsByTarget(final Pageable pageable, final Target target) { - return actionRepository.findByTarget(pageable, target); + return actionRepository.findByTarget(pageable, (JpaTarget) target); } @Override public List findActionsByTarget(final Target target) { - return actionRepository.findByTarget(target); + return actionRepository.findByTarget((JpaTarget) target); } @Override public List findActionsWithStatusCountByTargetOrderByIdDesc(final Target target) { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery(ActionWithStatusCount.class); - final Root actionRoot = query.from(Action.class); - final ListJoin actionStatusJoin = actionRoot.join(Action_.actionStatus, JoinType.LEFT); - final Join actionDsJoin = actionRoot.join(Action_.distributionSet); - final Join actionRolloutJoin = actionRoot.join(Action_.rollout, JoinType.LEFT); + final Root actionRoot = query.from(JpaAction.class); + final ListJoin actionStatusJoin = actionRoot.join(JpaAction_.actionStatus, + JoinType.LEFT); + final Join actionDsJoin = actionRoot.join(JpaAction_.distributionSet); + final Join actionRolloutJoin = actionRoot.join(JpaAction_.rollout, JoinType.LEFT); final CriteriaQuery multiselect = query.distinct(true).multiselect( - actionRoot.get(Action_.id), actionRoot.get(Action_.actionType), actionRoot.get(Action_.active), - actionRoot.get(Action_.forcedTime), actionRoot.get(Action_.status), actionRoot.get(Action_.createdAt), - actionRoot.get(Action_.lastModifiedAt), actionDsJoin.get(DistributionSet_.id), - actionDsJoin.get(DistributionSet_.name), actionDsJoin.get(DistributionSet_.version), - cb.count(actionStatusJoin), actionRolloutJoin.get(Rollout_.name)); - multiselect.where(cb.equal(actionRoot.get(Action_.target), target)); - multiselect.orderBy(cb.desc(actionRoot.get(Action_.id))); - multiselect.groupBy(actionRoot.get(Action_.id)); + actionRoot.get(JpaAction_.id), actionRoot.get(JpaAction_.actionType), actionRoot.get(JpaAction_.active), + actionRoot.get(JpaAction_.forcedTime), actionRoot.get(JpaAction_.status), + actionRoot.get(JpaAction_.createdAt), actionRoot.get(JpaAction_.lastModifiedAt), + actionDsJoin.get(JpaDistributionSet_.id), actionDsJoin.get(JpaDistributionSet_.name), + actionDsJoin.get(JpaDistributionSet_.version), cb.count(actionStatusJoin), + actionRolloutJoin.get(JpaRollout_.name)); + multiselect.where(cb.equal(actionRoot.get(JpaAction_.target), target)); + multiselect.orderBy(cb.desc(actionRoot.get(JpaAction_.id))); + multiselect.groupBy(actionRoot.get(JpaAction_.id)); return entityManager.createQuery(multiselect).getResultList(); } @Override - public Slice findActionsByTarget(final Specification specifiction, final Target target, - final Pageable pageable) { + public Page findActionsByTarget(final String rsqlParam, final Target target, final Pageable pageable) { + final Specification specification = RSQLUtility.parse(rsqlParam, ActionFields.class); - return actionRepository.findAll((Specification) (root, query, cb) -> cb - .and(specifiction.toPredicate(root, query, cb), cb.equal(root.get(Action_.target), target)), pageable); + return convertAcPage(actionRepository.findAll((Specification) (root, query, cb) -> cb + .and(specification.toPredicate(root, query, cb), cb.equal(root.get(JpaAction_.target), target)), + pageable)); + } + + private static Page convertAcPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override public Slice findActionsByTarget(final Target foundTarget, final Pageable pageable) { - return actionRepository.findByTarget(pageable, foundTarget); + return actionRepository.findByTarget(pageable, (JpaTarget) foundTarget); } @Override public Page findActiveActionsByTarget(final Pageable pageable, final Target target) { - return actionRepository.findByActiveAndTarget(pageable, target, true); + return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, true); } @Override public List findActiveActionsByTarget(final Target target) { - return actionRepository.findByActiveAndTarget(target, true); + return actionRepository.findByActiveAndTarget((JpaTarget) target, true); } @Override public List findInActiveActionsByTarget(final Target target) { - return actionRepository.findByActiveAndTarget(target, false); + return actionRepository.findByActiveAndTarget((JpaTarget) target, false); } @Override public Page findInActiveActionsByTarget(final Pageable pageable, final Target target) { - return actionRepository.findByActiveAndTarget(pageable, target, false); + return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, false); } @Override public Long countActionsByTarget(final Target target) { - return actionRepository.countByTarget(target); + return actionRepository.countByTarget((JpaTarget) target); } @Override - public Long countActionsByTarget(final Specification spec, final Target target) { + public Long countActionsByTarget(final String rsqlParam, final Target target) { + final Specification spec = RSQLUtility.parse(rsqlParam, ActionFields.class); + return actionRepository.count((root, query, cb) -> cb.and(spec.toPredicate(root, query, cb), - cb.equal(root.get(Action_.target), target))); + cb.equal(root.get(JpaAction_.target), target))); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Action forceTargetAction(final Long actionId) { - final Action action = actionRepository.findOne(actionId); + final JpaAction action = actionRepository.findOne(actionId); if (action != null && !action.isForced()) { action.setActionType(ActionType.FORCED); return actionRepository.save(action); @@ -634,20 +659,27 @@ public class JpaDeploymentManagement implements DeploymentManagement { public Page findActionStatusByAction(final Pageable pageReq, final Action action, final boolean withMessages) { if (withMessages) { - return actionStatusRepository.getByAction(pageReq, action); + return actionStatusRepository.getByAction(pageReq, (JpaAction) action); } else { - return actionStatusRepository.findByAction(pageReq, action); + return actionStatusRepository.findByAction(pageReq, (JpaAction) action); } } @Override public List findActionsByRolloutGroupParentAndStatus(final Rollout rollout, final RolloutGroup rolloutGroupParent, final Action.Status actionStatus) { - return actionRepository.findByRolloutAndRolloutGroupParentAndStatus(rollout, rolloutGroupParent, actionStatus); + return actionRepository.findByRolloutAndRolloutGroupParentAndStatus((JpaRollout) rollout, + (JpaRolloutGroup) rolloutGroupParent, actionStatus); } @Override public List findActionsByRolloutAndStatus(final Rollout rollout, final Action.Status actionStatus) { - return actionRepository.findByRolloutAndStatus(rollout, actionStatus); + return actionRepository.findByRolloutAndStatus((JpaRollout) rollout, actionStatus); + } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public Action generateAction() { + return new JpaAction(); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index da999e7cb..4e33d4960 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -24,28 +24,36 @@ import javax.persistence.EntityManager; import org.eclipse.hawkbit.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; +import org.eclipse.hawkbit.repository.DistributionSetFields; import org.eclipse.hawkbit.repository.DistributionSetFilter; import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder; import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; +import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata_; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.DistributionSet_; -import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.specifications.DistributionSetSpecification; -import org.eclipse.hawkbit.repository.specifications.DistributionSetTypeSpecification; -import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -54,6 +62,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -111,12 +120,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection dsIds, final String tagName) { - final Iterable sets = findDistributionSetListWithDetails(dsIds); + final List sets = findDistributionSetListWithDetails(dsIds); final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName); DistributionSetTagAssignmentResult result; - final List toBeChangedDSs = new ArrayList<>(); - for (final DistributionSet set : sets) { + final List toBeChangedDSs = new ArrayList<>(); + for (final JpaDistributionSet set : sets) { if (set.getTags().add(myTag)) { toBeChangedDSs.add(set); } @@ -124,17 +133,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // un-assignment case if (toBeChangedDSs.isEmpty()) { - for (final DistributionSet set : sets) { + for (final JpaDistributionSet set : sets) { if (set.getTags().remove(myTag)) { toBeChangedDSs.add(set); } } result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0, - toBeChangedDSs.size(), Collections.emptyList(), distributionSetRepository.save(toBeChangedDSs), - myTag); + toBeChangedDSs.size(), Collections.emptyList(), + new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), myTag); } else { result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(), - 0, distributionSetRepository.save(toBeChangedDSs), Collections.emptyList(), myTag); + 0, new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), Collections.emptyList(), myTag); } final DistributionSetTagAssignmentResult resultAssignment = result; @@ -145,8 +154,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { return result; } - @Override - public List findDistributionSetListWithDetails(final Collection distributionIdSet) { + private List findDistributionSetListWithDetails(final Collection distributionIdSet) { return distributionSetRepository.findAll(DistributionSetSpecification.byIds(distributionIdSet)); } @@ -156,8 +164,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { public DistributionSet updateDistributionSet(final DistributionSet ds) { checkNotNull(ds.getId()); final DistributionSet persisted = findDistributionSetByIdWithDetails(ds.getId()); - checkDistributionSetSoftwareModulesIsAllowedToModify(ds, persisted.getModules()); - return distributionSetRepository.save(ds); + checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, persisted.getModules()); + return distributionSetRepository.save((JpaDistributionSet) ds); } @Override @@ -196,7 +204,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { if (dSet.getType() == null) { dSet.setType(systemManagement.getTenantMetadata().getDefaultDsType()); } - return distributionSetRepository.save(dSet); + return distributionSetRepository.save((JpaDistributionSet) dSet); } private void prepareDsSave(final DistributionSet dSet) { @@ -220,18 +228,22 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { ds.setType(systemManagement.getTenantMetadata().getDefaultDsType()); } } - return distributionSetRepository.save(distributionSets); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection toSave = (Collection) distributionSets; + + return new ArrayList<>(distributionSetRepository.save(toSave)); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public DistributionSet assignSoftwareModules(final DistributionSet ds, final Set softwareModules) { - checkDistributionSetSoftwareModulesIsAllowedToModify(ds, softwareModules); + checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules); for (final SoftwareModule softwareModule : softwareModules) { ds.addModule(softwareModule); } - return distributionSetRepository.save(ds); + return distributionSetRepository.save((JpaDistributionSet) ds); } @Override @@ -241,8 +253,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { final Set softwareModules = new HashSet<>(); softwareModules.add(softwareModule); ds.removeModule(softwareModule); - checkDistributionSetSoftwareModulesIsAllowedToModify(ds, softwareModules); - return distributionSetRepository.save(ds); + checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules); + return distributionSetRepository.save((JpaDistributionSet) ds); } @Override @@ -251,7 +263,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { public DistributionSetType updateDistributionSetType(final DistributionSetType dsType) { checkNotNull(dsType.getId()); - final DistributionSetType persisted = distributionSetTypeRepository.findOne(dsType.getId()); + final JpaDistributionSetType persisted = distributionSetTypeRepository.findOne(dsType.getId()); // throw exception if user tries to update a DS type that is already in // use @@ -261,25 +273,36 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { dsType.getName())); } - return distributionSetTypeRepository.save(dsType); + return distributionSetTypeRepository.save((JpaDistributionSetType) dsType); } @Override - public Page findDistributionSetTypesAll(final Specification spec, - final Pageable pageable) { - return distributionSetTypeRepository.findAll(spec, pageable); + public Page findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, + DistributionSetTypeFields.class); + + return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable)); + } + + private static Page convertDsTPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override public Page findDistributionSetTypesAll(final Pageable pageable) { - return distributionSetTypeRepository.findByDeleted(pageable, false); + return convertDsTPage(distributionSetTypeRepository.findByDeleted(pageable, false)); } @Override public Page findDistributionSetsByFilters(final Pageable pageable, final DistributionSetFilter distributionSetFilter) { - final List> specList = buildDistributionSetSpecifications(distributionSetFilter); - return findByCriteriaAPI(pageable, specList); + final List> specList = buildDistributionSetSpecifications( + distributionSetFilter); + return convertDsPage(findByCriteriaAPI(pageable, specList)); + } + + private static Page convertDsPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } /** @@ -291,7 +314,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { */ private DistributionSet findDistributionSetsByFiltersAndInstalledOrAssignedTarget( final DistributionSetFilter distributionSetFilter) { - final List> specList = buildDistributionSetSpecifications(distributionSetFilter); + final List> specList = buildDistributionSetSpecifications( + distributionSetFilter); if (specList == null || specList.isEmpty()) { return null; } @@ -301,30 +325,33 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public Page findDistributionSetsAll(final Pageable pageReq, final Boolean deleted, final Boolean complete) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); if (deleted != null) { - final Specification spec = DistributionSetSpecification.isDeleted(deleted); + final Specification spec = DistributionSetSpecification.isDeleted(deleted); specList.add(spec); } if (complete != null) { - final Specification spec = DistributionSetSpecification.isCompleted(complete); + final Specification spec = DistributionSetSpecification.isCompleted(complete); specList.add(spec); } - return findByCriteriaAPI(pageReq, specList); + return convertDsPage(findByCriteriaAPI(pageReq, specList)); } @Override - public Page findDistributionSetsAll(final Specification spec, - final Pageable pageReq, final Boolean deleted) { - final List> specList = new ArrayList<>(); + public Page findDistributionSetsAll(final String rsqlParam, final Pageable pageReq, + final Boolean deleted) { + + final Specification spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class); + + final List> specList = new ArrayList<>(); if (deleted != null) { specList.add(DistributionSetSpecification.isDeleted(deleted)); } specList.add(spec); - return findByCriteriaAPI(pageReq, specList); + return convertDsPage(findByCriteriaAPI(pageReq, specList)); } @Override @@ -371,23 +398,23 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public DistributionSet findDistributionSetByNameAndVersion(final String distributionName, final String version) { - final Specification spec = DistributionSetSpecification + final Specification spec = DistributionSetSpecification .equalsNameAndVersionIgnoreCase(distributionName, version); return distributionSetRepository.findOne(spec); } @Override - public Iterable findDistributionSetList(final Collection dist) { - return distributionSetRepository.findAll(dist); + public List findDistributionSetsAll(final Collection dist) { + return new ArrayList<>(distributionSetRepository.findAll(DistributionSetSpecification.byIds(dist))); } @Override public Long countDistributionSetsAll() { - final List> specList = new ArrayList<>(); + final List> specList = new LinkedList<>(); - final Specification spec = DistributionSetSpecification.isDeleted(Boolean.FALSE); + final Specification spec = DistributionSetSpecification.isDeleted(Boolean.FALSE); specList.add(spec); return distributionSetRepository.count(SpecificationsBuilder.combineWithAnd(specList)); @@ -421,16 +448,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { throw new EntityAlreadyExistsException("Given type contains an Id!"); } - return distributionSetTypeRepository.save(type); + return distributionSetTypeRepository.save((JpaDistributionSetType) type); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteDistributionSetType(final DistributionSetType type) { + public void deleteDistributionSetType(final DistributionSetType ty) { + final JpaDistributionSetType type = (JpaDistributionSetType) ty; if (distributionSetRepository.countByType(type) > 0) { - final DistributionSetType toDelete = entityManager.merge(type); + final JpaDistributionSetType toDelete = entityManager.merge(type); toDelete.setDeleted(true); distributionSetTypeRepository.save(toDelete); } else { @@ -441,7 +469,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public DistributionSetMetadata createDistributionSetMetadata(final DistributionSetMetadata metadata) { + public DistributionSetMetadata createDistributionSetMetadata(final DistributionSetMetadata md) { + final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md; + if (distributionSetMetadataRepository.exists(metadata.getId())) { throwMetadataKeyAlreadyExists(metadata.getId().getKey()); } @@ -449,31 +479,38 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // log written because // modifying metadata is modifying the base distribution set itself for // auditing purposes. - entityManager.merge(metadata.getDistributionSet()).setLastModifiedAt(0L); + entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public List createDistributionSetMetadata( - final Collection metadata) { - for (final DistributionSetMetadata distributionSetMetadata : metadata) { + public List createDistributionSetMetadata(final Collection md) { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + final Collection metadata = (Collection) md; + + for (final JpaDistributionSetMetadata distributionSetMetadata : metadata) { checkAndThrowAlreadyIfDistributionSetMetadataExists(distributionSetMetadata.getId()); } - metadata.forEach(m -> entityManager.merge(m.getDistributionSet()).setLastModifiedAt(-1L)); - return (List) distributionSetMetadataRepository.save(metadata); + metadata.forEach(m -> entityManager.merge((JpaDistributionSet) m.getDistributionSet()).setLastModifiedAt(0L)); + + return new ArrayList( + (Collection) distributionSetMetadataRepository.save(metadata)); } @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public DistributionSetMetadata updateDistributionSetMetadata(final DistributionSetMetadata metadata) { + public DistributionSetMetadata updateDistributionSetMetadata(final DistributionSetMetadata md) { + final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md; + // check if exists otherwise throw entity not found exception findOne(metadata.getId()); // touch it to update the lock revision because we are modifying the // DS indirectly - entityManager.merge(metadata.getDistributionSet()).setLastModifiedAt(0L); + entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @@ -488,23 +525,29 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, final Pageable pageable) { - return distributionSetMetadataRepository.findAll( - (Specification) (root, query, cb) -> cb.equal( - root.get(DistributionSetMetadata_.distributionSet).get(DistributionSet_.id), distributionSetId), - pageable); + return convertMdPage(distributionSetMetadataRepository + .findAll((Specification) (root, query, cb) -> cb.equal( + root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), + distributionSetId), pageable)); } @Override public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, - final Specification spec, final Pageable pageable) { - return distributionSetMetadataRepository - .findAll( - (Specification) (root, query, - cb) -> cb.and( - cb.equal(root.get(DistributionSetMetadata_.distributionSet) - .get(DistributionSet_.id), distributionSetId), - spec.toPredicate(root, query, cb)), - pageable); + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + DistributionSetMetadataFields.class); + + return convertMdPage( + distributionSetMetadataRepository + .findAll((Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaDistributionSetMetadata_.distributionSet) + .get(JpaDistributionSet_.id), distributionSetId), + spec.toPredicate(root, query, cb)), pageable)); + } + + private static Page convertMdPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override @@ -518,19 +561,19 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public DistributionSet findDistributionSetByAction(final Action action) { - return distributionSetRepository.findByAction(action); + return distributionSetRepository.findByAction((JpaAction) action); } @Override public boolean isDistributionSetInUse(final DistributionSet distributionSet) { - return actionRepository.countByDistributionSet(distributionSet) > 0; + return actionRepository.countByDistributionSet((JpaDistributionSet) distributionSet) > 0; } - private static List> buildDistributionSetSpecifications( + private static List> buildDistributionSetSpecifications( final DistributionSetFilter distributionSetFilter) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - Specification spec; + Specification spec; if (null != distributionSetFilter.getIsComplete()) { spec = DistributionSetSpecification.isCompleted(distributionSetFilter.getIsComplete()); @@ -568,7 +611,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { return specList; } - private void checkDistributionSetSoftwareModulesIsAllowedToModify(final DistributionSet distributionSet, + private void checkDistributionSetSoftwareModulesIsAllowedToModify(final JpaDistributionSet distributionSet, final Set softwareModules) { if (!new HashSet(distributionSet.getModules()).equals(softwareModules) && actionRepository.countByDistributionSet(distributionSet) > 0) { @@ -602,8 +645,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { * list of @link {@link Specification} * @return the page with the found {@link DistributionSet} */ - private Page findByCriteriaAPI(final Pageable pageable, - final List> specList) { + private Page findByCriteriaAPI(final Pageable pageable, + final List> specList) { if (specList == null || specList.isEmpty()) { return distributionSetRepository.findAll(pageable); @@ -627,10 +670,11 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public List assignTag(final Collection dsIds, final DistributionSetTag tag) { - final List allDs = findDistributionSetListWithDetails(dsIds); + final List allDs = findDistributionSetListWithDetails(dsIds); allDs.forEach(ds -> ds.getTags().add(tag)); - final List save = distributionSetRepository.save(allDs); + + final List save = new ArrayList<>(distributionSetRepository.save(allDs)); afterCommit.afterCommit(() -> { @@ -646,19 +690,23 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public List unAssignAllDistributionSetsByTag(final DistributionSetTag tag) { - return unAssignTag(tag.getAssignedToDistributionSet(), tag); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection distributionSets = (Collection) tag.getAssignedToDistributionSet(); + + return new ArrayList<>(unAssignTag(distributionSets, tag)); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public DistributionSet unAssignTag(final Long dsId, final DistributionSetTag distributionSetTag) { - final List allDs = findDistributionSetListWithDetails(Arrays.asList(dsId)); - final List unAssignTag = unAssignTag(allDs, distributionSetTag); + final List allDs = findDistributionSetListWithDetails(Arrays.asList(dsId)); + final List unAssignTag = unAssignTag(allDs, distributionSetTag); return unAssignTag.isEmpty() ? null : unAssignTag.get(0); } - private List unAssignTag(final Collection distributionSets, + private List unAssignTag(final Collection distributionSets, final DistributionSetTag tag) { distributionSets.forEach(ds -> ds.getTags().remove(tag)); return distributionSetRepository.save(distributionSets); @@ -685,4 +733,16 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { final DistributionSetTag tag) { return toggleTagAssignment(sets.stream().map(ds -> ds.getId()).collect(Collectors.toList()), tag.getName()); } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public DistributionSetType generateDistributionSetType() { + return new JpaDistributionSetType(); + } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public DistributionSet generateDistributionSet() { + return new JpaDistributionSet(); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java index 523f91374..bada97a7b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java @@ -34,13 +34,13 @@ import org.eclipse.hawkbit.report.model.DataReportSeriesItem; import org.eclipse.hawkbit.report.model.InnerOuterDataReportSeries; import org.eclipse.hawkbit.report.model.SeriesTime; import org.eclipse.hawkbit.repository.ReportManagement; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSet_; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetInfo_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.model.Target_; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -88,13 +88,13 @@ public class JpaReportManagement implements ReportManagement { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery(Object[].class); - final Root targetRoot = query.from(Target.class); - final Join targetInfo = targetRoot.join(Target_.targetInfo); - final Expression countColumn = cb.count(targetInfo.get(TargetInfo_.targetId)); + final Root targetRoot = query.from(JpaTarget.class); + final Join targetInfo = targetRoot.join(JpaTarget_.targetInfo); + final Expression countColumn = cb.count(targetInfo.get(JpaTargetInfo_.targetId)); final CriteriaQuery multiselect = query - .multiselect(targetInfo.get(TargetInfo_.updateStatus), countColumn) - .groupBy(targetInfo.get(TargetInfo_.updateStatus)) - .orderBy(cb.desc(targetInfo.get(TargetInfo_.updateStatus))); + .multiselect(targetInfo.get(JpaTargetInfo_.updateStatus), countColumn) + .groupBy(targetInfo.get(JpaTargetInfo_.updateStatus)) + .orderBy(cb.desc(targetInfo.get(JpaTargetInfo_.updateStatus))); // | col1 | col2 | // | U_STATUS | COUNT | @@ -114,16 +114,17 @@ public class JpaReportManagement implements ReportManagement { // top X entries distribution usage final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder(); final CriteriaQuery queryTopX = cbTopX.createQuery(Object[].class); - final Root rootTopX = queryTopX.from(DistributionSet.class); - final ListJoin joinTopX = rootTopX.join(DistributionSet_.assignedToTargets, + final Root rootTopX = queryTopX.from(JpaDistributionSet.class); + final ListJoin joinTopX = rootTopX.join(JpaDistributionSet_.assignedToTargets, JoinType.LEFT); final Expression countColumn = cbTopX.count(joinTopX); // top x usage query final CriteriaQuery groupBy = queryTopX - .multiselect(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version), countColumn) - .where(cbTopX.equal(rootTopX.get(DistributionSet_.deleted), false)) - .groupBy(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version)) - .orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(DistributionSet_.name))); + .multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version), + countColumn) + .where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false)) + .groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version)) + .orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name))); // | col1 | col2 | col3 | // | NAME | VER | COUNT | final List resultListTop = entityManager.createQuery(groupBy).getResultList(); @@ -138,16 +139,17 @@ public class JpaReportManagement implements ReportManagement { // top X entries distribution usage final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder(); final CriteriaQuery queryTopX = cbTopX.createQuery(Object[].class); - final Root rootTopX = queryTopX.from(DistributionSet.class); - final ListJoin joinTopX = rootTopX.join(DistributionSet_.installedAtTargets, - JoinType.LEFT); + final Root rootTopX = queryTopX.from(JpaDistributionSet.class); + final ListJoin joinTopX = rootTopX + .join(JpaDistributionSet_.installedAtTargets, JoinType.LEFT); final Expression countColumn = cbTopX.count(joinTopX); // top x usage query final CriteriaQuery groupBy = queryTopX - .multiselect(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version), countColumn) - .where(cbTopX.equal(rootTopX.get(DistributionSet_.deleted), false)) - .groupBy(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version)) - .orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(DistributionSet_.name))); + .multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version), + countColumn) + .where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false)) + .groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version)) + .orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name))); // | col1 | col2 | col3 | // | NAME | VER | COUNT | final List resultListTop = entityManager.createQuery(groupBy).getResultList(); @@ -213,6 +215,7 @@ public class JpaReportManagement implements ReportManagement { final LocalDateTime from, final LocalDateTime to) { final Query createNativeQuery = entityManager .createNativeQuery(getFeedbackReceivedQueryTemplate(dateType, from, to)); + @SuppressWarnings("unchecked") final List resultList = createNativeQuery.getResultList(); final List> reportItems = resultList.stream() @@ -275,15 +278,15 @@ public class JpaReportManagement implements ReportManagement { // count select statement final CriteriaQuery countSelect = cb.createQuery(Long.class); - final Root countSelectRoot = countSelect.from(Target.class); - final Join targetInfoJoin = countSelectRoot.join(Target_.targetInfo); + final Root countSelectRoot = countSelect.from(JpaTarget.class); + final Join targetInfoJoin = countSelectRoot.join(JpaTarget_.targetInfo); countSelect.select(cb.count(countSelectRoot)); if (start != null && end != null) { - countSelect.where(cb.between(targetInfoJoin.get(TargetInfo_.lastTargetQuery), start, end)); + countSelect.where(cb.between(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), start, end)); } else if (from == null && to != null) { - countSelect.where(cb.lessThanOrEqualTo(targetInfoJoin.get(TargetInfo_.lastTargetQuery), end)); + countSelect.where(cb.lessThanOrEqualTo(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), end)); } else { - countSelect.where(cb.isNull(targetInfoJoin.get(TargetInfo_.lastTargetQuery))); + countSelect.where(cb.isNull(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery))); } return countSelect; } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java index b7ced5511..b3ea8fb74 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -20,28 +21,36 @@ import javax.persistence.criteria.JoinType; import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.Root; +import org.eclipse.hawkbit.repository.RolloutGroupFields; import org.eclipse.hawkbit.repository.RolloutGroupManagement; +import org.eclipse.hawkbit.repository.TargetFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction_; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; +import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup; +import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup_; import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Action_; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup_; -import org.eclipse.hawkbit.repository.model.RolloutTargetGroup; -import org.eclipse.hawkbit.repository.model.RolloutTargetGroup_; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetWithActionStatus; -import org.eclipse.hawkbit.repository.model.Target_; import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -72,20 +81,34 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { @Override public Page findRolloutGroupsByRolloutId(final Long rolloutId, final Pageable page) { - return rolloutGroupRepository.findByRolloutId(rolloutId, page); + return convertPage(rolloutGroupRepository.findByRolloutId(rolloutId, page)); + } + + private static Page convertPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); + } + + private static Page convertTPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override - public Page findRolloutGroupsAll(final Rollout rollout, - final Specification specification, final Pageable page) { - return rolloutGroupRepository.findAll((root, query, criteriaBuilder) -> criteriaBuilder.and( - criteriaBuilder.equal(root.get(RolloutGroup_.rollout), rollout), - specification.toPredicate(root, query, criteriaBuilder)), page); + public Page findRolloutGroupsAll(final Rollout rollout, final String rsqlParam, final Pageable page) { + + final Specification specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class); + + return convertPage( + rolloutGroupRepository + .findAll( + (root, query, criteriaBuilder) -> criteriaBuilder.and( + criteriaBuilder.equal(root.get(JpaRolloutGroup_.rollout), rollout), + specification.toPredicate(root, query, criteriaBuilder)), + page)); } @Override public Page findAllRolloutGroupsWithDetailedStatus(final Long rolloutId, final Pageable page) { - final Page rolloutGroups = rolloutGroupRepository.findByRolloutId(rolloutId, page); + final Page rolloutGroups = rolloutGroupRepository.findByRolloutId(rolloutId, page); final List rolloutGroupIds = rolloutGroups.getContent().stream().map(rollout -> rollout.getId()) .collect(Collectors.toList()); final Map> allStatesForRollout = getStatusCountItemForRolloutGroup( @@ -97,7 +120,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus); } - return rolloutGroups; + return convertPage(rolloutGroups); } @Override @@ -121,13 +144,16 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { } @Override - public Page findRolloutGroupTargets(final RolloutGroup rolloutGroup, - final Specification specification, final Pageable page) { - return targetRepository.findAll((root, query, criteriaBuilder) -> { - final ListJoin rolloutTargetJoin = root.join(Target_.rolloutTargetGroup); - return criteriaBuilder.and(specification.toPredicate(root, query, criteriaBuilder), + public Page findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam, + final Pageable page) { + + final Specification rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class); + + return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> { + final ListJoin rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup); + return criteriaBuilder.and(rsqlSpecification.toPredicate(root, query, criteriaBuilder), criteriaBuilder.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup)); - }, page); + }, page)); } @Override @@ -138,7 +164,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { // stored in the #TargetRolloutGroup. return targetRepository.findByRolloutTargetGroupRolloutGroupId(rolloutGroup.getId(), page); } - return targetRepository.findByActionsRolloutGroup(rolloutGroup, page); + return targetRepository.findByActionsRolloutGroup((JpaRolloutGroup) rolloutGroup, page); } private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) { @@ -154,8 +180,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { final CriteriaQuery countQuery = cb.createQuery(Long.class); final Root targetRoot = query.distinct(true).from(RolloutTargetGroup.class); - final Join targetJoin = targetRoot.join(RolloutTargetGroup_.target); - final ListJoin actionJoin = targetRoot.join(RolloutTargetGroup_.actions, + final Join targetJoin = targetRoot.join(RolloutTargetGroup_.target); + final ListJoin actionJoin = targetRoot.join(RolloutTargetGroup_.actions, JoinType.LEFT); final Root countQueryFrom = countQuery.distinct(true).from(RolloutTargetGroup.class); @@ -165,7 +191,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { .where(cb.equal(countQueryFrom.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup)); final Long totalCount = entityManager.createQuery(countQuery).getSingleResult(); - final CriteriaQuery multiselect = query.multiselect(targetJoin, actionJoin.get(Action_.status)) + final CriteriaQuery multiselect = query.multiselect(targetJoin, actionJoin.get(JpaAction_.status)) .where(cb.equal(targetRoot.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup)); final List targetWithActionStatus = entityManager.createQuery(multiselect) .setFirstResult(pageRequest.getOffset()).setMaxResults(pageRequest.getPageSize()).getResultList() @@ -173,4 +199,10 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { .collect(Collectors.toList()); return new PageImpl<>(targetWithActionStatus, pageRequest, totalCount); } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public RolloutGroup generateRolloutGroup() { + return new JpaRolloutGroup(); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index e4636f890..ec13c4f29 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -19,24 +20,28 @@ import javax.persistence.EntityManager; import org.eclipse.hawkbit.cache.CacheWriteNotify; import org.eclipse.hawkbit.repository.DeploymentManagement; +import org.eclipse.hawkbit.repository.RolloutFields; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditions; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorCondition; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessCondition; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_; +import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditions; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; -import org.eclipse.hawkbit.repository.model.RolloutTargetGroup; -import org.eclipse.hawkbit.repository.model.Rollout_; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.eclipse.hawkbit.rollout.condition.RolloutGroupActionEvaluator; import org.eclipse.hawkbit.rollout.condition.RolloutGroupConditionEvaluator; import org.slf4j.Logger; @@ -46,6 +51,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; @@ -132,15 +138,21 @@ public class JpaRolloutManagement implements RolloutManagement { @Override public Page findAll(final Pageable page) { - return rolloutRepository.findAll(page); + return convertPage(rolloutRepository.findAll(page)); + } + + private static Page convertPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override - public Page findAllWithDetailedStatusByPredicate(final Specification specification, - final Pageable page) { - final Page findAll = rolloutRepository.findAll(specification, page); + public Page findAllWithDetailedStatusByPredicate(final String rsqlParam, final Pageable page) { + + final Specification specification = RSQLUtility.parse(rsqlParam, RolloutFields.class); + + final Page findAll = rolloutRepository.findAll(specification, page); setRolloutStatusDetails(findAll); - return findAll; + return convertPage(findAll); } @Override @@ -153,7 +165,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Modifying public Rollout createRollout(final Rollout rollout, final int amountGroup, final RolloutGroupConditions conditions) { - final Rollout savedRollout = createRollout(rollout, amountGroup); + final JpaRollout savedRollout = createRollout((JpaRollout) rollout, amountGroup); return createRolloutGroups(amountGroup, conditions, savedRollout); } @@ -162,7 +174,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Modifying public Rollout createRolloutAsync(final Rollout rollout, final int amountGroup, final RolloutGroupConditions conditions) { - final Rollout savedRollout = createRollout(rollout, amountGroup); + final JpaRollout savedRollout = createRollout((JpaRollout) rollout, amountGroup); creatingRollouts.add(savedRollout.getName()); // need to flush the entity manager here to get the ID of the rollout, // because entity manager is set to FlushMode#Auto, entitymanager will @@ -182,7 +194,7 @@ public class JpaRolloutManagement implements RolloutManagement { return savedRollout; } - private Rollout createRollout(final Rollout rollout, final int amountGroup) { + private JpaRollout createRollout(final JpaRollout rollout, final int amountGroup) { verifyRolloutGroupParameter(amountGroup); final Long totalTargets = targetManagement.countTargetByTargetFilterQuery(rollout.getTargetFilterQuery()); rollout.setTotalTargets(totalTargets.longValue()); @@ -198,7 +210,7 @@ public class JpaRolloutManagement implements RolloutManagement { } private Rollout createRolloutGroupsInNewTransaction(final int amountOfGroups, - final RolloutGroupConditions conditions, final Rollout savedRollout) { + final RolloutGroupConditions conditions, final JpaRollout savedRollout) { final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setName("creatingRollout"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); @@ -221,7 +233,7 @@ public class JpaRolloutManagement implements RolloutManagement { * @return the rollout with created groups */ private Rollout createRolloutGroups(final int amountOfGroups, final RolloutGroupConditions conditions, - final Rollout savedRollout) { + final JpaRollout savedRollout) { int pageIndex = 0; int groupIndex = 0; final Long totalCount = savedRollout.getTotalTargets(); @@ -237,7 +249,7 @@ public class JpaRolloutManagement implements RolloutManagement { while (pageIndex < totalCount) { groupIndex++; final String nameAndDesc = "group-" + groupIndex; - final RolloutGroup group = new RolloutGroup(); + final JpaRolloutGroup group = new JpaRolloutGroup(); group.setName(nameAndDesc); group.setDescription(nameAndDesc); group.setRollout(savedRollout); @@ -272,7 +284,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public Rollout startRollout(final Rollout rollout) { - final Rollout mergedRollout = entityManager.merge(rollout); + final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout); checkIfRolloutCanStarted(rollout, mergedRollout); return doStartRollout(mergedRollout); } @@ -281,10 +293,10 @@ public class JpaRolloutManagement implements RolloutManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public Rollout startRolloutAsync(final Rollout rollout) { - final Rollout mergedRollout = entityManager.merge(rollout); + final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout); checkIfRolloutCanStarted(rollout, mergedRollout); mergedRollout.setStatus(RolloutStatus.STARTING); - final Rollout updatedRollout = rolloutRepository.save(mergedRollout); + final JpaRollout updatedRollout = rolloutRepository.save(mergedRollout); startingRollouts.add(updatedRollout.getName()); executor.execute(() -> { try { @@ -303,13 +315,13 @@ public class JpaRolloutManagement implements RolloutManagement { } - private Rollout doStartRollout(final Rollout rollout) { + private Rollout doStartRollout(final JpaRollout rollout) { final DistributionSet distributionSet = rollout.getDistributionSet(); final ActionType actionType = rollout.getActionType(); final long forceTime = rollout.getForcedTime(); - final List rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(rollout); + final List rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(rollout); for (int iGroup = 0; iGroup < rolloutGroups.size(); iGroup++) { - final RolloutGroup rolloutGroup = rolloutGroups.get(iGroup); + final JpaRolloutGroup rolloutGroup = rolloutGroups.get(iGroup); final List targetGroup = targetRepository.findByRolloutTargetGroupRolloutGroup(rolloutGroup); // firstgroup can already be started if (iGroup == 0) { @@ -336,7 +348,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void pauseRollout(final Rollout rollout) { - final Rollout mergedRollout = entityManager.merge(rollout); + final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout); if (mergedRollout.getStatus() != RolloutStatus.RUNNING) { throw new RolloutIllegalStateException("Rollout can only be paused in state running but current state is " + rollout.getStatus().name().toLowerCase()); @@ -354,7 +366,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void resumeRollout(final Rollout rollout) { - final Rollout mergedRollout = entityManager.merge(rollout); + final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout); if (!(RolloutStatus.PAUSED.equals(mergedRollout.getStatus()))) { throw new RolloutIllegalStateException("Rollout can only be resumed in state paused but current state is " + rollout.getStatus().name().toLowerCase()); @@ -379,13 +391,13 @@ public class JpaRolloutManagement implements RolloutManagement { return; } - final List rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck, + final List rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck, RolloutStatus.RUNNING); LOGGER.info("Found {} running rollouts to check", rolloutsToCheck.size()); - for (final Rollout rollout : rolloutsToCheck) { + for (final JpaRollout rollout : rolloutsToCheck) { LOGGER.debug("Checking rollout {}", rollout); - final List rolloutGroups = rolloutGroupRepository.findByRolloutAndStatus(rollout, + final List rolloutGroups = rolloutGroupRepository.findByRolloutAndStatus(rollout, RolloutGroupStatus.RUNNING); if (rolloutGroups.isEmpty()) { @@ -415,7 +427,7 @@ public class JpaRolloutManagement implements RolloutManagement { * In case this happens, set the rollout to error state. */ private void verifyStuckedRollouts() { - final List rolloutsInCreatingState = rolloutRepository.findByStatus(RolloutStatus.CREATING); + final List rolloutsInCreatingState = rolloutRepository.findByStatus(RolloutStatus.CREATING); rolloutsInCreatingState.stream().filter(rollout -> !creatingRollouts.contains(rollout.getName())) .forEach(rollout -> { LOGGER.warn( @@ -425,7 +437,7 @@ public class JpaRolloutManagement implements RolloutManagement { rolloutRepository.save(rollout); }); - final List rolloutsInStartingState = rolloutRepository.findByStatus(RolloutStatus.STARTING); + final List rolloutsInStartingState = rolloutRepository.findByStatus(RolloutStatus.STARTING); rolloutsInStartingState.stream().filter(rollout -> !startingRollouts.contains(rollout.getName())) .forEach(rollout -> { LOGGER.warn( @@ -437,8 +449,8 @@ public class JpaRolloutManagement implements RolloutManagement { } - private void executeRolloutGroups(final Rollout rollout, final List rolloutGroups) { - for (final RolloutGroup rolloutGroup : rolloutGroups) { + private void executeRolloutGroups(final JpaRollout rollout, final List rolloutGroups) { + for (final JpaRolloutGroup rolloutGroup : rolloutGroups) { // error state check, do we need to stop the whole // rollout because of error? final RolloutGroupErrorCondition errorCondition = rolloutGroup.getErrorCondition(); @@ -459,8 +471,8 @@ public class JpaRolloutManagement implements RolloutManagement { } } - private void executeLatestRolloutGroup(final Rollout rollout) { - final List latestRolloutGroup = rolloutGroupRepository + private void executeLatestRolloutGroup(final JpaRollout rollout) { + final List latestRolloutGroup = rolloutGroupRepository .findByRolloutAndStatusNotOrderByIdDesc(rollout, RolloutGroupStatus.SCHEDULED); if (latestRolloutGroup.isEmpty()) { return; @@ -478,13 +490,13 @@ public class JpaRolloutManagement implements RolloutManagement { } } - private boolean isRolloutComplete(final Rollout rollout) { + private boolean isRolloutComplete(final JpaRollout rollout) { final Long groupsActiveLeft = rolloutGroupRepository.countByRolloutAndStatusOrStatus(rollout, RolloutGroupStatus.RUNNING, RolloutGroupStatus.SCHEDULED); return groupsActiveLeft == 0; } - private boolean isRolloutGroupComplete(final Rollout rollout, final RolloutGroup rolloutGroup) { + private boolean isRolloutGroupComplete(final JpaRollout rollout, final JpaRolloutGroup rolloutGroup) { final Long actionsLeftForRollout = actionRepository .countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(rollout, rolloutGroup, Action.Status.ERROR, Action.Status.FINISHED, Action.Status.CANCELED); @@ -543,22 +555,22 @@ public class JpaRolloutManagement implements RolloutManagement { return rolloutRepository.count(likeNameOrDescription(searchText)); } - private static Specification likeNameOrDescription(final String searchText) { + private static Specification likeNameOrDescription(final String searchText) { return (rolloutRoot, query, criteriaBuilder) -> { final String searchTextToLower = searchText.toLowerCase(); return criteriaBuilder.or( - criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(Rollout_.name)), searchTextToLower), - criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(Rollout_.description)), + criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.name)), searchTextToLower), + criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.description)), searchTextToLower)); }; } @Override public Slice findRolloutByFilters(final Pageable pageable, final String searchText) { - final Specification specs = likeNameOrDescription(searchText); - final Slice findAll = criteriaNoCountDao.findAll(specs, pageable, Rollout.class); + final Specification specs = likeNameOrDescription(searchText); + final Slice findAll = criteriaNoCountDao.findAll(specs, pageable, JpaRollout.class); setRolloutStatusDetails(findAll); - return findAll; + return convertPage(findAll); } @Override @@ -579,7 +591,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Modifying public Rollout updateRollout(final Rollout rollout) { Assert.notNull(rollout.getId()); - return rolloutRepository.save(rollout); + return rolloutRepository.save((JpaRollout) rollout); } /** @@ -593,9 +605,9 @@ public class JpaRolloutManagement implements RolloutManagement { */ @Override public Page findAllRolloutsWithDetailedStatus(final Pageable page) { - final Page rollouts = findAll(page); + final Page rollouts = rolloutRepository.findAll(page); setRolloutStatusDetails(rollouts); - return rollouts; + return convertPage(rollouts); } @@ -615,7 +627,7 @@ public class JpaRolloutManagement implements RolloutManagement { return resultList.stream().collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId)); } - private void setRolloutStatusDetails(final Slice rollouts) { + private void setRolloutStatusDetails(final Slice rollouts) { final List rolloutIds = rollouts.getContent().stream().map(rollout -> rollout.getId()) .collect(Collectors.toList()); final Map> allStatesForRollout = getStatusCountItemForRollout( @@ -648,4 +660,10 @@ public class JpaRolloutManagement implements RolloutManagement { // calculate threshold return ((float) finished / (float) totalGroup) * 100; } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public Rollout generateRollout() { + return new JpaRollout(); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 3f25dff29..7ea7e46be 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -13,6 +13,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -27,23 +28,32 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.model.CustomSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSet_; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata_; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.SoftwareModule_; -import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey; -import org.eclipse.hawkbit.repository.specifications.SoftwareModuleSpecification; -import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; @@ -52,6 +62,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -100,7 +111,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { checkNotNull(sm.getId()); - final SoftwareModule module = softwareModuleRepository.findOne(sm.getId()); + final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); boolean updated = false; if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { @@ -121,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { checkNotNull(sm.getId()); - final SoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); + final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); boolean updated = false; if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) { @@ -142,7 +153,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { if (null != swModule.getId()) { throw new EntityAlreadyExistsException(); } - return softwareModuleRepository.save(swModule); + return softwareModuleRepository.save((JpaSoftwareModule) swModule); } @Override @@ -155,30 +166,40 @@ public class JpaSoftwareManagement implements SoftwareManagement { } }); - return softwareModuleRepository.save(swModules); + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection jpaCast = (Collection) swModules; + return new ArrayList<>(softwareModuleRepository.save(jpaCast)); } @Override public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { - final List> specList = new ArrayList<>(); + final List> specList = new LinkedList<>(); - Specification spec = SoftwareModuleSpecification.equalType(type); + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); specList.add(spec); spec = SoftwareModuleSpecification.isDeletedFalse(); specList.add(spec); - return findSwModuleByCriteriaAPI(pageable, specList); + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList)); + } + + private static Page convertSmPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); + } + + private static Page convertSmMdPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override public Long countSoftwareModulesByType(final SoftwareModuleType type) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - Specification spec = SoftwareModuleSpecification.equalType(type); + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); specList.add(spec); spec = SoftwareModuleSpecification.isDeletedFalse(); @@ -196,24 +217,24 @@ public class JpaSoftwareManagement implements SoftwareManagement { public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, final SoftwareModuleType type) { - return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, type); + return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); } - private boolean isUnassigned(final SoftwareModule bsmMerged) { + private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { return distributionSetRepository.findByModules(bsmMerged).isEmpty(); } - private Slice findSwModuleByCriteriaAPI(final Pageable pageable, - final List> specList) { + private Slice findSwModuleByCriteriaAPI(final Pageable pageable, + final List> specList) { return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, - SoftwareModule.class); + JpaSoftwareModule.class); } - private Long countSwModuleByCriteriaAPI(final List> specList) { + private Long countSwModuleByCriteriaAPI(final List> specList) { return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); } - private void deleteGridFsArtifacts(final SoftwareModule swModule) { + private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { artifactManagement.deleteLocalArtifact(localArtifact); } @@ -223,7 +244,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void deleteSoftwareModules(final Collection ids) { - final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); + final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); final Set assignedModuleIds = new HashSet<>(); swModulesToDelete.forEach(swModule -> { @@ -253,29 +274,29 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Slice findSoftwareModulesAll(final Pageable pageable) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); specList.add(spec); spec = (root, query, cb) -> { if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(SoftwareModule_.type); + root.fetch(JpaSoftwareModule_.type); } return cb.conjunction(); }; specList.add(spec); - return findSwModuleByCriteriaAPI(pageable, specList); + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList)); } @Override public Long countSoftwareModulesAll() { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); specList.add(spec); return countSwModuleByCriteriaAPI(specList); @@ -287,30 +308,38 @@ public class JpaSoftwareManagement implements SoftwareManagement { } @Override - public Page findSoftwareModulesByPredicate(final Specification spec, - final Pageable pageable) { - return softwareModuleRepository.findAll(spec, pageable); + public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + + return convertSmPage(softwareModuleRepository.findAll(spec, pageable)); } @Override - public Page findSoftwareModuleTypesByPredicate(final Specification spec, + public Page findSoftwareModuleTypesByPredicate(final String rsqlParam, final Pageable pageable) { - return softwareModuleTypeRepository.findAll(spec, pageable); + + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + + return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable)); + } + + private static Page convertSmTPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) public List findSoftwareModulesById(final Collection ids) { - return softwareModuleRepository.findByIdIn(ids); + return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); } @Override public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, final SoftwareModuleType type) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); specList.add(spec); if (!Strings.isNullOrEmpty(searchText)) { @@ -319,50 +348,53 @@ public class JpaSoftwareManagement implements SoftwareManagement { } if (null != type) { - spec = SoftwareModuleSpecification.equalType(type); + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); specList.add(spec); } spec = (root, query, cb) -> { if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(SoftwareModule_.type); + root.fetch(JpaSoftwareModule_.type); } return cb.conjunction(); }; specList.add(spec); - return findSwModuleByCriteriaAPI(pageable, specList); + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList)); } @Override public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( final Pageable pageable, final Long orderByDistributionId, final String searchText, - final SoftwareModuleType type) { + final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; final List resultList = new ArrayList<>(); final int pageSize = pageable.getPageSize(); final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // get the assigned software modules - final CriteriaQuery assignedQuery = cb.createQuery(SoftwareModule.class); - final Root assignedRoot = assignedQuery.from(SoftwareModule.class); + final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); + final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); assignedQuery.distinct(true); - final ListJoin assignedDsJoin = assignedRoot.join(SoftwareModule_.assignedTo); + final ListJoin assignedDsJoin = assignedRoot + .join(JpaSoftwareModule_.assignedTo); // build the specifications and then to predicates necessary by the // given filters final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), assignedRoot, assignedQuery, cb, - cb.equal(assignedDsJoin.get(DistributionSet_.id), orderByDistributionId)); + cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); // if we have some predicates then add it to the where clause of the // multi select assignedQuery.where(specPredicate); - assignedQuery.orderBy(cb.asc(assignedRoot.get(SoftwareModule_.name)), - cb.asc(assignedRoot.get(SoftwareModule_.version))); + assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); // don't page the assigned query on database, we need all assigned // software modules to filter // them out in the unassigned query - final List assignedSoftwareModules = entityManager.createQuery(assignedQuery).getResultList(); + final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) + .getResultList(); // map result if (pageable.getOffset() < assignedSoftwareModules.size()) { assignedSoftwareModules @@ -375,14 +407,14 @@ public class JpaSoftwareManagement implements SoftwareManagement { } // get the unassigned software modules - final CriteriaQuery unassignedQuery = cb.createQuery(SoftwareModule.class); + final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); unassignedQuery.distinct(true); - final Root unassignedRoot = unassignedQuery.from(SoftwareModule.class); + final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); Predicate[] unassignedSpec; if (!assignedSoftwareModules.isEmpty()) { unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb, cb.not(unassignedRoot.get(SoftwareModule_.id) + unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); } else { unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, @@ -390,9 +422,9 @@ public class JpaSoftwareManagement implements SoftwareManagement { } unassignedQuery.where(unassignedSpec); - unassignedQuery.orderBy(cb.asc(unassignedRoot.get(SoftwareModule_.name)), - cb.asc(unassignedRoot.get(SoftwareModule_.version))); - final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) + unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); + final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) .setMaxResults(pageSize).getResultList(); // map result @@ -401,9 +433,9 @@ public class JpaSoftwareManagement implements SoftwareManagement { return new SliceImpl<>(resultList); } - private static List> buildSpecificationList(final String searchText, - final SoftwareModuleType type) { - final List> specList = new ArrayList<>(); + private static List> buildSpecificationList(final String searchText, + final JpaSoftwareModuleType type) { + final List> specList = new ArrayList<>(); if (!Strings.isNullOrEmpty(searchText)) { specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); } @@ -414,8 +446,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { return specList; } - private Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb, + private Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb, final Predicate... additionalPredicates) { final List predicates = new ArrayList<>(); specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); @@ -428,9 +460,9 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); specList.add(spec); if (!Strings.isNullOrEmpty(searchText)) { @@ -439,7 +471,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { } if (null != type) { - spec = SoftwareModuleSpecification.equalType(type); + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); specList.add(spec); } @@ -479,17 +511,18 @@ public class JpaSoftwareManagement implements SoftwareManagement { throw new EntityAlreadyExistsException("Given type contains an Id!"); } - return softwareModuleTypeRepository.save(type); + return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModuleType(final SoftwareModuleType type) { + public void deleteSoftwareModuleType(final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; if (softwareModuleRepository.countByType(type) > 0 || distributionSetTypeRepository.countByElementsSmType(type) > 0) { - final SoftwareModuleType toDelete = entityManager.merge(type); + final JpaSoftwareModuleType toDelete = entityManager.merge(type); toDelete.setDeleted(true); softwareModuleTypeRepository.save(toDelete); } else { @@ -499,19 +532,22 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { - return softwareModuleRepository.findByAssignedTo(pageable, set); + return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); } @Override public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, final DistributionSet set, final SoftwareModuleType type) { - return softwareModuleRepository.findByAssignedToAndType(pageable, set, type); + return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, + (JpaSoftwareModuleType) type); } @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata metadata) { + public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + if (softwareModuleMetadataRepository.exists(metadata.getId())) { throwMetadataKeyAlreadyExists(metadata.getId().getKey()); } @@ -519,32 +555,36 @@ public class JpaSoftwareManagement implements SoftwareManagement { // log written because // modifying metadata is modifying the base software module itself for // auditing purposes. - entityManager.merge(metadata.getSoftwareModule()).setLastModifiedAt(-1L); + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); return softwareModuleMetadataRepository.save(metadata); } @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public List createSoftwareModuleMetadata( - final Collection metadata) { - for (final SoftwareModuleMetadata softwareModuleMetadata : metadata) { + public List createSoftwareModuleMetadata(final Collection md) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection metadata = (Collection) md; + + for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); } - metadata.forEach(m -> entityManager.merge(m.getSoftwareModule()).setLastModifiedAt(-1L)); - return softwareModuleMetadataRepository.save(metadata); + metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); + return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); } @Override @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying - public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata metadata) { + public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + // check if exists otherwise throw entity not found exception findSoftwareModuleMetadata(metadata.getId()); // touch it to update the lock revision because we are modifying the // software module // indirectly - entityManager.merge(metadata.getSoftwareModule()).setLastModifiedAt(-1L); + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); return softwareModuleMetadataRepository.save(metadata); } @@ -563,15 +603,18 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, - final Specification spec, final Pageable pageable) { - return softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, - cb) -> cb.and( - cb.equal(root.get(SoftwareModuleMetadata_.softwareModule) - .get(SoftwareModule_.id), softwareModuleId), + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + SoftwareModuleMetadataFields.class); + return convertSmMdPage( + softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId), spec.toPredicate(root, query, cb)), - pageable); + pageable)); } @Override @@ -609,4 +652,16 @@ public class JpaSoftwareManagement implements SoftwareManagement { return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); } + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public SoftwareModuleType generateSoftwareModuleType() { + return new JpaSoftwareModuleType(); + } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public SoftwareModule generateSoftwareModule() { + return new JpaSoftwareModule(); + } + } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java index b7a08fc2e..1acbd0f1b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java @@ -20,6 +20,9 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.TenantMetaData; @@ -167,7 +170,7 @@ public class JpaSystemManagement implements SystemManagement { try { createInitialTenant.set(tenant); cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null)); - return tenantMetaDataRepository.save(new TenantMetaData(createStandardSoftwareDataSetup(), tenant)); + return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant)); } finally { createInitialTenant.remove(); } @@ -253,27 +256,26 @@ public class JpaSystemManagement implements SystemManagement { throw new EntityNotFoundException("Metadata does not exist: " + metaData.getId()); } - return tenantMetaDataRepository.save(metaData); + return tenantMetaDataRepository.save((JpaTenantMetaData) metaData); } private DistributionSetType createStandardSoftwareDataSetup() { - final SoftwareModuleType eclApp = softwareModuleTypeRepository.save(new SoftwareModuleType("application", + final SoftwareModuleType eclApp = softwareModuleTypeRepository.save(new JpaSoftwareModuleType("application", "ECL Application", "Edge Controller Linux base application type", 1)); - final SoftwareModuleType eclOs = softwareModuleTypeRepository - .save(new SoftwareModuleType("os", "ECL OS", "Edge Controller Linux operation system image type", 1)); + final SoftwareModuleType eclOs = softwareModuleTypeRepository.save( + new JpaSoftwareModuleType("os", "ECL OS", "Edge Controller Linux operation system image type", 1)); final SoftwareModuleType eclJvm = softwareModuleTypeRepository.save( - new SoftwareModuleType("runtime", "ECL JVM", "Edge Controller Linux java virtual machine type.", 1)); + new JpaSoftwareModuleType("runtime", "ECL JVM", "Edge Controller Linux java virtual machine type.", 1)); - distributionSetTypeRepository.save( - new DistributionSetType("ecl_os", "OS only", "Standard Edge Controller Linux distribution set type.") - .addMandatoryModuleType(eclOs)); + distributionSetTypeRepository.save((JpaDistributionSetType) new JpaDistributionSetType("ecl_os", "OS only", + "Standard Edge Controller Linux distribution set type.").addMandatoryModuleType(eclOs)); - distributionSetTypeRepository.save(new DistributionSetType("ecl_os_app", "OS with optional app", - "Standard Edge Controller Linux distribution set type. OS only.").addMandatoryModuleType(eclOs) - .addOptionalModuleType(eclApp)); + distributionSetTypeRepository.save((JpaDistributionSetType) new JpaDistributionSetType("ecl_os_app", + "OS with optional app", "Standard Edge Controller Linux distribution set type. OS only.") + .addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp)); - return distributionSetTypeRepository - .save(new DistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm", + return distributionSetTypeRepository.save( + (JpaDistributionSetType) new JpaDistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm", "Standard Edge Controller Linux distribution set type. OS with optional application.") .addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp) .addOptionalModuleType(eclJvm)); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java index f1b885b13..4ff9c6e2b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -21,20 +22,26 @@ import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent; import org.eclipse.hawkbit.eventbus.event.TargetTagDeletedEvent; import org.eclipse.hawkbit.eventbus.event.TargetTagUpdateEvent; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; +import org.eclipse.hawkbit.repository.TagFields; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -86,7 +93,7 @@ public class JpaTagManagement implements TagManagement { throw new EntityAlreadyExistsException(); } - final TargetTag save = targetTagRepository.save(targetTag); + final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag); afterCommit .afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); @@ -97,13 +104,17 @@ public class JpaTagManagement implements TagManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createTargetTags(final Iterable targetTags) { + public List createTargetTags(final Collection tt) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection targetTags = (Collection) tt; + targetTags.forEach(tag -> { if (tag.getId() != null) { throw new EntityAlreadyExistsException(); } }); - final List save = targetTagRepository.save(targetTags); + + final List save = new ArrayList<>(targetTagRepository.save(targetTags)); afterCommit .afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); return save; @@ -113,10 +124,10 @@ public class JpaTagManagement implements TagManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void deleteTargetTag(final String targetTagName) { - final TargetTag tag = targetTagRepository.findByNameEquals(targetTagName); + final JpaTargetTag tag = targetTagRepository.findByNameEquals(targetTagName); - final List changed = new LinkedList<>(); - for (final Target target : targetRepository.findByTag(tag)) { + final List changed = new LinkedList<>(); + for (final JpaTarget target : targetRepository.findByTag(tag)) { target.getTags().remove(tag); changed.add(target); } @@ -133,12 +144,22 @@ public class JpaTagManagement implements TagManagement { @Override public List findAllTargetTags() { - return targetTagRepository.findAll(); + return new ArrayList<>(targetTagRepository.findAll()); } @Override - public Page findAllTargetTags(final Specification spec, final Pageable pageable) { - return targetTagRepository.findAll(spec, pageable); + public Page findAllTargetTags(final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class); + return convertTPage(targetTagRepository.findAll(spec, pageable)); + } + + private static Page convertTPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); + } + + private static Page convertDsPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override @@ -152,7 +173,7 @@ public class JpaTagManagement implements TagManagement { public TargetTag updateTargetTag(final TargetTag targetTag) { checkNotNull(targetTag.getName()); checkNotNull(targetTag.getId()); - final TargetTag save = targetTagRepository.save(targetTag); + final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag); afterCommit.afterCommit(() -> eventBus.post(new TargetTagUpdateEvent(save))); return save; } @@ -174,7 +195,7 @@ public class JpaTagManagement implements TagManagement { throw new EntityAlreadyExistsException(); } - final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag); + final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag); afterCommit.afterCommit( () -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); @@ -184,14 +205,17 @@ public class JpaTagManagement implements TagManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createDistributionSetTags( - final Collection distributionSetTags) { + public List createDistributionSetTags(final Collection dst) { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + final Collection distributionSetTags = (Collection) dst; + for (final DistributionSetTag dsTag : distributionSetTags) { if (dsTag.getId() != null) { throw new EntityAlreadyExistsException(); } } - final List save = distributionSetTagRepository.save(distributionSetTags); + final List save = new ArrayList<>(distributionSetTagRepository.save(distributionSetTags)); afterCommit.afterCommit( () -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); @@ -202,10 +226,10 @@ public class JpaTagManagement implements TagManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void deleteDistributionSetTag(final String tagName) { - final DistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName); + final JpaDistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName); - final List changed = new LinkedList<>(); - for (final DistributionSet set : distributionSetRepository.findByTag(tag)) { + final List changed = new LinkedList<>(); + for (final JpaDistributionSet set : distributionSetRepository.findByTag(tag)) { set.getTags().remove(tag); changed.add(set); } @@ -224,7 +248,7 @@ public class JpaTagManagement implements TagManagement { public DistributionSetTag updateDistributionSetTag(final DistributionSetTag distributionSetTag) { checkNotNull(distributionSetTag.getName()); checkNotNull(distributionSetTag.getId()); - final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag); + final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag); afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagUpdateEvent(save))); return save; @@ -232,7 +256,7 @@ public class JpaTagManagement implements TagManagement { @Override public List findAllDistributionSetTags() { - return distributionSetTagRepository.findAll(); + return new ArrayList<>(distributionSetTagRepository.findAll()); } @Override @@ -247,18 +271,31 @@ public class JpaTagManagement implements TagManagement { @Override public Page findAllTargetTags(final Pageable pageReq) { - return targetTagRepository.findAll(pageReq); + return convertTPage(targetTagRepository.findAll(pageReq)); } @Override public Page findAllDistributionSetTags(final Pageable pageReq) { - return distributionSetTagRepository.findAll(pageReq); + return convertDsPage(distributionSetTagRepository.findAll(pageReq)); } @Override - public Page findAllDistributionSetTags(final Specification spec, - final Pageable pageable) { - return distributionSetTagRepository.findAll(spec, pageable); + public Page findAllDistributionSetTags(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class); + + return convertDsPage(distributionSetTagRepository.findAll(spec, pageable)); + } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public TargetTag generateTargetTag() { + return new JpaTargetTag(); + } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public DistributionSetTag generateDistributionSetTag() { + return new JpaDistributionSetTag(); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java index a8c6b014f..5dd33b762 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java @@ -13,11 +13,13 @@ import java.util.List; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; -import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.specifications.TargetFilterQuerySpecification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specifications; @@ -50,7 +52,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme if (targetFilterQueryRepository.findByName(customTargetFilter.getName()) != null) { throw new EntityAlreadyExistsException(customTargetFilter.getName()); } - return targetFilterQueryRepository.save(customTargetFilter); + return targetFilterQueryRepository.save((JpaTargetFilterQuery) customTargetFilter); } @Override @@ -62,25 +64,29 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Override public Page findAllTargetFilterQuery(final Pageable pageable) { - return targetFilterQueryRepository.findAll(pageable); + return convertPage(targetFilterQueryRepository.findAll(pageable)); + } + + private static Page convertPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override public Page findTargetFilterQueryByFilters(final Pageable pageable, final String name) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); if (!Strings.isNullOrEmpty(name)) { specList.add(TargetFilterQuerySpecification.likeName(name)); } - return findTargetFilterQueryByCriteriaAPI(pageable, specList); + return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList)); } - private Page findTargetFilterQueryByCriteriaAPI(final Pageable pageable, - final List> specList) { + private Page findTargetFilterQueryByCriteriaAPI(final Pageable pageable, + final List> specList) { if (specList == null || specList.isEmpty()) { return targetFilterQueryRepository.findAll(pageable); } - final Specifications specs = SpecificationsBuilder.combineWithAnd(specList); + final Specifications specs = SpecificationsBuilder.combineWithAnd(specList); return targetFilterQueryRepository.findAll(specs, pageable); } @@ -99,7 +105,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Transactional(isolation = Isolation.READ_UNCOMMITTED) public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQuery targetFilterQuery) { Assert.notNull(targetFilterQuery.getId()); - return targetFilterQueryRepository.save(targetFilterQuery); + return targetFilterQueryRepository.save((JpaTargetFilterQuery) targetFilterQuery); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 513d5b52c..0e900e655 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -33,22 +33,25 @@ import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.model.DistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetIdName; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetInfo_; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.model.Target_; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.specifications.TargetSpecifications; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; @@ -58,6 +61,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; @@ -121,7 +125,8 @@ public class JpaTargetManagement implements TargetManagement { @Override public List findTargetByControllerID(final Collection controllerIDs) { - return targetRepository.findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs)); + return new ArrayList<>(targetRepository + .findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs))); } @Override @@ -134,28 +139,27 @@ public class JpaTargetManagement implements TargetManagement { // workarround - no join fetch allowed that is why we need specification // instead of query for // count() of Pageable - final Specification spec = (root, query, cb) -> { + final Specification spec = (root, query, cb) -> { if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(Target_.targetInfo); + root.fetch(JpaTarget_.targetInfo); } return cb.conjunction(); }; - return criteriaNoCountDao.findAll(spec, pageable, Target.class); + return convertPage(criteriaNoCountDao.findAll(spec, pageable, JpaTarget.class)); } @Override public Slice findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) { - return findTargetsAll(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable); + return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable); } @Override - public Slice findTargetsAll(final String targetFilterQuery, final Pageable pageable) { - return findTargetsAll(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable); + public Page findTargetsAll(final String targetFilterQuery, final Pageable pageable) { + return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable); } - @Override - public Page findTargetsAll(final Specification spec, final Pageable pageable) { - return targetRepository.findAll(spec, pageable); + private Page findTargetsBySpec(final Specification spec, final Pageable pageable) { + return convertPage(targetRepository.findAll(spec, pageable)); } @Override @@ -171,16 +175,23 @@ public class JpaTargetManagement implements TargetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Target updateTarget(final Target target) { Assert.notNull(target.getId()); - target.setNew(false); - return targetRepository.save(target); + + final JpaTarget toUpdate = (JpaTarget) target; + toUpdate.setNew(false); + return targetRepository.save(toUpdate); } @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List updateTargets(final Iterable targets) { - targets.forEach(target -> target.setNew(false)); - return targetRepository.save(targets); + public List updateTargets(final Collection targets) { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection toUpdate = (Collection) targets; + + toUpdate.forEach(target -> target.setNew(false)); + + return new ArrayList<>(targetRepository.save(toUpdate)); } @Override @@ -206,11 +217,22 @@ public class JpaTargetManagement implements TargetManagement { } @Override - public Page findTargetByAssignedDistributionSet(final Long distributionSetID, - final Specification spec, final Pageable pageReq) { - return targetRepository.findAll((Specification) (root, query, cb) -> cb.and( + public Page findTargetByAssignedDistributionSet(final Long distributionSetID, final String rsqlParam, + final Pageable pageReq) { + + final Specification spec = RSQLUtility.parse(rsqlParam, TargetFields.class); + + return convertPage(targetRepository.findAll((Specification) (root, query, cb) -> cb.and( TargetSpecifications.hasAssignedDistributionSet(distributionSetID).toPredicate(root, query, cb), - spec.toPredicate(root, query, cb)), pageReq); + spec.toPredicate(root, query, cb)), pageReq)); + } + + private static Page convertPage(final Page findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); + } + + private static Slice convertPage(final Slice findAll) { + return new PageImpl<>(new ArrayList<>(findAll.getContent())); } @Override @@ -219,11 +241,14 @@ public class JpaTargetManagement implements TargetManagement { } @Override - public Page findTargetByInstalledDistributionSet(final Long distributionSetId, - final Specification spec, final Pageable pageable) { - return targetRepository.findAll((Specification) (root, query, cb) -> cb.and( + public Page findTargetByInstalledDistributionSet(final Long distributionSetId, final String rsqlParam, + final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, TargetFields.class); + + return convertPage(targetRepository.findAll((Specification) (root, query, cb) -> cb.and( TargetSpecifications.hasInstalledDistributionSet(distributionSetId).toPredicate(root, query, cb), - spec.toPredicate(root, query, cb)), pageable); + spec.toPredicate(root, query, cb)), pageable)); } @Override @@ -235,7 +260,7 @@ public class JpaTargetManagement implements TargetManagement { public Slice findTargetByFilters(final Pageable pageable, final Collection status, final String searchText, final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag, final String... tagNames) { - final List> specList = buildSpecificationList(status, searchText, + final List> specList = buildSpecificationList(status, searchText, installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames); return findByCriteriaAPI(pageable, specList); } @@ -244,15 +269,15 @@ public class JpaTargetManagement implements TargetManagement { public Long countTargetByFilters(final Collection status, final String searchText, final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag, final String... tagNames) { - final List> specList = buildSpecificationList(status, searchText, + final List> specList = buildSpecificationList(status, searchText, installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames); return countByCriteriaAPI(specList); } - private static List> buildSpecificationList(final Collection status, + private static List> buildSpecificationList(final Collection status, final String searchText, final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag, final boolean fetch, final String... tagNames) { - final List> specList = new ArrayList<>(); + final List> specList = new ArrayList<>(); if (status != null && !status.isEmpty()) { specList.add(TargetSpecifications.hasTargetUpdateStatus(status, fetch)); } @@ -269,14 +294,15 @@ public class JpaTargetManagement implements TargetManagement { return specList; } - private Slice findByCriteriaAPI(final Pageable pageable, final List> specList) { + private Slice findByCriteriaAPI(final Pageable pageable, final List> specList) { if (specList == null || specList.isEmpty()) { - return criteriaNoCountDao.findAll(pageable, Target.class); + return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class)); } - return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, Target.class); + return convertPage( + criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, JpaTarget.class)); } - private Long countByCriteriaAPI(final List> specList) { + private Long countByCriteriaAPI(final List> specList) { if (specList == null || specList.isEmpty()) { return targetRepository.count(); } @@ -298,7 +324,7 @@ public class JpaTargetManagement implements TargetManagement { public TargetTagAssignmentResult toggleTagAssignment(final Collection targetIds, final String tagName) { final TargetTag tag = targetTagRepository.findByNameEquals(tagName); final List alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName, targetIds); - final List allTargets = targetRepository + final List allTargets = targetRepository .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds)); // all are already assigned -> unassign @@ -315,7 +341,7 @@ public class JpaTargetManagement implements TargetManagement { // some or none are assigned -> assign allTargets.forEach(target -> target.getTags().add(tag)); final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(), - allTargets.size(), 0, targetRepository.save(allTargets), Collections.emptyList(), tag); + allTargets.size(), 0, new ArrayList<>(targetRepository.save(allTargets)), Collections.emptyList(), tag); afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result))); @@ -328,11 +354,11 @@ public class JpaTargetManagement implements TargetManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public List assignTag(final Collection targetIds, final TargetTag tag) { - final List allTargets = targetRepository + final List allTargets = targetRepository .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds)); allTargets.forEach(target -> target.getTags().add(tag)); - final List save = targetRepository.save(allTargets); + final List save = new ArrayList<>(targetRepository.save(allTargets)); afterCommit.afterCommit(() -> { final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save, @@ -344,9 +370,11 @@ public class JpaTargetManagement implements TargetManagement { } private List unAssignTag(final Collection targets, final TargetTag tag) { - targets.forEach(target -> target.getTags().remove(tag)); + final Collection toUnassign = (Collection) targets; - final List save = targetRepository.save(targets); + toUnassign.forEach(target -> target.getTags().remove(tag)); + + final List save = new ArrayList<>(targetRepository.save(toUnassign)); afterCommit.afterCommit(() -> { final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(), Collections.emptyList(), save, tag); @@ -366,8 +394,9 @@ public class JpaTargetManagement implements TargetManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) public Target unAssignTag(final String controllerID, final TargetTag targetTag) { - final List allTargets = targetRepository - .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID))); + // TODO : optimize this, findone? + final List allTargets = new ArrayList<>(targetRepository + .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID)))); final List unAssignTag = unAssignTag(allTargets, targetTag); return unAssignTag.isEmpty() ? null : unAssignTag.get(0); } @@ -378,20 +407,20 @@ public class JpaTargetManagement implements TargetManagement { final Collection filterByStatus, final String filterBySearchText, final Boolean selectTargetWithNoTag, final String... filterByTagNames) { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = cb.createQuery(Target.class); - final Root targetRoot = query.from(Target.class); + final CriteriaQuery query = cb.createQuery(JpaTarget.class); + final Root targetRoot = query.from(JpaTarget.class); // necessary joins for the select - final Join targetInfo = (Join) targetRoot.fetch(Target_.targetInfo, - JoinType.LEFT); + final Join targetInfo = (Join) targetRoot + .fetch(JpaTarget_.targetInfo, JoinType.LEFT); // select case expression to retrieve the case value as a column to be // able to order based on // this column, installed first,... final Expression selectCase = cb.selectCase() - .when(cb.equal(targetInfo.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id), + .when(cb.equal(targetInfo.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id), orderByDistributionId), 1) - .when(cb.equal(targetRoot.get(Target_.assignedDistributionSet).get(DistributionSet_.id), + .when(cb.equal(targetRoot.get(JpaTarget_.assignedDistributionSet).get(JpaDistributionSet_.id), orderByDistributionId), 2) .otherwise(100); // multiselect statement order by the select case and controllerId @@ -409,7 +438,7 @@ public class JpaTargetManagement implements TargetManagement { query.where(specificationsForMultiSelect); } // add the order to the multi select first based on the selectCase - query.orderBy(cb.asc(selectCase), cb.desc(targetRoot.get(Target_.id))); + query.orderBy(cb.asc(selectCase), cb.desc(targetRoot.get(JpaTarget_.id))); // the result is a Object[] due the fact that the selectCase is an extra // column, so it cannot // be mapped directly to a Target entity because the selectCase is not a @@ -419,14 +448,14 @@ public class JpaTargetManagement implements TargetManagement { // multiselect order) of the array and // the 2nd contains the selectCase int value. final int pageSize = pageable.getPageSize(); - final List resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset()) + final List resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset()) .setMaxResults(pageSize + 1).getResultList(); final boolean hasNext = resultList.size() > pageSize; - return new SliceImpl<>(resultList, pageable, hasNext); + return new SliceImpl<>(new ArrayList<>(resultList), pageable, hasNext); } - private static Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb) { + private static Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb) { final Predicate[] predicates = new Predicate[specifications.size()]; for (int index = 0; index < predicates.length; index++) { predicates[index] = specifications.get(index).toPredicate(root, query, cb); @@ -448,9 +477,9 @@ public class JpaTargetManagement implements TargetManagement { public List findAllTargetIds() { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery(TargetIdName.class); - final Root targetRoot = query.from(Target.class); - return entityManager.createQuery(query.multiselect(targetRoot.get(Target_.id), - targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name))).getResultList(); + final Root targetRoot = query.from(JpaTarget.class); + return entityManager.createQuery(query.multiselect(targetRoot.get(JpaTarget_.id), + targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name))).getResultList(); } @@ -461,16 +490,16 @@ public class JpaTargetManagement implements TargetManagement { final String... filterByTagNames) { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery(Object[].class); - final Root targetRoot = query.from(Target.class); + final Root targetRoot = query.from(JpaTarget.class); List resultList; - String sortProperty = Target_.id.getName(); + String sortProperty = JpaTarget_.id.getName(); if (pageRequest.getSort() != null && pageRequest.getSort().iterator().hasNext()) { sortProperty = pageRequest.getSort().iterator().next().getProperty(); } - final CriteriaQuery multiselect = query.multiselect(targetRoot.get(Target_.id), - targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name), targetRoot.get(sortProperty)); + final CriteriaQuery multiselect = query.multiselect(targetRoot.get(JpaTarget_.id), + targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty)); final Predicate[] specificationsForMultiSelect = specificationsToPredicate( buildSpecificationList(filterByStatus, filterBySearchText, installedOrAssignedDistributionSetId, @@ -493,18 +522,18 @@ public class JpaTargetManagement implements TargetManagement { final TargetFilterQuery targetFilterQuery) { final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery(Object[].class); - final Root targetRoot = query.from(Target.class); + final Root targetRoot = query.from(JpaTarget.class); - String sortProperty = Target_.id.getName(); + String sortProperty = JpaTarget_.id.getName(); if (pageRequest.getSort() != null && pageRequest.getSort().iterator().hasNext()) { sortProperty = pageRequest.getSort().iterator().next().getProperty(); } - final CriteriaQuery multiselect = query.multiselect(targetRoot.get(Target_.id), - targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name), targetRoot.get(sortProperty)); + final CriteriaQuery multiselect = query.multiselect(targetRoot.get(JpaTarget_.id), + targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty)); - final Specification spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class); - final List> specList = new ArrayList<>(); + final Specification spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class); + final List> specList = new ArrayList<>(); specList.add(spec); final Predicate[] specificationsForMultiSelect = specificationsToPredicate(specList, targetRoot, multiselect, @@ -529,16 +558,17 @@ public class JpaTargetManagement implements TargetManagement { @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetsCreatedOverPeriod" }, allEntries = true) - public Target createTarget(final Target target, final TargetUpdateStatus status, final Long lastTargetQuery, + public Target createTarget(final Target t, final TargetUpdateStatus status, final Long lastTargetQuery, final URI address) { + final JpaTarget target = (JpaTarget) t; if (targetRepository.findByControllerId(target.getControllerId()) != null) { throw new EntityAlreadyExistsException(target.getControllerId()); } target.setNew(true); - final Target savedTarget = targetRepository.save(target); - final TargetInfo targetInfo = savedTarget.getTargetInfo(); + final JpaTarget savedTarget = targetRepository.save(target); + final JpaTargetInfo targetInfo = (JpaTargetInfo) savedTarget.getTargetInfo(); targetInfo.setUpdateStatus(status); if (lastTargetQuery != null) { targetInfo.setLastTargetQuery(lastTargetQuery); @@ -596,24 +626,24 @@ public class JpaTargetManagement implements TargetManagement { @Override public List findTargetsByTag(final String tagName) { - final TargetTag tag = targetTagRepository.findByNameEquals(tagName); - return targetRepository.findByTag(tag); + final JpaTargetTag tag = targetTagRepository.findByNameEquals(tagName); + return new ArrayList<>(targetRepository.findByTag(tag)); } @Override public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) { - final Specification specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class); + final Specification specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class); return targetRepository.count(specs); } @Override public Long countTargetByTargetFilterQuery(final String targetFilterQuery) { - final Specification specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class); + final Specification specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class); return targetRepository.count(specs); } private List getTargetIdNameResultSet(final Pageable pageRequest, final CriteriaBuilder cb, - final Root targetRoot, final CriteriaQuery multiselect) { + final Root targetRoot, final CriteriaQuery multiselect) { List resultList; if (pageRequest.getSort() != null) { final List orders = new ArrayList<>(); @@ -633,4 +663,10 @@ public class JpaTargetManagement implements TargetManagement { } return resultList; } + + @Override + @Transactional(propagation = Propagation.SUPPORTS) + public Target generateTarget(final String controllerId) { + return new JpaTarget(controllerId); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java index 5cc27d75c..c9781a2a4 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.repository.jpa; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -134,16 +135,17 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan configurationKey.validate(applicationContext, value); - TenantConfiguration tenantConfiguration = tenantConfigurationRepository + JpaTenantConfiguration tenantConfiguration = tenantConfigurationRepository .findByKey(configurationKey.getKeyName()); if (tenantConfiguration == null) { - tenantConfiguration = new TenantConfiguration(configurationKey.getKeyName(), value.toString()); + tenantConfiguration = new JpaTenantConfiguration(configurationKey.getKeyName(), value.toString()); } else { tenantConfiguration.setValue(value.toString()); } - final TenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository.save(tenantConfiguration); + final JpaTenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository + .save(tenantConfiguration); final Class clazzT = (Class) value.getClass(); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/LocalArtifactRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/LocalArtifactRepository.java index fcad668d2..e6eb62a27 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/LocalArtifactRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/LocalArtifactRepository.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; import java.util.Optional; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -23,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface LocalArtifactRepository extends BaseEntityRepository { +public interface LocalArtifactRepository extends BaseEntityRepository { /** * Counts artifacts size where the related software module is not @@ -31,7 +32,7 @@ public interface LocalArtifactRepository extends BaseEntityRepository getSumOfUndeletedArtifactSize(); /** @@ -60,7 +61,7 @@ public interface LocalArtifactRepository extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Retrieves all {@link RolloutGroup} referring a specific rollout in the @@ -36,7 +38,7 @@ public interface RolloutGroupRepository * the rollout the rolloutgroups belong to * @return the rollout groups belonging to a rollout ordered by ID ASC. */ - List findByRolloutOrderByIdAsc(final Rollout rollout); + List findByRolloutOrderByIdAsc(final JpaRollout rollout); /** * Retrieves all {@link RolloutGroup} referring a specific rollout in a @@ -48,7 +50,7 @@ public interface RolloutGroupRepository * the status of the rollout groups * @return the rollout groups belonging to a rollout in a specific status */ - List findByRolloutAndStatus(final Rollout rollout, final RolloutGroupStatus status); + List findByRolloutAndStatus(final Rollout rollout, final RolloutGroupStatus status); /** * Counts all {@link RolloutGroup} referring a specific rollout. @@ -57,7 +59,7 @@ public interface RolloutGroupRepository * the rollout the rolloutgroup belong to * @return the count of the rollout groups for a specific rollout */ - Long countByRollout(final Rollout rollout); + Long countByRollout(final JpaRollout rollout); /** * Counts all {@link RolloutGroup} referring a specific rollout in a @@ -70,7 +72,7 @@ public interface RolloutGroupRepository * @return the count of rollout groups belonging to a rollout in a specific * status */ - Long countByRolloutAndStatus(Rollout rollout, RolloutGroupStatus rolloutGroupStatus); + Long countByRolloutAndStatus(JpaRollout rollout, RolloutGroupStatus rolloutGroupStatus); /** * Counts all {@link RolloutGroup} referring a specific rollout in specific @@ -88,8 +90,8 @@ public interface RolloutGroupRepository * @return the count of rollout groups belonging to a rollout in specific * status */ - @Query("SELECT COUNT(r.id) FROM RolloutGroup r WHERE r.rollout = :rollout and (r.status = :status1 or r.status = :status2)") - Long countByRolloutAndStatusOrStatus(@Param("rollout") Rollout rollout, + @Query("SELECT COUNT(r.id) FROM JpaRolloutGroup r WHERE r.rollout = :rollout and (r.status = :status1 or r.status = :status2)") + Long countByRolloutAndStatusOrStatus(@Param("rollout") JpaRollout rollout, @Param("status1") RolloutGroupStatus rolloutGroupStatus1, @Param("status2") RolloutGroupStatus rolloutGroupStatus2); @@ -103,7 +105,7 @@ public interface RolloutGroupRepository * the status of the rolloutgroups * @return The child {@link RolloutGroup}s in a specific status */ - List findByParentAndStatus(RolloutGroup rolloutGroup, RolloutGroupStatus status); + List findByParentAndStatus(JpaRolloutGroup rolloutGroup, RolloutGroupStatus status); /** * Retrieves all {@link RolloutGroup} for a specific rollout and status not @@ -116,7 +118,7 @@ public interface RolloutGroupRepository * @return rolloutgroup referring to a rollout and not having a specific * status ordered by ID DESC. */ - List findByRolloutAndStatusNotOrderByIdDesc(Rollout rollout, RolloutGroupStatus notStatus); + List findByRolloutAndStatusNotOrderByIdDesc(JpaRollout rollout, RolloutGroupStatus notStatus); /** * Retrieves all {@link RolloutGroup} for a specific rollout. @@ -127,6 +129,6 @@ public interface RolloutGroupRepository * the page request to sort, limit the result * @return a page of found {@link RolloutGroup} or {@code empty}. */ - Page findByRolloutId(final Long rolloutId, Pageable page); + Page findByRolloutId(final Long rolloutId, Pageable page); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java index 212672419..e73c12952 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java @@ -10,8 +10,9 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -25,7 +26,8 @@ import org.springframework.transaction.annotation.Transactional; * The repository interface for the {@link Rollout} model. */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface RolloutRepository extends BaseEntityRepository, JpaSpecificationExecutor { +public interface RolloutRepository + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Updates the {@code lastCheck} field of the {@link Rollout} for rollouts @@ -42,7 +44,7 @@ public interface RolloutRepository extends BaseEntityRepository, */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE Rollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status") + @Query("UPDATE JpaRollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status") int updateLastCheck(@Param("lastCheck") final long lastCheck, @Param("delay") final long delay, @Param("status") final RolloutStatus status); @@ -57,7 +59,7 @@ public interface RolloutRepository extends BaseEntityRepository, * @return the list of {@link Rollout} for specific lastCheck time and * status */ - List findByLastCheckAndStatus(long lastCheck, RolloutStatus status); + List findByLastCheckAndStatus(long lastCheck, RolloutStatus status); /** * Retrieves all {@link Rollout} for a specific {@code name} @@ -66,7 +68,7 @@ public interface RolloutRepository extends BaseEntityRepository, * the rollout name * @return {@link Rollout} for specific name */ - Page findByName(final Pageable pageable, String name); + Page findByName(final Pageable pageable, String name); /** * Retrieves all {@link Rollout} for a specific {@code name} @@ -75,7 +77,7 @@ public interface RolloutRepository extends BaseEntityRepository, * the rollout name * @return {@link Rollout} for specific name */ - Rollout findByName(String name); + JpaRollout findByName(String name); /** * Retrieves all {@link Rollout} for a specific status. @@ -84,5 +86,5 @@ public interface RolloutRepository extends BaseEntityRepository, * the status of the rollouts to retrieve * @return a list of {@link Rollout} having the given status */ - List findByStatus(final RolloutStatus status); + List findByStatus(final RolloutStatus status); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutTargetGroupRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutTargetGroupRepository.java index 2e7eac55d..8cb267c69 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutTargetGroupRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutTargetGroupRepository.java @@ -8,8 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa; -import org.eclipse.hawkbit.repository.model.RolloutTargetGroup; -import org.eclipse.hawkbit.repository.model.RolloutTargetGroupId; +import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup; +import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroupId; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.transaction.annotation.Isolation; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleMetadataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleMetadataRepository.java index 8023a9361..c962b31ec 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleMetadataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleMetadataRepository.java @@ -10,8 +10,9 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -25,8 +26,8 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleMetadataRepository - extends PagingAndSortingRepository, - JpaSpecificationExecutor { + extends PagingAndSortingRepository, + JpaSpecificationExecutor { /** * Saves all given entities. @@ -37,7 +38,7 @@ public interface SoftwareModuleMetadataRepository * in case the given entity is (@literal null}. */ @Override - List save(Iterable entities); + List save(Iterable entities); /** * finds all software module meta data of the given software module id. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java index e03b3e084..08c84b349 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java @@ -10,6 +10,9 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; @@ -30,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Counts all {@link SoftwareModule}s based on the given {@link Type}. @@ -39,7 +42,7 @@ public interface SoftwareModuleRepository * to count for * @return number of {@link SoftwareModule}s */ - Long countByType(SoftwareModuleType type); + Long countByType(JpaSoftwareModuleType type); /** * Retrieves {@link SoftwareModule} by filtering on name AND version AND @@ -54,7 +57,7 @@ public interface SoftwareModuleRepository * @return the found {@link SoftwareModule} with the given name AND version * AND type */ - SoftwareModule findOneByNameAndVersionAndType(String name, String version, SoftwareModuleType type); + JpaSoftwareModule findOneByNameAndVersionAndType(String name, String version, JpaSoftwareModuleType type); /** * deletes the {@link SoftwareModule}s with the given IDs. @@ -69,7 +72,7 @@ public interface SoftwareModuleRepository */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE SoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids") + @Query("UPDATE JpaSoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids") void deleteSoftwareModule(@Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy, @Param("ids") final Long... ids); @@ -81,7 +84,7 @@ public interface SoftwareModuleRepository * @return all {@link SoftwareModule}s that are assigned to given * {@link DistributionSet}. */ - Page findByAssignedTo(Pageable pageable, DistributionSet set); + Page findByAssignedTo(Pageable pageable, JpaDistributionSet set); /** * @@ -92,7 +95,7 @@ public interface SoftwareModuleRepository * {@link DistributionSet} */ @EntityGraph(value = "SoftwareModule.artifacts", type = EntityGraphType.LOAD) - List findByAssignedTo(DistributionSet set); + List findByAssignedTo(JpaDistributionSet set); /** * @param pageable @@ -104,7 +107,7 @@ public interface SoftwareModuleRepository * @return all {@link SoftwareModule}s that are assigned to given * {@link DistributionSet} filtered by {@link SoftwareModuleType}. */ - Page findByAssignedToAndType(Pageable pageable, DistributionSet set, SoftwareModuleType type); + Page findByAssignedToAndType(Pageable pageable, JpaDistributionSet set, JpaSoftwareModuleType type); /** * retrieves all software modules with a given {@link SoftwareModuleType} @@ -117,11 +120,11 @@ public interface SoftwareModuleRepository * @return {@link List} of found {@link SoftwareModule}s */ // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 - @Query("SELECT sm FROM SoftwareModule sm WHERE sm.id IN ?1 and sm.type = ?2") - List findByIdInAndType(Iterable ids, SoftwareModuleType type); + @Query("SELECT sm FROM JpaSoftwareModule sm WHERE sm.id IN ?1 and sm.type = ?2") + List findByIdInAndType(Iterable ids, JpaSoftwareModuleType type); @Override - List save(Iterable entities); + List save(Iterable entities); /** * retrieves all software modules with a given @@ -132,6 +135,6 @@ public interface SoftwareModuleRepository * @return {@link List} of found {@link SoftwareModule}s */ // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 - @Query("SELECT sm FROM SoftwareModule sm WHERE sm.id IN ?1") - List findByIdIn(Iterable ids); + @Query("SELECT sm FROM JpaSoftwareModule sm WHERE sm.id IN ?1") + List findByIdIn(Iterable ids); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java index fe2cfadf4..c4ecfbd74 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -21,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleTypeRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * @param pageable @@ -47,7 +48,7 @@ public interface SoftwareModuleTypeRepository * @return all {@link SoftwareModuleType}s in the repository with given * {@link SoftwareModuleType#getKey()} */ - SoftwareModuleType findByKey(String key); + JpaSoftwareModuleType findByKey(String key); /** * @@ -56,5 +57,5 @@ public interface SoftwareModuleTypeRepository * @return all {@link SoftwareModuleType}s in the repository with given * {@link SoftwareModuleType#getName()} */ - SoftwareModuleType findByName(String name); + JpaSoftwareModuleType findByName(String name); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java index 346fe2ec2..1f2fec8d8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.springframework.data.domain.Page; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -21,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetFilterQueryRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * Find customer target filter by name @@ -35,11 +36,11 @@ public interface TargetFilterQueryRepository * Find list of all custom target filters. */ @Override - Page findAll(); + Page findAll(); @Override @Modifying @Transactional - S save(S entity); + S save(S entity); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetInfoRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetInfoRepository.java index 1c3378bba..815fa3961 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetInfoRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetInfoRepository.java @@ -13,6 +13,7 @@ import java.util.List; import javax.persistence.Entity; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.springframework.cache.annotation.CacheEvict; @@ -42,7 +43,7 @@ public interface TargetInfoRepository { */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status") + @Query("update JpaTargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status") void setTargetUpdateStatus(@Param("status") TargetUpdateStatus status, @Param("targets") List targets); /** @@ -54,7 +55,7 @@ public interface TargetInfoRepository { * @return persisted or updated {@link Entity} */ @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) - S save(S entity); + S save(S entity); /** * Deletes info entries by ID. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java index b3d390016..0d84a3cad 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java @@ -11,11 +11,13 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.Collection; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetWithActionStatus; import org.springframework.cache.annotation.CacheEvict; @@ -35,7 +37,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface TargetRepository extends BaseEntityRepository, JpaSpecificationExecutor { +public interface TargetRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** * Loads {@link Target} including details {@link EntityGraph} by given ID. @@ -45,7 +47,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * @return found {@link Target} or null if not found. */ @EntityGraph(value = "Target.detail", type = EntityGraphType.LOAD) - Target findByControllerId(String controllerID); + JpaTarget findByControllerId(String controllerID); /** * Finds targets by given list of {@link Target#getControllerId()}s. @@ -65,7 +67,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 - @Query("DELETE FROM Target t WHERE t.id IN ?1") + @Query("DELETE FROM JpaTarget t WHERE t.id IN ?1") void deleteByIdIn(final Collection targetIDs); /** @@ -75,8 +77,8 @@ public interface TargetRepository extends BaseEntityRepository, Jp * to be found * @return list of found targets */ - @Query(value = "SELECT DISTINCT t FROM Target t JOIN t.tags tt WHERE tt = :tag") - List findByTag(@Param("tag") final TargetTag tag); + @Query(value = "SELECT DISTINCT t FROM JpaTarget t JOIN t.tags tt WHERE tt = :tag") + List findByTag(@Param("tag") final JpaTargetTag tag); /** * Finds all {@link Target}s based on given {@link Target#getControllerId()} @@ -88,7 +90,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * to search for * @return {@link List} of found {@link Target}s. */ - @Query(value = "SELECT DISTINCT t from Target t JOIN t.tags tt WHERE tt.name = :tagname AND t.controllerId IN :targets") + @Query(value = "SELECT DISTINCT t from JpaTarget t JOIN t.tags tt WHERE tt.name = :tagname AND t.controllerId IN :targets") List findByTagNameAndControllerIdIn(@Param("tagname") final String tag, @Param("targets") final Collection controllerIds); @@ -114,7 +116,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * * @return found targets */ - Page findByTargetInfoInstalledDistributionSet(final Pageable pageable, final DistributionSet set); + Page findByTargetInfoInstalledDistributionSet(final Pageable pageable, final JpaDistributionSet set); /** * retrieves the {@link Target}s which has the {@link DistributionSet} @@ -138,7 +140,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * * @return found targets */ - Page findByAssignedDistributionSet(final Pageable pageable, final DistributionSet set); + Page findByAssignedDistributionSet(final Pageable pageable, final JpaDistributionSet set); /** * Saves all given {@link Target}s. @@ -154,7 +156,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) - List save(Iterable entities); + List save(Iterable entities); /** * Saves a given entity. Use the returned instance for further operations as @@ -168,7 +170,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) - S save(S entity); + S save(S entity); /** * Finds all targets that have defined {@link DistributionSet} assigned. @@ -199,7 +201,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * @return number of found {@link Target}s with given * {@link Target#getControllerId()}s */ - @Query("SELECT COUNT(t) FROM Target t WHERE t.controllerId IN ?1") + @Query("SELECT COUNT(t) FROM JpaTarget t WHERE t.controllerId IN ?1") Long countByControllerIdIn(final Collection ids); /** @@ -228,7 +230,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * @return found targets */ Page findByAssignedDistributionSetOrTargetInfoInstalledDistributionSet(final Pageable pageable, - final DistributionSet assigned, final DistributionSet installed); + final JpaDistributionSet assigned, final JpaDistributionSet installed); /** * Finds all targets that have defined {@link DistributionSet} assigned or @@ -255,12 +257,12 @@ public interface TargetRepository extends BaseEntityRepository, Jp * @see org.springframework.data.repository.CrudRepository#findAll() */ @Override - List findAll(); + List findAll(); @Override // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 - @Query("SELECT t FROM Target t WHERE t.id IN ?1") - List findAll(Iterable ids); + @Query("SELECT t FROM JpaTarget t WHERE t.id IN ?1") + List findAll(Iterable ids); /** * Sets {@link Target#getAssignedDistributionSet()}. @@ -276,11 +278,11 @@ public interface TargetRepository extends BaseEntityRepository, Jp */ @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Query("UPDATE Target t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy WHERE t.id IN :targets") - void setAssignedDistributionSet(@Param("set") DistributionSet set, @Param("lastModifiedAt") Long modifiedAt, + @Query("UPDATE JpaTarget t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy WHERE t.id IN :targets") + void setAssignedDistributionSet(@Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy, @Param("targets") Collection targets); - List findByRolloutTargetGroupRolloutGroup(final RolloutGroup rolloutGroup); + List findByRolloutTargetGroupRolloutGroup(final JpaRolloutGroup rolloutGroup); /** * @@ -304,7 +306,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * the page request parameter * @return a page of all targets related to a rollout group */ - Page findByActionsRolloutGroup(RolloutGroup rolloutGroup, Pageable page); + Page findByActionsRolloutGroup(JpaRolloutGroup rolloutGroup, Pageable page); /** * Find all targets with action status for a specific group. @@ -315,7 +317,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * the ID of the rollout group * @return targets with action status */ - @Query("select DISTINCT NEW org.eclipse.hawkbit.repository.model.TargetWithActionStatus(a.target,a.status) from Action a inner join fetch a.target t where a.rolloutGroup.id = :rolloutGroupId") + @Query("select DISTINCT NEW org.eclipse.hawkbit.repository.model.TargetWithActionStatus(a.target,a.status) from JpaAction a inner join fetch a.target t where a.rolloutGroup.id = :rolloutGroupId") Page findTargetsWithActionStatusByRolloutGroupId(final Pageable pageable, @Param("rolloutGroupId") Long rolloutGroupId); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java index 92f48d699..6b9e021b1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.TargetTag; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; @@ -22,7 +23,7 @@ import org.springframework.transaction.annotation.Transactional; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetTagRepository - extends BaseEntityRepository, JpaSpecificationExecutor { + extends BaseEntityRepository, JpaSpecificationExecutor { /** * deletes the {@link TargetTag}s with the given tag names. @@ -42,7 +43,7 @@ public interface TargetTagRepository * to filter on * @return the {@link TargetTag} if found, otherwise null */ - TargetTag findByNameEquals(final String tagName); + JpaTargetTag findByNameEquals(final String tagName); /** * Returns all instances of the type. @@ -50,8 +51,8 @@ public interface TargetTagRepository * @return all entities */ @Override - List findAll(); + List findAll(); @Override - List save(Iterable entities); + List save(Iterable entities); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java index 6494aafea..bd99cb918 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; @@ -19,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface TenantConfigurationRepository extends BaseEntityRepository { +public interface TenantConfigurationRepository extends BaseEntityRepository { /** * Finds a specific {@link TenantConfiguration} by the configuration key. @@ -28,10 +29,10 @@ public interface TenantConfigurationRepository extends BaseEntityRepository findAll(); + List findAll(); /** * Deletes a tenant configuration by tenant and key. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantMetaDataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantMetaDataRepository.java index 63c213d2c..353f6500b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantMetaDataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantMetaDataRepository.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.transaction.annotation.Isolation; @@ -20,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional; * */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -public interface TenantMetaDataRepository extends PagingAndSortingRepository { +public interface TenantMetaDataRepository extends PagingAndSortingRepository { /** * Search {@link TenantMetaData} by tenant name. @@ -42,7 +43,7 @@ public interface TenantMetaDataRepository extends PagingAndSortingRepository findAll(); + List findAll(); /** * @param tenant diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElement.java similarity index 86% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElement.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElement.java index 8414a6f1a..26a603078 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElement.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; @@ -21,6 +21,10 @@ import javax.persistence.ManyToOne; import javax.persistence.MapsId; import javax.persistence.Table; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; + /** * Relation element between a {@link DistributionSetType} and its * {@link SoftwareModuleType} elements. @@ -40,12 +44,12 @@ public class DistributionSetTypeElement implements Serializable { @MapsId("dsType") @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "distribution_set_type", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_dstype")) - private DistributionSetType dsType; + private JpaDistributionSetType dsType; @MapsId("smType") @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "software_module_type", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_smtype")) - private SoftwareModuleType smType; + private JpaSoftwareModuleType smType; public DistributionSetTypeElement() { // Default constructor for JPA @@ -62,7 +66,7 @@ public class DistributionSetTypeElement implements Serializable { * to true if the {@link SoftwareModuleType} if * mandatory element in the {@link DistributionSet}. */ - public DistributionSetTypeElement(final DistributionSetType dsType, final SoftwareModuleType smType, + public DistributionSetTypeElement(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType, final boolean mandatory) { super(); key = new DistributionSetTypeElementCompositeKey(dsType, smType); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElementCompositeKey.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElementCompositeKey.java similarity index 89% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElementCompositeKey.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElementCompositeKey.java index 2ee1aba0d..f94a3784a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTypeElementCompositeKey.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DistributionSetTypeElementCompositeKey.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; @@ -40,7 +40,7 @@ public class DistributionSetTypeElementCompositeKey implements Serializable { * @param smType * in the key */ - DistributionSetTypeElementCompositeKey(final DistributionSetType dsType, final SoftwareModuleType smType) { + DistributionSetTypeElementCompositeKey(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType) { super(); this.dsType = dsType.getId(); this.smType = smType.getId(); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DsMetadataCompositeKey.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DsMetadataCompositeKey.java similarity index 95% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DsMetadataCompositeKey.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DsMetadataCompositeKey.java index adc37d65a..52ad217c0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DsMetadataCompositeKey.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DsMetadataCompositeKey.java @@ -6,10 +6,12 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; +import org.eclipse.hawkbit.repository.model.DistributionSet; + /** * The DistributionSet Metadata composite key which contains the meta data key * and the ID of the DistributionSet itself. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java new file mode 100644 index 000000000..1080b35fd --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -0,0 +1,274 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.NamedEntityGraphs; +import javax.persistence.NamedSubgraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.cache.CacheField; +import org.eclipse.hawkbit.cache.CacheKeys; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.persistence.annotations.CascadeOnDelete; + +/** + *

+ * Applicable transition changes of the {@link SoftwareModule}s state of a + * {@link Target}, e.g. install, uninstall, update and preparations for the + * transition change, i.e. download. + *

+ * + *

+ * Actions are managed by the SP server and applied to the targets by the + * client. + *

+ */ +@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), + @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), + @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) +@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), + @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), + @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) +@Entity +public class JpaAction extends JpaTenantAwareBaseEntity implements Action { + private static final long serialVersionUID = 1L; + + /** + * the {@link DistributionSet} which should be installed by this action. + */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) + private JpaDistributionSet distributionSet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) + private JpaTarget target; + + @Column(name = "active") + private boolean active; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { + CascadeType.REMOVE }) + private List actionStatus; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) + private JpaRolloutGroup rolloutGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) + private JpaRollout rollout; + + /** + * Note: filled only in {@link Status#DOWNLOAD}. + */ + @Transient + @CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT) + private int downloadProgressPercent; + + /** + * @return the distributionSet + */ + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + /** + * @param distributionSet + * the distributionSet to set + */ + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + /** + * @return true when action is in state {@link Status#CANCELING} or + * {@link Status#CANCELED}, false otherwise + */ + @Override + public boolean isCancelingOrCanceled() { + return status == Status.CANCELING || status == Status.CANCELED; + } + + @Override + public void setActive(final boolean active) { + this.active = active; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + + @Override + public int getDownloadProgressPercent() { + return downloadProgressPercent; + } + + @Override + public void setDownloadProgressPercent(final int downloadProgressPercent) { + this.downloadProgressPercent = downloadProgressPercent; + } + + @Override + public boolean isActive() { + return active; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + /** + * @return the actionType + */ + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public List getActionStatus() { + return actionStatus; + } + + @Override + public void setTarget(final Target target) { + this.target = (JpaTarget) target; + } + + @Override + public Target getTarget() { + return target; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public RolloutGroup getRolloutGroup() { + return rolloutGroup; + } + + @Override + public void setRolloutGroup(final RolloutGroup rolloutGroup) { + this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; + } + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + /** + * checks if the {@link #forcedTime} is hit by the given + * {@code hitTimeMillis}, by means if the given milliseconds are greater + * than the forcedTime. + * + * @param hitTimeMillis + * the milliseconds, mostly the + * {@link System#currentTimeMillis()} + * @return {@code true} if this {@link #type} is in + * {@link ActionType#TIMEFORCED} and the given {@code hitTimeMillis} + * is greater than the {@link #forcedTime} otherwise {@code false} + */ + @Override + public boolean isHitAutoForceTime(final long hitTimeMillis) { + if (actionType == ActionType.TIMEFORCED) { + return hitTimeMillis >= forcedTime; + } + return false; + } + + /** + * @return {@code true} if either the {@link #type} is + * {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but + * then if the {@link #forcedTime} has been exceeded otherwise + * always {@code false} + */ + @Override + public boolean isForce() { + switch (actionType) { + case FORCED: + return true; + case TIMEFORCED: + return isHitAutoForceTime(System.currentTimeMillis()); + default: + return false; + } + } + + /** + * @return true when action is forced, false otherwise + */ + @Override + public boolean isForced() { + return actionType == ActionType.FORCED; + } + + @Override + public String toString() { + return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java new file mode 100644 index 000000000..94f76cae7 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.Action.Status; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.persistence.annotations.CascadeOnDelete; + +import com.google.common.base.Splitter; + +/** + * Entity to store the status for a specific action. + */ +@Table(name = "sp_action_status", indexes = { @Index(name = "sp_idx_action_status_01", columnList = "tenant,action"), + @Index(name = "sp_idx_action_status_02", columnList = "tenant,action,status"), + @Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") }) +@Entity +public class JpaActionStatus extends JpaTenantAwareBaseEntity implements ActionStatus { + private static final long serialVersionUID = 1L; + + @Column(name = "target_occurred_at") + private Long occurredAt; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "action", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_act_stat_action")) + private JpaAction action; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class) + @CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = { + @Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") }) + @Column(name = "detail_message", length = 512) + private final List messages = new ArrayList<>(); + + /** + * Creates a new {@link ActionStatus} object. + * + * @param action + * the action for this action status + * @param status + * the status for this action status + * @param occurredAt + * the occurred timestamp + */ + public JpaActionStatus(final Action action, final Status status, final Long occurredAt) { + this.action = (JpaAction) action; + this.status = status; + this.occurredAt = occurredAt; + } + + /** + * Creates a new {@link ActionStatus} object. + * + * @param action + * the action for this action status + * @param status + * the status for this action status + * @param occurredAt + * the occurred timestamp + * @param messages + * the messages which should be added to this action status + */ + public JpaActionStatus(final JpaAction action, final Status status, final Long occurredAt, + final String... messages) { + this.action = action; + this.status = status; + this.occurredAt = occurredAt; + for (final String msg : messages) { + addMessage(msg); + } + } + + /** + * JPA default constructor. + */ + public JpaActionStatus() { + // JPA default constructor. + } + + @Override + public Long getOccurredAt() { + return occurredAt; + } + + @Override + public void setOccurredAt(final Long occurredAt) { + this.occurredAt = occurredAt; + } + + /** + * Adds message including splitting in case it exceeds 512 length. + * + * @param message + * to add + */ + @Override + public final void addMessage(final String message) { + Splitter.fixedLength(512).split(message).forEach(messages::add); + } + + @Override + public List getMessages() { + return messages; + } + + @Override + public Action getAction() { + return action; + } + + @Override + public void setAction(final Action action) { + this.action = (JpaAction) action; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java new file mode 100644 index 000000000..be0b5e1ac --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; + +import org.eclipse.hawkbit.repository.model.Artifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + +/** + * Tenant specific locally stored artifact representation that is used by + * {@link SoftwareModule}. + */ +@MappedSuperclass +public abstract class JpaArtifact extends JpaTenantAwareBaseEntity implements Artifact { + private static final long serialVersionUID = 1L; + + @Column(name = "sha1_hash", length = 40, nullable = true) + private String sha1Hash; + + @Column(name = "md5_hash", length = 32, nullable = true) + private String md5Hash; + + @Column(name = "file_size") + private Long size; + + @Override + public abstract SoftwareModule getSoftwareModule(); + + @Override + public String getMd5Hash() { + return md5Hash; + } + + @Override + public String getSha1Hash() { + return sha1Hash; + } + + public void setMd5Hash(final String md5Hash) { + this.md5Hash = md5Hash; + } + + public void setSha1Hash(final String sha1Hash) { + this.sha1Hash = sha1Hash; + } + + @Override + public Long getSize() { + return size; + } + + public void setSize(final Long size) { + this.size = size; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaBaseEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaBaseEntity.java new file mode 100644 index 000000000..cfe4ada52 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaBaseEntity.java @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Version; + +import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener; +import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener; +import org.eclipse.hawkbit.repository.model.BaseEntity; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +/** + * Holder of the base attributes common to all entities. + * + */ +@MappedSuperclass +@Access(AccessType.FIELD) +@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) +public abstract class JpaBaseEntity implements BaseEntity { + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + private String createdBy; + private String lastModifiedBy; + private Long createdAt; + private Long lastModifiedAt; + + @Version + @Column(name = "optlock_revision") + private long optLockRevision; + + /** + * Default constructor needed for JPA entities. + */ + public JpaBaseEntity() { + // Default constructor needed for JPA entities. + } + + @Override + @Access(AccessType.PROPERTY) + @Column(name = "created_at", insertable = true, updatable = false) + public Long getCreatedAt() { + return createdAt; + } + + @Override + @Access(AccessType.PROPERTY) + @Column(name = "created_by", insertable = true, updatable = false, length = 40) + public String getCreatedBy() { + return createdBy; + } + + @Override + @Access(AccessType.PROPERTY) + @Column(name = "last_modified_at", insertable = false, updatable = true) + public Long getLastModifiedAt() { + return lastModifiedAt; + } + + @Override + @Access(AccessType.PROPERTY) + @Column(name = "last_modified_by", insertable = false, updatable = true, length = 40) + public String getLastModifiedBy() { + return lastModifiedBy; + } + + @CreatedBy + public void setCreatedBy(final String createdBy) { + this.createdBy = createdBy; + } + + @LastModifiedBy + public void setLastModifiedBy(final String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + + @CreatedDate + public void setCreatedAt(final Long createdAt) { + this.createdAt = createdAt; + } + + @LastModifiedDate + public void setLastModifiedAt(final Long lastModifiedAt) { + this.lastModifiedAt = lastModifiedAt; + } + + @Override + public long getOptLockRevision() { + return optLockRevision; + } + + public void setOptLockRevision(final long optLockRevision) { + this.optLockRevision = optLockRevision; + } + + @Override + public Long getId() { + return id; + } + + @Override + public String toString() { + return "BaseEntity [id=" + id + "]"; + } + + public void setId(final Long id) { + this.id = id; + } + + /** + * Defined equals/hashcode strategy for the repository in general is that an + * entity is equal if it has the same {@link #getId()} and + * {@link #getOptLockRevision()} and class. + * + * @see java.lang.Object#hashCode() + */ + @Override + // Exception squid:S864 - generated code + @SuppressWarnings({ "squid:S864" }) + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (id == null ? 0 : id.hashCode()); + result = prime * result + (int) (optLockRevision ^ optLockRevision >>> 32); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + /** + * Defined equals/hashcode strategy for the repository in general is that an + * entity is equal if it has the same {@link #getId()} and + * {@link #getOptLockRevision()} and class. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { // NOSONAR - as this is generated + // code + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(this.getClass().isInstance(obj))) { + return false; + } + final JpaBaseEntity other = (JpaBaseEntity) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (optLockRevision != other.optLockRevision) { + return false; + } + return true; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java new file mode 100644 index 000000000..201d4d657 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -0,0 +1,326 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; +import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetIdName; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.persistence.annotations.CascadeOnDelete; + +/** + *

+ * The {@link DistributionSet} is defined in the SP repository and contains at + * least an OS and an Agent Hub. + *

+ * + *

+ * A {@link Target} has exactly one target {@link DistributionSet} assigned. + *

+ * + */ +@Entity +@Table(name = "sp_distribution_set", uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { + @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), + @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), + @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), + @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) +public class JpaDistributionSet extends JpaNamedVersionedEntity implements DistributionSet { + private static final long serialVersionUID = 1L; + + @Column(name = "required_migration_step") + private boolean requiredMigrationStep = false; + + @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinTable(name = "sp_ds_module", joinColumns = { + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) + private final Set modules = new HashSet<>(); + + @ManyToMany(targetEntity = JpaDistributionSetTag.class) + @JoinTable(name = "sp_ds_dstag", joinColumns = { + @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) + private Set tags = new HashSet<>(); + + @Column(name = "deleted") + private boolean deleted = false; + + @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) + private List installedAtTargets; + + @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) + private List actions; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { + CascadeType.REMOVE }) + @JoinColumn(name = "ds_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) + @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) + private DistributionSetType type; + + @Column(name = "complete") + private boolean complete = false; + + /** + * Default constructor. + */ + public JpaDistributionSet() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link DistributionSet} + * @param version + * of the {@link DistributionSet} + * @param description + * of the {@link DistributionSet} + * @param type + * of the {@link DistributionSet} + * @param moduleList + * {@link SoftwareModule}s of the {@link DistributionSet} + */ + public JpaDistributionSet(final String name, final String version, final String description, + final DistributionSetType type, final Iterable moduleList) { + super(name, version, description); + + this.type = type; + if (moduleList != null) { + moduleList.forEach(this::addModule); + } + if (this.type != null) { + complete = this.type.checkComplete(this); + } + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + /** + * @return immutable list of meta data elements. + */ + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + @Override + public List getActions() { + return actions; + } + + @Override + public boolean isRequiredMigrationStep() { + return requiredMigrationStep; + } + + @Override + public DistributionSet setDeleted(final boolean deleted) { + this.deleted = deleted; + return this; + } + + @Override + public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { + requiredMigrationStep = isRequiredMigrationStep; + return this; + } + + @Override + public DistributionSet setTags(final Set tags) { + this.tags = tags; + return this; + } + + /** + * @return the assignedTargets + */ + @Override + public List getAssignedTargets() { + return assignedToTargets; + } + + /** + * @return the installedTargets + */ + @Override + public List getInstalledTargets() { + return installedAtTargets; + } + + @Override + public String toString() { + return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() + + ", getId()=" + getId() + "]"; + } + + /** + * + * @return unmodifiableSet of {@link SoftwareModule}. + */ + @Override + public Set getModules() { + return Collections.unmodifiableSet(modules); + } + + @Override + public DistributionSetIdName getDistributionSetIdName() { + return new DistributionSetIdName(getId(), getName(), getVersion()); + } + + /** + * @param softwareModule + * @return true if the module was added and false + * if it already existed in the set + * + */ + @Override + public boolean addModule(final SoftwareModule softwareModule) { + + // we cannot allow that modules are added without a type defined + if (type == null) { + throw new DistributionSetTypeUndefinedException(); + } + + // check if it is allowed to such a module to this DS type + if (!type.containsModuleType(softwareModule.getType())) { + throw new UnsupportedSoftwareModuleForThisDistributionSetException(); + } + + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + return false; + } + + final long allready = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); + + if (allready >= softwareModule.getType().getMaxAssignments()) { + final Optional sameKey = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); + modules.remove(sameKey.get()); + } + + if (modules.add(softwareModule)) { + complete = type.checkComplete(this); + return true; + } + + return false; + } + + /** + * Removed given {@link SoftwareModule} from this DS instance. + * + * @param softwareModule + * to remove + * @return true if element was found and removed + */ + @Override + public boolean removeModule(final SoftwareModule softwareModule) { + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + modules.remove(found.get()); + complete = type.checkComplete(this); + return true; + } + + return false; + + } + + /** + * Searches through modules for the given type. + * + * @param type + * to search for + * @return SoftwareModule of given type or null if not in the + * list. + */ + @Override + public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { + final Optional result = modules.stream().filter(module -> module.getType().equals(type)) + .findFirst(); + + if (result.isPresent()) { + return result.get(); + } + + return null; + } + + @Override + public DistributionSetType getType() { + return type; + } + + @Override + public void setType(final DistributionSetType type) { + this.type = type; + } + + @Override + public boolean isComplete() { + return complete; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetMetadata.java new file mode 100644 index 000000000..b73e3c72e --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetMetadata.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; + +/** + * Meta data for {@link DistributionSet}. + * + */ +@IdClass(DsMetadataCompositeKey.class) +@Entity +@Table(name = "sp_ds_metadata") +public class JpaDistributionSetMetadata extends JpaMetaData implements DistributionSetMetadata { + private static final long serialVersionUID = 1L; + + @Id + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds")) + private JpaDistributionSet distributionSet; + + public JpaDistributionSetMetadata() { + // default public constructor for JPA + } + + public JpaDistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) { + super(key, value); + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + public DsMetadataCompositeKey getId() { + return new DsMetadataCompositeKey(distributionSet, getKey()); + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (!super.equals(obj)) { + return false; + } + final JpaDistributionSetMetadata other = (JpaDistributionSetMetadata) obj; + if (distributionSet == null) { + if (other.distributionSet != null) { + return false; + } + } else if (!distributionSet.equals(other.distributionSet)) { + return false; + } + return true; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetTag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetTag.java new file mode 100644 index 000000000..4b6e67135 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetTag.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Index; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; + +/** + * A {@link DistributionSetTag} is used to describe DistributionSet attributes + * and use them also for filtering the DistributionSet list. + * + */ +@Entity +@Table(name = "sp_distributionset_tag", indexes = { + @Index(name = "sp_idx_distribution_set_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_ds_tag")) +public class JpaDistributionSetTag extends JpaTag implements DistributionSetTag { + private static final long serialVersionUID = 1L; + + @ManyToMany(mappedBy = "tags", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY) + private List assignedToDistributionSet; + + /** + * Public constructor. + * + * @param name + * of the {@link DistributionSetTag} + **/ + public JpaDistributionSetTag(final String name) { + super(name, null, null); + } + + /** + * Public constructor. + * + * @param name + * of the {@link DistributionSetTag} + * @param description + * of the {@link DistributionSetTag} + * @param colour + * of tag in UI + */ + public JpaDistributionSetTag(final String name, final String description, final String colour) { + super(name, description, colour); + } + + public JpaDistributionSetTag() { + super(); + } + + @Override + public List getAssignedToDistributionSet() { + return assignedToDistributionSet; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { // NOSONAR - as this is generated + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof DistributionSetTag)) { + return false; + } + + return true; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetType.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetType.java new file mode 100644 index 000000000..d8edd4dcc --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSetType.java @@ -0,0 +1,310 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; + +/** + * A distribution set type defines which software module types can or have to be + * {@link DistributionSet}. + * + */ +@Entity +@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_prim", columnList = "tenant,id") }, uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_dst_name"), + @UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_dst_key") }) +public class JpaDistributionSetType extends JpaNamedEntity implements DistributionSetType { + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = { + CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true) + @JoinColumn(name = "distribution_set_type", insertable = false, updatable = false) + private final Set elements = new HashSet<>(); + + @Column(name = "type_key", nullable = false, length = 64) + private String key; + + @Column(name = "colour", nullable = true, length = 16) + private String colour; + + @Column(name = "deleted") + private boolean deleted = false; + + 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) { + this(key, name, description, null); + } + + /** + * Constructor. + * + * @param key + * of the type + * @param name + * of the type + * @param description + * of the type + * @param color + * of the type. It will be null by default + */ + public JpaDistributionSetType(final String key, final String name, final String description, final String color) { + super(name, description); + this.key = key; + colour = color; + } + + /** + * @return the deleted + */ + @Override + public boolean isDeleted() { + return deleted; + } + + /** + * @param deleted + * the deleted to set + */ + @Override + public void setDeleted(final boolean deleted) { + this.deleted = deleted; + } + + @Override + public Set getMandatoryModuleTypes() { + return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType()) + .collect(Collectors.toSet()); + } + + @Override + public Set getOptionalModuleTypes() { + return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType()) + .collect(Collectors.toSet()); + } + + /** + * Checks if the given {@link SoftwareModuleType} is in this + * {@link DistributionSetType}. + * + * @param softwareModuleType + * search for + * @return true if found + */ + @Override + public boolean containsModuleType(final SoftwareModuleType softwareModuleType) { + for (final DistributionSetTypeElement distributionSetTypeElement : elements) { + if (distributionSetTypeElement.getSmType().equals(softwareModuleType)) { + return true; + } + + } + return false; + } + + /** + * Checks if the given {@link SoftwareModuleType} is in this + * {@link DistributionSetType} and defined as + * {@link DistributionSetTypeElement#isMandatory()}. + * + * @param softwareModuleType + * search for + * @return true if found + */ + @Override + public boolean containsMandatoryModuleType(final SoftwareModuleType softwareModuleType) { + return elements.stream().filter(element -> element.isMandatory()) + .filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent(); + + } + + /** + * Checks if the given {@link SoftwareModuleType} is in this + * {@link DistributionSetType} and defined as + * {@link DistributionSetTypeElement#isMandatory()}. + * + * @param softwareModuleType + * search for by {@link SoftwareModuleType#getId()} + * @return true if found + */ + @Override + public boolean containsMandatoryModuleType(final Long softwareModuleTypeId) { + return elements.stream().filter(element -> element.isMandatory()) + .filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent(); + + } + + /** + * Checks if the given {@link SoftwareModuleType} is in this + * {@link DistributionSetType} and NOT defined as + * {@link DistributionSetTypeElement#isMandatory()}. + * + * @param softwareModuleType + * search for + * @return true if found + */ + @Override + public boolean containsOptionalModuleType(final SoftwareModuleType softwareModuleType) { + return elements.stream().filter(element -> !element.isMandatory()) + .filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent(); + + } + + /** + * Checks if the given {@link SoftwareModuleType} is in this + * {@link DistributionSetType} and NOT defined as + * {@link DistributionSetTypeElement#isMandatory()}. + * + * @param softwareModuleTypeId + * search by {@link SoftwareModuleType#getId()} + * @return true if found + */ + @Override + public boolean containsOptionalModuleType(final Long softwareModuleTypeId) { + return elements.stream().filter(element -> !element.isMandatory()) + .filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent(); + + } + + /** + * Compares the modules of this {@link DistributionSetType} and the given + * one. + * + * @param dsType + * to compare with + * @return true if the lists are identical. + */ + @Override + public boolean areModuleEntriesIdentical(final DistributionSetType dsType) { + return new HashSet(((JpaDistributionSetType) dsType).elements).equals(elements); + } + + /** + * Adds {@link SoftwareModuleType} that is optional for the + * {@link DistributionSet}. + * + * @param smType + * to add + * @return updated instance + */ + @Override + public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) { + elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, false)); + + return this; + } + + /** + * Adds {@link SoftwareModuleType} that is mandatory for the + * {@link DistributionSet}. + * + * @param smType + * to add + * @return updated instance + */ + @Override + public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) { + elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, true)); + + return this; + } + + /** + * Removes {@link SoftwareModuleType} from the list. + * + * @param smTypeId + * to remove + * @return updated instance + */ + @Override + public DistributionSetType removeModuleType(final Long smTypeId) { + // we search by id (standard equals compares also revison) + final Optional found = elements.stream() + .filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst(); + + if (found.isPresent()) { + elements.remove(found.get()); + } + + return this; + } + + @Override + public String getKey() { + return key; + } + + @Override + public void setKey(final String key) { + this.key = key; + } + + /** + * @param distributionSet + * to check for completeness + * @return true if the all mandatory software module types are + * in the system. + */ + @Override + public boolean checkComplete(final DistributionSet distributionSet) { + return distributionSet.getModules().stream().map(module -> module.getType()).collect(Collectors.toList()) + .containsAll(getMandatoryModuleTypes()); + } + + @Override + public String getColour() { + return colour; + } + + @Override + public void setColour(final String colour) { + this.colour = colour; + } + + public Set getElements() { + return elements; + } + + @Override + public String toString() { + return "DistributionSetType [key=" + key + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]"; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifact.java new file mode 100644 index 000000000..ab55bf307 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifact.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.net.URL; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.repository.model.ExternalArtifact; +import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + +/** + * External artifact representation with all the necessary information to + * generate an artifact {@link URL} at runtime. + * + */ +@Table(name = "sp_external_artifact", indexes = { + @Index(name = "sp_idx_external_artifact_prim", columnList = "id,tenant") }) +@Entity +public class JpaExternalArtifact extends JpaArtifact implements ExternalArtifact { + private static final long serialVersionUID = 1L; + + @ManyToOne + @JoinColumn(name = "provider", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_art_to_ext_provider")) + private JpaExternalArtifactProvider externalArtifactProvider; + + @Column(name = "url_suffix", length = 512) + private String urlSuffix; + + // CascadeType.PERSIST as we register ourself at the BSM + @ManyToOne(optional = false, cascade = { CascadeType.PERSIST }) + @JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_external_assigned_sm")) + private JpaSoftwareModule softwareModule; + + /** + * Default constructor. + */ + public JpaExternalArtifact() { + super(); + } + + /** + * Constructs {@link ExternalArtifact}. + * + * @param externalArtifactProvider + * of the artifact + * @param urlSuffix + * of the artifact + * @param softwareModule + * of the artifact + */ + public JpaExternalArtifact(@NotNull final ExternalArtifactProvider externalArtifactProvider, final String urlSuffix, + final SoftwareModule softwareModule) { + setSoftwareModule(softwareModule); + this.externalArtifactProvider = (JpaExternalArtifactProvider) externalArtifactProvider; + + if (urlSuffix != null) { + this.urlSuffix = urlSuffix; + } else { + this.urlSuffix = externalArtifactProvider.getDefaultSuffix(); + } + } + + /** + * @return the softwareModule + */ + @Override + public SoftwareModule getSoftwareModule() { + return softwareModule; + } + + @Override + public final void setSoftwareModule(final SoftwareModule softwareModule) { + this.softwareModule = (JpaSoftwareModule) softwareModule; + this.softwareModule.addArtifact(this); + } + + @Override + public ExternalArtifactProvider getExternalArtifactProvider() { + return externalArtifactProvider; + } + + @Override + public String getUrl() { + return new StringBuilder().append(externalArtifactProvider.getBasePath()).append(urlSuffix).toString(); + } + + @Override + public String getUrlSuffix() { + return urlSuffix; + } + + @Override + public void setExternalArtifactProvider(final ExternalArtifactProvider externalArtifactProvider) { + this.externalArtifactProvider = (JpaExternalArtifactProvider) externalArtifactProvider; + } + + /** + * @param urlSuffix + * the urlSuffix to set + */ + @Override + public void setUrlSuffix(final String urlSuffix) { + this.urlSuffix = urlSuffix; + } + + @Override + public int hashCode() { // NOSONAR - as this is generated + final int prime = 31; + int result = super.hashCode(); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { // NOSONAR - as this is generated + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof JpaExternalArtifact)) { + return false; + } + + return true; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifactProvider.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifactProvider.java new file mode 100644 index 000000000..527a90510 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaExternalArtifactProvider.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Index; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.model.ExternalArtifact; +import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; + +/** + * External repositories for artifact storage. The SP server provides URLs for + * the targets to download from these external resources but does not access + * them itself. + * + */ +@Table(name = "sp_external_provider", indexes = { + @Index(name = "sp_idx_external_provider_prim", columnList = "tenant,id") }) +@Entity +public class JpaExternalArtifactProvider extends JpaNamedEntity implements ExternalArtifactProvider { + private static final long serialVersionUID = 1L; + + @Column(name = "base_url", length = 512, nullable = false) + private String basePath; + + @Column(name = "default_url_suffix", length = 512, nullable = true) + private String defaultSuffix; + + /** + * Constructs {@link ExternalArtifactProvider} based on given properties. + * + * @param name + * of the provided + * @param description + * which is optional + * @param baseURL + * of all {@link ExternalArtifact}s of the provider + * @param defaultUrlSuffix + * that is used if {@link ExternalArtifact#getUrlSuffix()} is + * empty. + */ + public JpaExternalArtifactProvider(final String name, final String description, final String baseURL, + final String defaultUrlSuffix) { + super(name, description); + basePath = baseURL; + defaultSuffix = defaultUrlSuffix; + } + + JpaExternalArtifactProvider() { + super(); + defaultSuffix = ""; + basePath = ""; + } + + @Override + public String getBasePath() { + return basePath; + } + + @Override + public String getDefaultSuffix() { + return defaultSuffix; + } + + @Override + public void setBasePath(final String basePath) { + this.basePath = basePath; + } + + @Override + public void setDefaultSuffix(final String defaultSuffix) { + this.defaultSuffix = defaultSuffix; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaLocalArtifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaLocalArtifact.java new file mode 100644 index 000000000..7c6de6c0d --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaLocalArtifact.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + +import com.mongodb.gridfs.GridFS; +import com.mongodb.gridfs.GridFSFile; + +/** + * Tenant specific locally stored artifact representation that is used by + * {@link SoftwareModule} . It contains all information that is provided by the + * user while all SP server generated information related to the artifact (hash, + * length) is stored directly with the binary itself. + * + * + * + */ +@Table(name = "sp_artifact", indexes = { @Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"), + @Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") }) +@Entity +public class JpaLocalArtifact extends JpaArtifact implements LocalArtifact { + private static final long serialVersionUID = 1L; + + @NotNull + @Column(name = "gridfs_file_name", length = 40) + private String gridFsFileName; + + @NotNull + @Column(name = "provided_file_name", length = 256) + private String filename; + + @ManyToOne(optional = false, cascade = { CascadeType.PERSIST }) + @JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm")) + private JpaSoftwareModule softwareModule; + + /** + * Default constructor. + */ + public JpaLocalArtifact() { + super(); + } + + /** + * Constructs artifact. + * + * @param gridFsFileName + * that is the link to the {@link GridFS} entity. + * @param filename + * that is used by {@link GridFSFile} store. + * @param softwareModule + * of this artifact + */ + public JpaLocalArtifact(@NotNull final String gridFsFileName, @NotNull final String filename, + final SoftwareModule softwareModule) { + setSoftwareModule(softwareModule); + this.gridFsFileName = gridFsFileName; + this.filename = filename; + } + + @Override + public int hashCode() { // NOSONAR - as this is generated + final int prime = 31; + int result = super.hashCode(); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { // NOSONAR - as this is generated + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof LocalArtifact)) { + return false; + } + + return true; + } + + @Override + public SoftwareModule getSoftwareModule() { + return softwareModule; + } + + @Override + public final void setSoftwareModule(final SoftwareModule softwareModule) { + this.softwareModule = (JpaSoftwareModule) softwareModule; + this.softwareModule.addArtifact(this); + } + + public String getGridFsFileName() { + return gridFsFileName; + } + + @Override + public String getFilename() { + return filename; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaMetaData.java new file mode 100644 index 000000000..f2d905d89 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaMetaData.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +import org.eclipse.hawkbit.repository.model.MetaData; + +/** + * Meta data for entities. + * + */ +@MappedSuperclass +public abstract class JpaMetaData implements MetaData { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "meta_key", length = 128) + private String key; + + @Column(name = "meta_value", length = 4000) + @Basic + private String value; + + public JpaMetaData(final String key, final String value) { + super(); + this.key = key; + this.value = value; + } + + public JpaMetaData() { + // Default constructor needed for JPA entities + } + + @Override + public String getKey() { + return key; + } + + @Override + public void setKey(final String key) { + this.key = key; + } + + @Override + public String getValue() { + return value; + } + + @Override + public void setValue(final String value) { + this.value = value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(this.getClass().isInstance(obj))) { + return false; + } + final JpaMetaData other = (JpaMetaData) obj; + if (key == null) { + if (other.key != null) { + return false; + } + } else if (!key.equals(other.key)) { + return false; + } + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!value.equals(other.value)) { + return false; + } + return true; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedEntity.java new file mode 100644 index 000000000..e4e48ac36 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedEntity.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; + +import org.eclipse.hawkbit.repository.model.NamedEntity; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; + +/** + * {@link TenantAwareBaseEntity} extension for all entities that are named in + * addition to their technical ID. + */ +@MappedSuperclass +public abstract class JpaNamedEntity extends JpaTenantAwareBaseEntity implements NamedEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "name", nullable = false, length = 64) + private String name; + + @Column(name = "description", nullable = true, length = 512) + private String description; + + /** + * Default constructor. + */ + public JpaNamedEntity() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link NamedEntity} + * @param description + * of the {@link NamedEntity} + */ + public JpaNamedEntity(final String name, final String description) { + this.name = name; + this.description = description; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setDescription(final String description) { + this.description = description; + } + + @Override + public void setName(final String name) { + this.name = name; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedVersionedEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedVersionedEntity.java new file mode 100644 index 000000000..33a7036d5 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaNamedVersionedEntity.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; + +import org.eclipse.hawkbit.repository.model.NamedEntity; +import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; + +/** + * Extension for {@link NamedEntity} that are versioned. + * + */ +@MappedSuperclass +public abstract class JpaNamedVersionedEntity extends JpaNamedEntity implements NamedVersionedEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "version", nullable = false, length = 64) + private String version; + + /** + * parameterized constructor. + * + * @param name + * of the entity + * @param version + * of the entity + * @param description + */ + public JpaNamedVersionedEntity(final String name, final String version, final String description) { + super(name, description); + this.version = version; + } + + JpaNamedVersionedEntity() { + super(); + } + + @Override + public String getVersion() { + return version; + } + + @Override + public void setVersion(final String version) { + this.version = version; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java new file mode 100644 index 000000000..25e1a3a93 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.cache.CacheField; +import org.eclipse.hawkbit.cache.CacheKeys; +import org.eclipse.hawkbit.repository.model.Action.ActionType; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; + +/** + * @author Michael Hirsch + * + */ +@Entity +@Table(name = "sp_rollout", indexes = { + @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_rollout")) +public class JpaRollout extends JpaNamedEntity implements Rollout { + + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = JpaRolloutGroup.class) + @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) + private List rolloutGroups; + + @Column(name = "target_filter", length = 1024, nullable = false) + private String targetFilterQuery; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) + private JpaDistributionSet distributionSet; + + @Column(name = "status") + private RolloutStatus status = RolloutStatus.CREATING; + + @Column(name = "last_check") + private long lastCheck = 0L; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType = ActionType.FORCED; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) + private int rolloutGroupsTotal = 0; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) + private int rolloutGroupsCreated = 0; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public List getRolloutGroups() { + return rolloutGroups; + } + + @Override + public void setRolloutGroups(final List rolloutGroups) { + this.rolloutGroups = rolloutGroups; + } + + @Override + public String getTargetFilterQuery() { + return targetFilterQuery; + } + + @Override + public void setTargetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + } + + @Override + public RolloutStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutStatus status) { + this.status = status; + } + + @Override + public long getLastCheck() { + return lastCheck; + } + + @Override + public void setLastCheck(final long lastCheck) { + this.lastCheck = lastCheck; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + @Override + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + @Override + public int getRolloutGroupsTotal() { + return rolloutGroupsTotal; + } + + @Override + public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { + this.rolloutGroupsTotal = rolloutGroupsTotal; + } + + @Override + public int getRolloutGroupsCreated() { + return rolloutGroupsCreated; + } + + @Override + public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { + this.rolloutGroupsCreated = rolloutGroupsCreated; + } + + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery + + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck + + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } + + /** + * + * State machine for rollout. + * + */ + public enum RolloutStatus { + + /** + * Rollouts is beeing created. + */ + CREATING, + + /** + * Rollout is ready to start. + */ + READY, + + /** + * Rollout is paused. + */ + PAUSED, + + /** + * Rollout is starting. + */ + STARTING, + + /** + * Rollout is stopped. + */ + STOPPED, + + /** + * Rollout is running. + */ + RUNNING, + + /** + * Rollout is finished. + */ + FINISHED, + + /** + * Rollout could not created due errors, might be database problem due + * asynchronous creating. + */ + ERROR_CREATING, + + /** + * Rollout could not started due errors, might be database problem due + * asynchronous starting. + */ + ERROR_STARTING; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java new file mode 100644 index 000000000..f167d89fd --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -0,0 +1,509 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; + +/** + * JPA entity definition of persisting a group of an rollout. + * + * @author Michael Hirsch + * + */ +@Entity +@Table(name = "sp_rolloutgroup", indexes = { + @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) +public class JpaRolloutGroup extends JpaNamedEntity implements RolloutGroup { + + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) + private JpaRollout rollout; + + @Column(name = "status") + private RolloutGroupStatus status = RolloutGroupStatus.READY; + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) + @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY) + private JpaRolloutGroup parent; + + @Column(name = "success_condition", nullable = false) + private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + + @Column(name = "success_condition_exp", length = 512, nullable = false) + private String successConditionExp = null; + + @Column(name = "success_action", nullable = false) + private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + + @Column(name = "success_action_exp", length = 512, nullable = false) + private String successActionExp = null; + + @Column(name = "error_condition") + private RolloutGroupErrorCondition errorCondition = null; + + @Column(name = "error_condition_exp", length = 512) + private String errorConditionExp = null; + + @Column(name = "error_action") + private RolloutGroupErrorAction errorAction = null; + + @Column(name = "error_action_exp", length = 512) + private String errorActionExp = null; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public RolloutGroupStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutGroupStatus status) { + this.status = status; + } + + public List getRolloutTargetGroup() { + return rolloutTargetGroup; + } + + @Override + public RolloutGroup getParent() { + return parent; + } + + @Override + public void setParent(final RolloutGroup parent) { + this.parent = (JpaRolloutGroup) parent; + } + + @Override + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + @Override + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + @Override + public String getSuccessConditionExp() { + return successConditionExp; + } + + @Override + public void setSuccessConditionExp(final String finishExp) { + successConditionExp = finishExp; + } + + @Override + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + @Override + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + @Override + public String getErrorConditionExp() { + return errorConditionExp; + } + + @Override + public void setErrorConditionExp(final String errorExp) { + errorConditionExp = errorExp; + } + + @Override + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + @Override + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + @Override + public String getErrorActionExp() { + return errorActionExp; + } + + @Override + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + + @Override + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + @Override + public String getSuccessActionExp() { + return successActionExp; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + @Override + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + @Override + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + @Override + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + /** + * @return the totalTargetCountStatus + */ + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + /** + * @param totalTargetCountStatus + * the totalTargetCountStatus to set + */ + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup + + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp + + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() + + ", getId()=" + getId() + "]"; + } + + /** + * Rollout goup state machine. + * + */ + public enum RolloutGroupStatus { + + /** + * Ready to start the group. + */ + READY, + + /** + * Group is scheduled and started sometime, e.g. trigger of group + * before. + */ + SCHEDULED, + + /** + * Group is finished. + */ + FINISHED, + + /** + * Group is finished and has errors. + */ + ERROR, + + /** + * Group is running. + */ + RUNNING; + } + + /** + * The condition to evaluate if an group is success state. + */ + public enum RolloutGroupSuccessCondition { + THRESHOLD("thresholdRolloutGroupSuccessCondition"); + + private final String beanName; + + private RolloutGroupSuccessCondition(final String beanName) { + this.beanName = beanName; + } + + /** + * @return the beanName + */ + public String getBeanName() { + return beanName; + } + } + + /** + * The condition to evaluate if an group is in error state. + */ + public enum RolloutGroupErrorCondition { + THRESHOLD("thresholdRolloutGroupErrorCondition"); + + private final String beanName; + + private RolloutGroupErrorCondition(final String beanName) { + this.beanName = beanName; + } + + /** + * @return the beanName + */ + public String getBeanName() { + return beanName; + } + } + + /** + * The actions executed when the {@link RolloutGroup#errorCondition} is hit. + */ + public enum RolloutGroupErrorAction { + PAUSE("pauseRolloutGroupAction"); + + private final String beanName; + + private RolloutGroupErrorAction(final String beanName) { + this.beanName = beanName; + } + + /** + * @return the beanName + */ + public String getBeanName() { + return beanName; + } + } + + /** + * The actions executed when the {@link RolloutGroup#successCondition} is + * hit. + */ + public enum RolloutGroupSuccessAction { + NEXTGROUP("startNextRolloutGroupAction"); + + private final String beanName; + + private RolloutGroupSuccessAction(final String beanName) { + this.beanName = beanName; + } + + /** + * @return the beanName + */ + public String getBeanName() { + return beanName; + } + } + + /** + * Object which holds all {@link RolloutGroup} conditions together which can + * easily built. + */ + public static class RolloutGroupConditions { + private RolloutGroupSuccessCondition successCondition = null; + private String successConditionExp = null; + private RolloutGroupSuccessAction successAction = null; + private String successActionExp = null; + private RolloutGroupErrorCondition errorCondition = null; + private String errorConditionExp = null; + private RolloutGroupErrorAction errorAction = null; + private String errorActionExp = null; + + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + public String getSuccessConditionExp() { + return successConditionExp; + } + + public void setSuccessConditionExp(final String finishConditionExp) { + successConditionExp = finishConditionExp; + } + + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + public String getSuccessActionExp() { + return successActionExp; + } + + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + public String getErrorConditionExp() { + return errorConditionExp; + } + + public void setErrorConditionExp(final String errorConditionExp) { + this.errorConditionExp = errorConditionExp; + } + + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + public String getErrorActionExp() { + return errorActionExp; + } + + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + } + + /** + * Builder to build easily the {@link RolloutGroupConditions}. + * + */ + public static class RolloutGroupConditionBuilder { + private final RolloutGroupConditions conditions = new RolloutGroupConditions(); + + public RolloutGroupConditions build() { + return conditions; + } + + /** + * Sets the finish condition and expression on the builder. + * + * @param condition + * the finish condition + * @param expression + * the finish expression + * @return the builder itself + */ + public RolloutGroupConditionBuilder successCondition(final RolloutGroupSuccessCondition condition, + final String expression) { + conditions.setSuccessCondition(condition); + conditions.setSuccessConditionExp(expression); + return this; + } + + /** + * Sets the success action and expression on the builder. + * + * @param action + * the success action + * @param expression + * the error expression + * @return the builder itself + */ + public RolloutGroupConditionBuilder successAction(final RolloutGroupSuccessAction action, + final String expression) { + conditions.setSuccessAction(action); + conditions.setSuccessActionExp(expression); + return this; + } + + /** + * Sets the error condition and expression on the builder. + * + * @param condition + * the error condition + * @param expression + * the error expression + * @return the builder itself + */ + public RolloutGroupConditionBuilder errorCondition(final RolloutGroupErrorCondition condition, + final String expression) { + conditions.setErrorCondition(condition); + conditions.setErrorConditionExp(expression); + return this; + } + + /** + * Sets the error action and expression on the builder. + * + * @param action + * the error action + * @param expression + * the error expression + * @return the builder itself + */ + public RolloutGroupConditionBuilder errorAction(final RolloutGroupErrorAction action, final String expression) { + conditions.setErrorAction(action); + conditions.setErrorActionExp(expression); + return this; + } + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java new file mode 100644 index 000000000..306b6980b --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java @@ -0,0 +1,266 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.Artifact; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.ExternalArtifact; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.persistence.annotations.CascadeOnDelete; + +/** + * Base Software Module that is supported by OS level provisioning mechanism on + * the edge controller, e.g. OS, JVM, AgentHub. + * + */ +@Entity +@Table(name = "sp_base_software_module", uniqueConstraints = @UniqueConstraint(columnNames = { "module_type", "name", + "version", "tenant" }, name = "uk_base_sw_mod"), indexes = { + @Index(name = "sp_idx_base_sw_module_01", columnList = "tenant,deleted,name,version"), + @Index(name = "sp_idx_base_sw_module_02", columnList = "tenant,deleted,module_type"), + @Index(name = "sp_idx_base_sw_module_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "SoftwareModule.artifacts", attributeNodes = { @NamedAttributeNode("artifacts") }) +public class JpaSoftwareModule extends JpaNamedVersionedEntity implements SoftwareModule { + private static final long serialVersionUID = 1L; + + @ManyToOne + @JoinColumn(name = "module_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_module_type")) + private JpaSoftwareModuleType type; + + @ManyToMany(mappedBy = "modules", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY) + private final List assignedTo = new ArrayList<>(); + + @Column(name = "deleted") + private boolean deleted = false; + + @Column(name = "vendor", nullable = true, length = 256) + private String vendor; + + @OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaLocalArtifact.class) + private List artifacts; + + @OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaExternalArtifact.class) + private List externalArtifacts; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaSoftwareModuleMetadata.class) + @JoinColumn(name = "sw_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + /** + * Default constructor. + */ + public JpaSoftwareModule() { + super(); + } + + /** + * parameterized constructor. + * + * @param type + * of the {@link SoftwareModule} + * @param name + * abstract name of the {@link SoftwareModule} + * @param version + * of the {@link SoftwareModule} + * @param description + * of the {@link SoftwareModule} + * @param vendor + * of the {@link SoftwareModule} + */ + public JpaSoftwareModule(final SoftwareModuleType type, final String name, final String version, + final String description, final String vendor) { + super(name, version, description); + this.vendor = vendor; + this.type = (JpaSoftwareModuleType) type; + } + + /** + * @param artifact + * is added to the assigned {@link Artifact}s. + */ + @Override + public void addArtifact(final LocalArtifact artifact) { + if (null == artifacts) { + artifacts = new ArrayList<>(4); + } + + if (!artifacts.contains(artifact)) { + artifacts.add(artifact); + } + } + + /** + * @param artifact + * is added to the assigned {@link Artifact}s. + */ + @Override + public void addArtifact(final ExternalArtifact artifact) { + if (null == externalArtifacts) { + externalArtifacts = new ArrayList<>(4); + } + + if (!externalArtifacts.contains(artifact)) { + externalArtifacts.add(artifact); + } + + } + + /** + * @param artifactId + * to look for + * @return found {@link Artifact} + */ + @Override + public Optional getLocalArtifact(final Long artifactId) { + if (null == artifacts) { + return Optional.empty(); + } + + return artifacts.stream().filter(artifact -> artifact.getId().equals(artifactId)).findFirst(); + } + + /** + * @param fileName + * to look for + * @return found {@link Artifact} + */ + @Override + public Optional getLocalArtifactByFilename(final String fileName) { + if (null == artifacts) { + return Optional.empty(); + } + + return artifacts.stream().filter(artifact -> artifact.getFilename().equalsIgnoreCase(fileName.trim())) + .findFirst(); + } + + /** + * @return the artifacts + */ + @Override + public List getArtifacts() { + final List result = new ArrayList<>(); + result.addAll(artifacts); + result.addAll(externalArtifacts); + + return result; + } + + /** + * @return local artifacts only + */ + @Override + public List getLocalArtifacts() { + if (artifacts == null) { + return Collections.emptyList(); + } + + return artifacts; + } + + @Override + public String getVendor() { + return vendor; + } + + /** + * @param artifact + * is removed from the assigned {@link LocalArtifact}s. + */ + @Override + public void removeArtifact(final LocalArtifact artifact) { + if (null != artifacts) { + artifacts.remove(artifact); + } + } + + /** + * @param artifact + * is removed from the assigned {@link ExternalArtifact}s. + */ + @Override + public void removeArtifact(final ExternalArtifact artifact) { + if (null != externalArtifacts) { + externalArtifacts.remove(artifact); + } + } + + @Override + public void setVendor(final String vendor) { + this.vendor = vendor; + } + + @Override + public SoftwareModuleType getType() { + return type; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public void setDeleted(final boolean deleted) { + this.deleted = deleted; + } + + @Override + public void setType(final SoftwareModuleType type) { + this.type = (JpaSoftwareModuleType) type; + } + + /** + * @return immutable list of meta data elements. + */ + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + @Override + public String toString() { + return "SoftwareModule [deleted=" + deleted + ", name=" + getName() + ", version=" + getVersion() + + ", revision=" + getOptLockRevision() + ", Id=" + getId() + ", type=" + getType().getName() + "]"; + } + + /** + * @return the assignedTo + */ + @Override + public List getAssignedTo() { + return assignedTo; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleMetadata.java new file mode 100644 index 000000000..aba08f0ed --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleMetadata.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; + +/** + * Metadata for {@link SoftwareModule}. + * + */ +@IdClass(SwMetadataCompositeKey.class) +@Entity +@Table(name = "sp_sw_metadata") +public class JpaSoftwareModuleMetadata extends JpaMetaData implements SoftwareModuleMetadata { + private static final long serialVersionUID = 1L; + + @Id + @ManyToOne(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinColumn(name = "sw_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_sw")) + private SoftwareModule softwareModule; + + public JpaSoftwareModuleMetadata() { + // default public constructor for JPA + } + + public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) { + super(key, value); + this.softwareModule = softwareModule; + } + + public SwMetadataCompositeKey getId() { + return new SwMetadataCompositeKey(softwareModule, getKey()); + } + + @Override + public SoftwareModule getSoftwareModule() { + return softwareModule; + } + + @Override + public void setSoftwareModule(final SoftwareModule softwareModule) { + this.softwareModule = softwareModule; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((softwareModule == null) ? 0 : softwareModule.hashCode()); + return result; + } + + @Override + 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; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleType.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleType.java new file mode 100644 index 000000000..9948a7cde --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModuleType.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Index; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; + +/** + * Type of a software modules. + * + */ +@Entity +@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_prim", columnList = "tenant,id") }, uniqueConstraints = { + @UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_smt_type_key"), + @UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_smt_name") }) +public class JpaSoftwareModuleType extends JpaNamedEntity implements SoftwareModuleType { + private static final long serialVersionUID = 1L; + + @Column(name = "type_key", nullable = false, length = 64) + private String key; + + @Column(name = "max_ds_assignments", nullable = false) + private int maxAssignments; + + @Column(name = "colour", nullable = true, length = 16) + private String colour; + + @Column(name = "deleted") + private boolean deleted = false; + + /** + * 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); + } + + /** + * 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(); + this.key = key; + this.maxAssignments = maxAssignments; + setDescription(description); + setName(name); + this.colour = colour; + } + + /** + * Default Constructor. + */ + public JpaSoftwareModuleType() { + super(); + } + + @Override + public String getKey() { + return key; + } + + @Override + public int getMaxAssignments() { + return maxAssignments; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public void setDeleted(final boolean deleted) { + this.deleted = deleted; + } + + @Override + public String getColour() { + return colour; + } + + @Override + public void setColour(final String colour) { + this.colour = colour; + } + + @Override + public String toString() { + return "SoftwareModuleType [key=" + key + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTag.java new file mode 100644 index 000000000..ee4da0824 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTag.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; + +import org.eclipse.hawkbit.repository.model.Tag; + +/** + * A Tag can be used as describing and organizational meta information for any + * kind of entity. + * + */ +@MappedSuperclass +public abstract class JpaTag extends JpaNamedEntity implements Tag { + private static final long serialVersionUID = 1L; + + @Column(name = "colour", nullable = true, length = 16) + private String colour; + + protected JpaTag() { + super(); + } + + /** + * 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) { + super(name, description); + this.colour = colour; + } + + @Override + public String getColour() { + return colour; + } + + @Override + public void setColour(final String colour) { + this.colour = colour; + } + + @Override + public String toString() { + return "Tag [getOptLockRevision()=" + getOptLockRevision() + ", getId()=" + getId() + "]"; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java new file mode 100644 index 000000000..08a66a9b3 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetIdName; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.repository.model.helper.SecurityChecker; +import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.springframework.data.domain.Persistable; + +/** + *

+ * The {@link Target} is the target of all provisioning operations. It contains + * the currently installed {@link DistributionSet} (i.e. current state). In + * addition it holds the target {@link DistributionSet} that has to be + * provisioned next (i.e. target state). + *

+ * + *

+ * {@link #getStatus()}s() shows if the {@link Target} is + * {@link TargetStatus#IN_SYNC} or a provisioning is + * {@link TargetStatus#PENDING} or the target is only + * {@link TargetStatus#REGISTERED}, i.e. a target {@link DistributionSet} . + *

+ * + */ +@Entity +@Table(name = "sp_target", indexes = { + @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), + @Index(name = "sp_idx_target_02", columnList = "tenant,name"), + @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), + @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), + @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) +@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), + @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) +public class JpaTarget extends JpaNamedEntity implements Persistable, Target { + private static final long serialVersionUID = 1L; + + @Column(name = "controller_id", length = 64) + @Size(min = 1) + @NotNull + private String controllerId; + + @Transient + private boolean entityNew = false; + + @ManyToMany(targetEntity = JpaTargetTag.class) + @JoinTable(name = "sp_target_target_tag", joinColumns = { + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) + private Set tags = new HashSet<>(); + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { + CascadeType.REMOVE }, targetEntity = JpaAction.class) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) + private final List actions = new ArrayList<>(); + + @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) + private JpaDistributionSet assignedDistributionSet; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) + @PrimaryKeyJoinColumn + private JpaTargetInfo targetInfo = null; + + /** + * the security token of the target which allows if enabled to authenticate + * with this security token. + */ + @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) + private String securityToken = null; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + @JoinColumn(name = "target_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + */ + public JpaTarget(final String controllerId) { + this.controllerId = controllerId; + setName(controllerId); + securityToken = SecurityTokenGeneratorHolder.getInstance().generateToken(); + targetInfo = new JpaTargetInfo(this); + } + + /** + * empty constructor for JPA. + */ + JpaTarget() { + controllerId = null; + securityToken = null; + } + + @Override + public DistributionSet getAssignedDistributionSet() { + return assignedDistributionSet; + } + + @Override + public String getControllerId() { + return controllerId; + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { + this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; + } + + @Override + public void setControllerId(final String controllerId) { + this.controllerId = controllerId; + } + + @Override + public void setTags(final Set tags) { + this.tags = tags; + } + + @Override + public List getActions() { + return actions; + } + + @Override + public TargetIdName getTargetIdName() { + return new TargetIdName(getId(), getControllerId(), getName()); + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the targetInfo + */ + @Override + public TargetInfo getTargetInfo() { + return targetInfo; + } + + /** + * @param targetInfo + * the targetInfo to set + */ + @Override + public void setTargetInfo(final TargetInfo targetInfo) { + this.targetInfo = (JpaTargetInfo) targetInfo; + } + + /** + * @return the securityToken + */ + @Override + public String getSecurityToken() { + if (SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + return securityToken; + } + return null; + } + + /** + * @param securityToken + * the securityToken to set + */ + @Override + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + + @Override + public String toString() { + return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetFilterQuery.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetFilterQuery.java new file mode 100644 index 000000000..1ad1b69b8 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetFilterQuery.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Index; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.TargetFilterQuery; + +/** + * Stored target filter. + * + */ +@Entity +@Table(name = "sp_target_filter_query", indexes = { + @Index(name = "sp_idx_target_filter_query_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_tenant_custom_filter_name")) +public class JpaTargetFilterQuery extends JpaTenantAwareBaseEntity implements TargetFilterQuery { + private static final long serialVersionUID = 7493966984413479089L; + + @Column(name = "name", length = 64) + private String name; + + @Column(name = "query", length = 1024) + private String query; + + public JpaTargetFilterQuery() { + // Default constructor for JPA. + } + + public JpaTargetFilterQuery(final String name, final String query) { + this.name = name; + this.query = query; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override + public String getQuery() { + return query; + } + + @Override + public void setQuery(final String query) { + this.query = query; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java new file mode 100644 index 000000000..7b7b3e2e4 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -0,0 +1,372 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Persistable; + +/** + * A table which contains all the information inserted, updated by the + * controller itself. So this entity does not provide audit information because + * changes on this entity are mostly only done by controller requests. That's + * the reason that we store these information in a separated table so we don't + * modifying the {@link Target} itself when a controller reports it's + * {@link #lastTargetQuery} for example. + * + */ +@Table(name = "sp_target_info", indexes = { + @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) +@Entity +public class JpaTargetInfo implements Persistable, TargetInfo { + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); + + @Id + private Long targetId; + + @Transient + private boolean entityNew = false; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.MERGE, + CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) + @MapsId + private JpaTarget target; + + @Column(name = "address", length = 512) + private String address = null; + + @Column(name = "last_target_query") + private Long lastTargetQuery = null; + + @Column(name = "install_date") + private Long installationDate; + + @Column(name = "update_status", nullable = false, length = 255) + @Enumerated(EnumType.STRING) + private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; + + @ManyToOne(optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) + private JpaDistributionSet installedDistributionSet; + + /** + * Read only on management API. Are commited by controller. + */ + @ElementCollection + @Column(name = "attribute_value", length = 128) + @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) + @CollectionTable(name = "sp_target_attributes", joinColumns = { + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) + + private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); + + // set default request controller attributes to true, because we want to + // request them the first + // time + @Column(name = "request_controller_attributes", nullable = false) + private boolean requestControllerAttributes = true; + + /** + * Constructor for {@link TargetStatus}. + * + * @param target + * related to this status. + */ + public JpaTargetInfo(final JpaTarget target) { + this.target = target; + targetId = target.getId(); + } + + JpaTargetInfo() { + target = null; + targetId = null; + } + + @Override + public Long getId() { + return targetId; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the ipAddress + */ + @Override + public URI getAddress() { + if (address == null) { + return null; + } + try { + return URI.create(address); + } catch (final IllegalArgumentException e) { + LOG.warn("Invalid address provided. Cloud not be configured to URI", e); + return null; + } + } + + /** + * @param address + * the ipAddress to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + public void setAddress(final String address) { + // check if this is a real URI + if (address != null) { + URI.create(address); + } + + this.address = address; + } + + public Long getTargetId() { + return targetId; + } + + public void setTargetId(final Long targetId) { + this.targetId = targetId; + } + + @Override + public Target getTarget() { + return target; + } + + public void setTarget(final JpaTarget target) { + this.target = target; + } + + @Override + public Long getLastTargetQuery() { + return lastTargetQuery; + } + + public void setLastTargetQuery(final Long lastTargetQuery) { + this.lastTargetQuery = lastTargetQuery; + } + + public void setRequestControllerAttributes(final boolean requestControllerAttributes) { + this.requestControllerAttributes = requestControllerAttributes; + } + + @Override + public Map getControllerAttributes() { + return controllerAttributes; + } + + public boolean isRequestControllerAttributes() { + return requestControllerAttributes; + } + + @Override + public Long getInstallationDate() { + return installationDate; + } + + public void setInstallationDate(final Long installationDate) { + this.installationDate = installationDate; + } + + @Override + public TargetUpdateStatus getUpdateStatus() { + return updateStatus; + } + + public void setUpdateStatus(final TargetUpdateStatus updateStatus) { + this.updateStatus = updateStatus; + } + + @Override + public DistributionSet getInstalledDistributionSet() { + return installedDistributionSet; + } + + public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { + this.installedDistributionSet = installedDistributionSet; + } + + /** + * @return the poll time which holds the last poll time of the target, the + * next poll time and the overdue time. In case the + * {@link #lastTargetQuery} is not set e.g. the target never polled + * before this method returns {@code null} + */ + @Override + public PollStatus getPollStatus() { + if (lastTargetQuery == null) { + return null; + } + return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { + final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder + .getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = DurationHelper.formattedStringToDuration( + TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + }); + } + + /** + * The poll time object which holds all the necessary information around the + * target poll time, e.g. the last poll time, the next poll time and the + * overdue poll time. + * + */ + public static final class PollStatus { + private final LocalDateTime lastPollDate; + private final LocalDateTime nextPollDate; + private final LocalDateTime overdueDate; + private final LocalDateTime currentDate; + + private PollStatus(final LocalDateTime lastPollDate, final LocalDateTime nextPollDate, + final LocalDateTime overdueDate, final LocalDateTime currentDate) { + this.lastPollDate = lastPollDate; + this.nextPollDate = nextPollDate; + this.overdueDate = overdueDate; + this.currentDate = currentDate; + } + + /** + * calculates if the target poll time is overdue and the target has not + * been polled in the configured poll time interval. + * + * @return {@code true} if the current time is after the poll time + * overdue date otherwise {@code false}. + */ + public boolean isOverdue() { + return currentDate.isAfter(overdueDate); + } + + /** + * @return the lastPollDate + */ + public LocalDateTime getLastPollDate() { + return lastPollDate; + } + + public LocalDateTime getNextPollDate() { + return nextPollDate; + } + + public LocalDateTime getOverdueDate() { + return overdueDate; + } + + public LocalDateTime getCurrentDate() { + return currentDate; + } + + @Override + public String toString() { + return "PollTime [lastPollDate=" + lastPollDate + ", nextPollDate=" + nextPollDate + ", overdueDate=" + + overdueDate + ", currentDate=" + currentDate + "]"; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TargetInfo)) { + return false; + } + final JpaTargetInfo other = (JpaTargetInfo) obj; + if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + if (targetId == null) { + if (other.targetId != null) { + return false; + } + } else if (!targetId.equals(other.targetId)) { + return false; + } + return true; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetTag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetTag.java new file mode 100644 index 000000000..0d8f3a5d1 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetTag.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Index; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetTag; + +/** + * A {@link TargetTag} is used to describe Target attributes and use them also + * for filtering the target list. + * + */ +@Entity +@Table(name = "sp_target_tag", indexes = { + @Index(name = "sp_idx_target_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_targ_tag")) +public class JpaTargetTag extends JpaTag implements TargetTag { + private static final long serialVersionUID = 1L; + + @ManyToMany(mappedBy = "tags", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + /** + * Constructor. + * + * @param name + * of {@link TargetTag} + * @param description + * of {@link TargetTag} + * @param colour + * of {@link TargetTag} + */ + public JpaTargetTag(final String name, final String description, final String colour) { + super(name, description, colour); + } + + /** + * Public constructor. + * + * @param name + * of the {@link TargetTag} + **/ + public JpaTargetTag(final String name) { + super(name, null, null); + } + + public JpaTargetTag() { + super(); + } + + @Override + public List getAssignedToTargets() { + return assignedToTargets; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof TargetTag)) { + return false; + } + + return true; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantAwareBaseEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantAwareBaseEntity.java new file mode 100644 index 000000000..e921e6915 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantAwareBaseEntity.java @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; +import javax.persistence.PrePersist; + +import org.eclipse.hawkbit.repository.exception.TenantNotExistException; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder; +import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder; +import org.eclipse.persistence.annotations.Multitenant; +import org.eclipse.persistence.annotations.MultitenantType; +import org.eclipse.persistence.annotations.TenantDiscriminatorColumn; + +/** + * Holder of the base attributes common to all tenant aware entities. + * + */ +@MappedSuperclass +@TenantDiscriminatorColumn(name = "tenant", length = 40) +@Multitenant(MultitenantType.SINGLE_TABLE) +public abstract class JpaTenantAwareBaseEntity extends JpaBaseEntity implements TenantAwareBaseEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40) + private String tenant; + + /** + * Default constructor needed for JPA entities. + */ + public JpaTenantAwareBaseEntity() { + // Default constructor needed for JPA entities. + } + + /** + * PrePersist listener method for all {@link TenantAwareBaseEntity} + * entities. + */ + @PrePersist + public void prePersist() { + // before persisting the entity check the current ID of the tenant by + // using the TenantAware + // service + final String currentTenant = SystemManagementHolder.getInstance().currentTenant(); + if (currentTenant == null) { + throw new TenantNotExistException("Tenant " + + TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant() + + " does not exists, cannot create entity " + this.getClass() + " with id " + super.getId()); + } + setTenant(currentTenant.toUpperCase()); + } + + @Override + public String getTenant() { + return tenant; + } + + public void setTenant(final String tenant) { + this.tenant = tenant; + } + + @Override + public String toString() { + return "BaseEntity [id=" + super.getId() + "]"; + } + + /** + * Tenant aware entities extend the equals/hashcode strategy with the tenant + * name. That would allow for instance in a multi-schema based data + * separation setup to have the same primary key for different entities of + * different tenants. + * + * @see org.eclipse.hawkbit.repository.model.BaseEntity#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (tenant == null ? 0 : tenant.hashCode()); + return result; + } + + /** + * Tenant aware entities extend the equals/hashcode strategy with the tenant + * name. That would allow for instance in a multi-schema based data + * separation setup to have the same primary key for different entities of + * different tenants. + * + * @see org.eclipse.hawkbit.repository.model.BaseEntity#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (!super.equals(obj)) { + return false; + } + final JpaTenantAwareBaseEntity other = (JpaTenantAwareBaseEntity) obj; + if (tenant == null) { + if (other.tenant != null) { + return false; + } + } else if (!tenant.equals(other.tenant)) { + return false; + } + return true; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantConfiguration.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantConfiguration.java new file mode 100644 index 000000000..2d1342b74 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantConfiguration.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.TenantConfiguration; + +/** + * A JPA entity which stores the tenant specific configuration. + * + */ +@Entity +@Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key", + "tenant" }, name = "uk_tenant_key")) +public class JpaTenantConfiguration extends JpaTenantAwareBaseEntity implements TenantConfiguration { + private static final long serialVersionUID = 1L; + + @Column(name = "conf_key", length = 128) + private String key; + + @Column(name = "conf_value", length = 512) + @Basic + 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) { + this.key = key; + this.value = value; + + } + + @Override + public String getKey() { + return key; + } + + @Override + public void setKey(final String key) { + this.key = key; + } + + @Override + public String getValue() { + return value; + } + + @Override + public void setValue(final String value) { + this.value = value; + } + +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantMetaData.java new file mode 100644 index 000000000..7cb31b3c4 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTenantMetaData.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.hawkbit.repository.model.TenantMetaData; + +/** + * Tenant entity with meta data that is configured globally for the entire + * tenant. This entity is not tenant aware to allow the system to access it + * through the {@link EntityManager} even before the actual tenant exists. + * + * Entities owned by the tenant are based on {@link TenantAwareBaseEntity}. + * + */ +@Table(name = "sp_tenant", indexes = { + @Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = { + @UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") }) +@Entity +public class JpaTenantMetaData extends JpaBaseEntity implements TenantMetaData { + private static final long serialVersionUID = 1L; + + @Column(name = "tenant", nullable = false, length = 40) + private String tenant; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type")) + 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) { + super(); + this.defaultDsType = (JpaDistributionSetType) defaultDsType; + this.tenant = tenant; + } + + @Override + public DistributionSetType getDefaultDsType() { + return defaultDsType; + } + + @Override + public void setDefaultDsType(final DistributionSetType defaultDsType) { + this.defaultDsType = (JpaDistributionSetType) defaultDsType; + } + + @Override + public String getTenant() { + return tenant; + } + + public void setTenant(final String tenant) { + this.tenant = tenant; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + this.getClass().getName().hashCode(); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof TenantMetaData)) { + return false; + } + + return true; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroup.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroup.java similarity index 77% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroup.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroup.java index 7a46b15b1..0bb969c7f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroup.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroup.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; import java.util.List; @@ -24,6 +24,9 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.persistence.annotations.ExistenceChecking; import org.eclipse.persistence.annotations.ExistenceType; @@ -41,16 +44,16 @@ public class RolloutTargetGroup implements Serializable { private static final long serialVersionUID = 1L; @Id - @ManyToOne(targetEntity = RolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) - @JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group") ) + @ManyToOne(targetEntity = JpaRolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) + @JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group")) private RolloutGroup rolloutGroup; @Id - @ManyToOne(targetEntity = Target.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) - @JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target") ) - private Target target; + @ManyToOne(targetEntity = JpaTarget.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) + @JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target")) + private JpaTarget target; - @OneToMany(targetEntity = Action.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) + @OneToMany(targetEntity = JpaAction.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) @JoinColumns(value = { @JoinColumn(name = "rolloutgroup", referencedColumnName = "rolloutGroup_Id"), @JoinColumn(name = "target", referencedColumnName = "target_id") }) private List actions; @@ -64,7 +67,7 @@ public class RolloutTargetGroup implements Serializable { public RolloutTargetGroup(final RolloutGroup rolloutGroup, final Target target) { this.rolloutGroup = rolloutGroup; - this.target = target; + this.target = (JpaTarget) target; } public RolloutTargetGroupId getId() { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroupId.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroupId.java similarity index 88% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroupId.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroupId.java index 88226142a..cc1c9cbe7 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutTargetGroupId.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/RolloutTargetGroupId.java @@ -6,10 +6,13 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; + /** * Combined unique key of the table {@link RolloutTargetGroup}. * diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SwMetadataCompositeKey.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/SwMetadataCompositeKey.java similarity index 96% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SwMetadataCompositeKey.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/SwMetadataCompositeKey.java index 90b3779a1..e9c63b511 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SwMetadataCompositeKey.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/model/SwMetadataCompositeKey.java @@ -6,10 +6,12 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.repository.jpa.model; import java.io.Serializable; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + /** * The Software Module meta data composite key which contains the meta data key * and the ID of the software module itself. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/ActionSpecifications.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/ActionSpecifications.java similarity index 55% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/ActionSpecifications.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/ActionSpecifications.java index 62e7167f1..54d529d6c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/ActionSpecifications.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/ActionSpecifications.java @@ -6,20 +6,22 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; import javax.persistence.criteria.Join; import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.SetJoin; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Action_; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSet_; import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.repository.model.LocalArtifact_; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModule_; import org.eclipse.hawkbit.repository.model.Target; import org.springframework.data.jpa.domain.Specification; @@ -28,7 +30,7 @@ import org.springframework.data.jpa.domain.Specification; * Spring Data JPQL Specifications. * */ -public class ActionSpecifications { +public final class ActionSpecifications { private ActionSpecifications() { // utility class @@ -47,15 +49,16 @@ public class ActionSpecifications { * assigned * @return a specification to use with spring JPA */ - public static Specification hasTargetAssignedArtifact(final Target target, + public static Specification hasTargetAssignedArtifact(final Target target, final LocalArtifact localArtifact) { return (actionRoot, query, criteriaBuilder) -> { - final Join dsJoin = actionRoot.join(Action_.distributionSet); - final SetJoin modulesJoin = dsJoin.join(DistributionSet_.modules); - final ListJoin artifactsJoin = modulesJoin.join(SoftwareModule_.artifacts); + final Join dsJoin = actionRoot.join(JpaAction_.distributionSet); + final SetJoin modulesJoin = dsJoin.join(JpaDistributionSet_.modules); + final ListJoin artifactsJoin = modulesJoin + .join(JpaSoftwareModule_.artifacts); return criteriaBuilder.and( - criteriaBuilder.equal(artifactsJoin.get(LocalArtifact_.filename), localArtifact.getFilename()), - criteriaBuilder.equal(actionRoot.get(Action_.target), target)); + criteriaBuilder.equal(artifactsJoin.get(JpaLocalArtifact_.filename), localArtifact.getFilename()), + criteriaBuilder.equal(actionRoot.get(JpaAction_.target), target)); }; } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetSpecification.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetSpecification.java similarity index 58% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetSpecification.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetSpecification.java index b95f0b8e7..4ee849bcc 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetSpecification.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetSpecification.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; import java.util.Collection; @@ -18,15 +18,17 @@ import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.SetJoin; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag_; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTag_; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.DistributionSet_; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetInfo_; -import org.eclipse.hawkbit.repository.model.Target_; import org.springframework.data.jpa.domain.Specification; /** @@ -48,8 +50,8 @@ public final class DistributionSetSpecification { * attribute is ignored * @return the {@link DistributionSet} {@link Specification} */ - public static Specification isDeleted(final Boolean isDeleted) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSet_.deleted), isDeleted); + public static Specification isDeleted(final Boolean isDeleted) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSet_.deleted), isDeleted); } @@ -62,8 +64,8 @@ public final class DistributionSetSpecification { * the attribute is ignored * @return the {@link DistributionSet} {@link Specification} */ - public static Specification isCompleted(final Boolean isCompleted) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSet_.complete), isCompleted); + public static Specification isCompleted(final Boolean isCompleted) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSet_.complete), isCompleted); } @@ -75,12 +77,12 @@ public final class DistributionSetSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byId(final Long distid) { + public static Specification byId(final Long distid) { return (targetRoot, query, cb) -> { - final Predicate predicate = cb.equal(targetRoot. get(DistributionSet_.id), distid); - targetRoot.fetch(DistributionSet_.modules, JoinType.LEFT); - targetRoot.fetch(DistributionSet_.tags, JoinType.LEFT); - targetRoot.fetch(DistributionSet_.type, JoinType.LEFT); + final Predicate predicate = cb.equal(targetRoot. get(JpaDistributionSet_.id), distid); + targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT); + targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT); + targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT); query.distinct(true); return predicate; @@ -95,12 +97,12 @@ public final class DistributionSetSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byIds(final Collection distids) { + public static Specification byIds(final Collection distids) { return (targetRoot, query, cb) -> { - final Predicate predicate = targetRoot. get(DistributionSet_.id).in(distids); - targetRoot.fetch(DistributionSet_.modules, JoinType.LEFT); - targetRoot.fetch(DistributionSet_.tags, JoinType.LEFT); - targetRoot.fetch(DistributionSet_.type, JoinType.LEFT); + final Predicate predicate = targetRoot. get(JpaDistributionSet_.id).in(distids); + targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT); + targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT); + targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT); query.distinct(true); return predicate; }; @@ -114,11 +116,11 @@ public final class DistributionSetSpecification { * to be filtered on * @return the {@link DistributionSet} {@link Specification} */ - public static Specification likeNameOrDescriptionOrVersion(final String subString) { + public static Specification likeNameOrDescriptionOrVersion(final String subString) { return (targetRoot, query, cb) -> cb.or( - cb.like(cb.lower(targetRoot. get(DistributionSet_.name)), subString.toLowerCase()), - cb.like(cb.lower(targetRoot. get(DistributionSet_.version)), subString.toLowerCase()), - cb.like(cb.lower(targetRoot. get(DistributionSet_.description)), subString.toLowerCase())); + cb.like(cb.lower(targetRoot. get(JpaDistributionSet_.name)), subString.toLowerCase()), + cb.like(cb.lower(targetRoot. get(JpaDistributionSet_.version)), subString.toLowerCase()), + cb.like(cb.lower(targetRoot. get(JpaDistributionSet_.description)), subString.toLowerCase())); } /** @@ -131,10 +133,10 @@ public final class DistributionSetSpecification { * flag to select distribution sets with no tag * @return the {@link DistributionSet} {@link Specification} */ - public static Specification hasTags(final Collection tagNames, + public static Specification hasTags(final Collection tagNames, final Boolean selectDSWithNoTag) { return (targetRoot, query, cb) -> { - final SetJoin tags = targetRoot.join(DistributionSet_.tags, + final SetJoin tags = targetRoot.join(JpaDistributionSet_.tags, JoinType.LEFT); final Predicate predicate = getPredicate(tags, tagNames, selectDSWithNoTag, cb); query.distinct(true); @@ -142,10 +144,10 @@ public final class DistributionSetSpecification { }; } - private static Predicate getPredicate(final SetJoin tags, + private static Predicate getPredicate(final SetJoin tags, final Collection tagNames, final Boolean selectDSWithNoTag, final CriteriaBuilder cb) { - tags.get(DistributionSetTag_.name); - final Path exp = tags.get(DistributionSetTag_.name); + tags.get(JpaDistributionSetTag_.name); + final Path exp = tags.get(JpaDistributionSetTag_.name); if (selectDSWithNoTag != null && selectDSWithNoTag) { if (tagNames != null) { return cb.or(exp.isNull(), exp.in(tagNames)); @@ -167,11 +169,11 @@ public final class DistributionSetSpecification { * to be filtered on * @return the {@link Specification} */ - public static Specification equalsNameAndVersionIgnoreCase(final String name, + public static Specification equalsNameAndVersionIgnoreCase(final String name, final String version) { return (targetRoot, query, cb) -> cb.and( - cb.equal(cb.lower(targetRoot. get(DistributionSet_.name)), name.toLowerCase()), - cb.equal(cb.lower(targetRoot. get(DistributionSet_.version)), version.toLowerCase())); + cb.equal(cb.lower(targetRoot. get(JpaDistributionSet_.name)), name.toLowerCase()), + cb.equal(cb.lower(targetRoot. get(JpaDistributionSet_.version)), version.toLowerCase())); } @@ -183,8 +185,9 @@ public final class DistributionSetSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byType(final DistributionSetType type) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSet_.type), type); + public static Specification byType(final DistributionSetType type) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSet_.type), + type); } @@ -195,12 +198,12 @@ public final class DistributionSetSpecification { * @return the specification to search for a distribution set which is * installed to the given targetId */ - public static Specification installedTarget(final String installedTargetId) { + public static Specification installedTarget(final String installedTargetId) { return (dsRoot, query, cb) -> { - final ListJoin installedTargetJoin = dsRoot - .join(DistributionSet_.installedAtTargets, JoinType.INNER); - final Join targetJoin = installedTargetJoin.join(TargetInfo_.target); - return cb.equal(targetJoin.get(Target_.controllerId), installedTargetId); + final ListJoin installedTargetJoin = dsRoot + .join(JpaDistributionSet_.installedAtTargets, JoinType.INNER); + final Join targetJoin = installedTargetJoin.join(JpaTargetInfo_.target); + return cb.equal(targetJoin.get(JpaTarget_.controllerId), installedTargetId); }; } @@ -211,11 +214,11 @@ public final class DistributionSetSpecification { * @return the specification to search for a distribution set which is * assigned to the given targetId */ - public static Specification assignedTarget(final String assignedTargetId) { + public static Specification assignedTarget(final String assignedTargetId) { return (dsRoot, query, cb) -> { - final ListJoin assignedTargetJoin = dsRoot.join(DistributionSet_.assignedToTargets, - JoinType.INNER); - return cb.equal(assignedTargetJoin.get(Target_.controllerId), assignedTargetId); + final ListJoin assignedTargetJoin = dsRoot + .join(JpaDistributionSet_.assignedToTargets, JoinType.INNER); + return cb.equal(assignedTargetJoin.get(JpaTarget_.controllerId), assignedTargetId); }; } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetTypeSpecification.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetTypeSpecification.java similarity index 75% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetTypeSpecification.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetTypeSpecification.java index 13776deb0..0a8306faa 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/DistributionSetTypeSpecification.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/DistributionSetTypeSpecification.java @@ -6,11 +6,12 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType_; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.DistributionSetType_; import org.springframework.data.jpa.domain.Specification; /** @@ -31,8 +32,9 @@ public final class DistributionSetTypeSpecification { * attribute is ignored * @return the {@link DistributionSetType} {@link Specification} */ - public static Specification isDeleted(final Boolean isDeleted) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSetType_.deleted), isDeleted); + public static Specification isDeleted(final Boolean isDeleted) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSetType_.deleted), + isDeleted); } /** @@ -44,8 +46,8 @@ public final class DistributionSetTypeSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byId(final Long distid) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSetType_.id), distid); + public static Specification byId(final Long distid) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSetType_.id), distid); } /** @@ -57,8 +59,8 @@ public final class DistributionSetTypeSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byName(final String name) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSetType_.name), name); + public static Specification byName(final String name) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSetType_.name), name); } /** @@ -70,8 +72,8 @@ public final class DistributionSetTypeSpecification { * to search * @return the {@link DistributionSet} {@link Specification} */ - public static Specification byKey(final String key) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(DistributionSetType_.key), key); + public static Specification byKey(final String key) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaDistributionSetType_.key), key); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SoftwareModuleSpecification.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleSpecification.java similarity index 63% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SoftwareModuleSpecification.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleSpecification.java index 680f97778..feba50ac8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SoftwareModuleSpecification.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleSpecification.java @@ -6,13 +6,14 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; import javax.persistence.criteria.Predicate; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.SoftwareModule_; import org.springframework.data.jpa.domain.Specification; /** @@ -33,10 +34,10 @@ public final class SoftwareModuleSpecification { * to search for * @return the {@link SoftwareModule} {@link Specification} */ - public static Specification byId(final Long moduleId) { + public static Specification byId(final Long moduleId) { return (targetRoot, query, cb) -> { - final Predicate predicate = cb.equal(targetRoot. get(SoftwareModule_.id), moduleId); - targetRoot.fetch(SoftwareModule_.type); + final Predicate predicate = cb.equal(targetRoot. get(JpaSoftwareModule_.id), moduleId); + targetRoot.fetch(JpaSoftwareModule_.type); return predicate; }; } @@ -47,8 +48,8 @@ public final class SoftwareModuleSpecification { * * @return the {@link SoftwareModule} {@link Specification} */ - public static Specification isDeletedFalse() { - return (swRoot, query, cb) -> cb.equal(swRoot. get(SoftwareModule_.deleted), Boolean.FALSE); + public static Specification isDeletedFalse() { + return (swRoot, query, cb) -> cb.equal(swRoot. get(JpaSoftwareModule_.deleted), Boolean.FALSE); } /** @@ -59,10 +60,10 @@ public final class SoftwareModuleSpecification { * to be filtered on * @return the {@link SoftwareModule} {@link Specification} */ - public static Specification likeNameOrVersion(final String subString) { + public static Specification likeNameOrVersion(final String subString) { return (targetRoot, query, cb) -> cb.or( - cb.like(cb.lower(targetRoot. get(SoftwareModule_.name)), subString.toLowerCase()), - cb.like(cb.lower(targetRoot. get(SoftwareModule_.version)), subString.toLowerCase())); + cb.like(cb.lower(targetRoot. get(JpaSoftwareModule_.name)), subString.toLowerCase()), + cb.like(cb.lower(targetRoot. get(JpaSoftwareModule_.version)), subString.toLowerCase())); } /** @@ -73,8 +74,9 @@ public final class SoftwareModuleSpecification { * to be filtered on * @return the {@link SoftwareModule} {@link Specification} */ - public static Specification equalType(final SoftwareModuleType type) { - return (targetRoot, query, cb) -> cb.equal(targetRoot. get(SoftwareModule_.type), type); + public static Specification equalType(final JpaSoftwareModuleType type) { + return (targetRoot, query, cb) -> cb.equal(targetRoot. get(JpaSoftwareModule_.type), + type); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SpecificationsBuilder.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SpecificationsBuilder.java similarity index 95% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SpecificationsBuilder.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SpecificationsBuilder.java index 83a4c6f8b..005942719 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/SpecificationsBuilder.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SpecificationsBuilder.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; import java.util.List; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetFilterQuerySpecification.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetFilterQuerySpecification.java similarity index 67% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetFilterQuerySpecification.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetFilterQuerySpecification.java index 0b600c849..cb3b775ac 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetFilterQuerySpecification.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetFilterQuerySpecification.java @@ -6,10 +6,11 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery_; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; -import org.eclipse.hawkbit.repository.model.TargetFilterQuery_; import org.springframework.data.jpa.domain.Specification; /** @@ -22,10 +23,10 @@ public class TargetFilterQuerySpecification { // utility class } - public static Specification likeName(final String searchText) { + public static Specification likeName(final String searchText) { return (targetFilterQueryRoot, query, cb) -> { final String searchTextToLower = searchText.toLowerCase(); - return cb.like(cb.lower(targetFilterQueryRoot.get(TargetFilterQuery_.name)), searchTextToLower); + return cb.like(cb.lower(targetFilterQueryRoot.get(JpaTargetFilterQuery_.name)), searchTextToLower); }; } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetSpecifications.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java similarity index 59% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetSpecifications.java rename to hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java index de894d3a3..6571f8668 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/specifications/TargetSpecifications.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/TargetSpecifications.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.repository.specifications; +package org.eclipse.hawkbit.repository.jpa.specifications; import java.util.Collection; import java.util.List; @@ -20,15 +20,19 @@ import javax.persistence.criteria.Root; import javax.persistence.criteria.SetJoin; import javax.validation.constraints.NotNull; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag_; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSet_; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetInfo_; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.repository.model.TargetTag_; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.model.Target_; import org.springframework.data.jpa.domain.Specification; /** @@ -50,10 +54,11 @@ public final class TargetSpecifications { * * @return the {@link Target} {@link Specification} */ - public static Specification byControllerIdWithStatusAndTagsInJoin(final Collection controllerIDs) { + public static Specification byControllerIdWithStatusAndTagsInJoin( + final Collection controllerIDs) { return (targetRoot, query, cb) -> { - final Predicate predicate = targetRoot.get(Target_.controllerId).in(controllerIDs); - targetRoot.fetch(Target_.tags, JoinType.LEFT); + final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs); + targetRoot.fetch(JpaTarget_.tags, JoinType.LEFT); query.distinct(true); return predicate; }; @@ -68,12 +73,12 @@ public final class TargetSpecifications { * * @return the {@link Target} {@link Specification} */ - public static Specification byControllerIdWithStatusAndAssignedInJoin( + public static Specification byControllerIdWithStatusAndAssignedInJoin( final Collection controllerIDs) { return (targetRoot, query, cb) -> { - final Predicate predicate = targetRoot.get(Target_.controllerId).in(controllerIDs); - targetRoot.fetch(Target_.assignedDistributionSet); + final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs); + targetRoot.fetch(JpaTarget_.assignedDistributionSet); return predicate; }; } @@ -89,19 +94,19 @@ public final class TargetSpecifications { * join it. * @return the {@link Target} {@link Specification} */ - public static Specification hasTargetUpdateStatus(final Collection updateStatus, + public static Specification hasTargetUpdateStatus(final Collection updateStatus, final boolean fetch) { return (targetRoot, query, cb) -> { if (!query.getResultType().isAssignableFrom(Long.class)) { if (fetch) { - targetRoot.fetch(Target_.targetInfo); + targetRoot.fetch(JpaTarget_.targetInfo); } else { - targetRoot.join(Target_.targetInfo); + targetRoot.join(JpaTarget_.targetInfo); } - return targetRoot.get(Target_.targetInfo).get(TargetInfo_.updateStatus).in(updateStatus); + return targetRoot.get(JpaTarget_.targetInfo).get(JpaTargetInfo_.updateStatus).in(updateStatus); } - final Join targetInfoJoin = targetRoot.join(Target_.targetInfo); - return targetInfoJoin.get(TargetInfo_.updateStatus).in(updateStatus); + final Join targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo); + return targetInfoJoin.get(JpaTargetInfo_.updateStatus).in(updateStatus); }; } @@ -113,11 +118,11 @@ public final class TargetSpecifications { * to be filtered on * @return the {@link Target} {@link Specification} */ - public static Specification likeNameOrDescriptionOrIp(final String searchText) { + public static Specification likeNameOrDescriptionOrIp(final String searchText) { return (targetRoot, query, cb) -> { final String searchTextToLower = searchText.toLowerCase(); - return cb.or(cb.like(cb.lower(targetRoot.get(Target_.name)), searchTextToLower), - cb.like(cb.lower(targetRoot.get(Target_.description)), searchTextToLower)); + return cb.or(cb.like(cb.lower(targetRoot.get(JpaTarget_.name)), searchTextToLower), + cb.like(cb.lower(targetRoot.get(JpaTarget_.description)), searchTextToLower)); }; } @@ -129,14 +134,14 @@ public final class TargetSpecifications { * to be filtered on * @return the {@link Target} {@link Specification} */ - public static Specification hasInstalledOrAssignedDistributionSet(@NotNull final Long distributionId) { + public static Specification hasInstalledOrAssignedDistributionSet(@NotNull final Long distributionId) { return (targetRoot, query, cb) -> { - final Join targetInfoJoin = targetRoot.join(Target_.targetInfo); + final Join targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo); return cb.or( - cb.equal(targetInfoJoin.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id), + cb.equal(targetInfoJoin.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id), distributionId), - cb.equal(targetRoot. get(Target_.assignedDistributionSet).get(DistributionSet_.id), - distributionId)); + cb.equal(targetRoot. get(JpaTarget_.assignedDistributionSet) + .get(JpaDistributionSet_.id), distributionId)); }; } @@ -150,13 +155,12 @@ public final class TargetSpecifications { * set that is not yet assigned * @return the {@link Target} {@link Specification} */ - public static Specification hasControllerIdAndAssignedDistributionSetIdNot(final List tIDs, + public static Specification hasControllerIdAndAssignedDistributionSetIdNot(final List tIDs, @NotNull final Long distributionId) { - return (targetRoot, query, cb) -> cb - .and(targetRoot.get(Target_.controllerId).in(tIDs), - cb.or(cb.notEqual(targetRoot. get(Target_.assignedDistributionSet) - .get(DistributionSet_.id), distributionId), - cb.isNull(targetRoot. get(Target_.assignedDistributionSet)))); + return (targetRoot, query, cb) -> cb.and(targetRoot.get(JpaTarget_.controllerId).in(tIDs), + cb.or(cb.notEqual(targetRoot. get(JpaTarget_.assignedDistributionSet) + .get(JpaDistributionSet_.id), distributionId), + cb.isNull(targetRoot. get(JpaTarget_.assignedDistributionSet)))); } /** @@ -169,7 +173,7 @@ public final class TargetSpecifications { * flag to get targets with no tag assigned * @return the {@link Target} {@link Specification} */ - public static Specification hasTags(final String[] tagNames, final Boolean selectTargetWithNoTag) { + public static Specification hasTags(final String[] tagNames, final Boolean selectTargetWithNoTag) { return (targetRoot, query, cb) -> { final Predicate predicate = getPredicate(targetRoot, cb, selectTargetWithNoTag, tagNames); query.distinct(true); @@ -177,10 +181,10 @@ public final class TargetSpecifications { }; } - private static Predicate getPredicate(final Root targetRoot, final CriteriaBuilder cb, + private static Predicate getPredicate(final Root targetRoot, final CriteriaBuilder cb, final Boolean selectTargetWithNoTag, final String[] tagNames) { - final SetJoin tags = targetRoot.join(Target_.tags, JoinType.LEFT); - final Path exp = tags.get(TargetTag_.name); + final SetJoin tags = targetRoot.join(JpaTarget_.tags, JoinType.LEFT); + final Path exp = tags.get(JpaTargetTag_.name); if (selectTargetWithNoTag) { if (tagNames != null) { return cb.or(exp.isNull(), exp.in(tagNames)); @@ -200,9 +204,9 @@ public final class TargetSpecifications { * the ID of the distribution set which must be assigned * @return the {@link Target} {@link Specification} */ - public static Specification hasAssignedDistributionSet(final Long distributionSetId) { + public static Specification hasAssignedDistributionSet(final Long distributionSetId) { return (targetRoot, query, cb) -> cb.equal( - targetRoot. get(Target_.assignedDistributionSet).get(DistributionSet_.id), + targetRoot. get(JpaTarget_.assignedDistributionSet).get(JpaDistributionSet_.id), distributionSetId); } @@ -214,10 +218,10 @@ public final class TargetSpecifications { * the ID of the distribution set which must be assigned * @return the {@link Target} {@link Specification} */ - public static Specification hasInstalledDistributionSet(final Long distributionSetId) { + public static Specification hasInstalledDistributionSet(final Long distributionSetId) { return (targetRoot, query, cb) -> { - final Join targetInfoJoin = targetRoot.join(Target_.targetInfo); - return cb.equal(targetInfoJoin.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id), + final Join targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo); + return cb.equal(targetInfoJoin.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id), distributionSetId); }; } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java index eedb36037..51b57bb17 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java @@ -10,193 +10,66 @@ package org.eclipse.hawkbit.repository.model; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.NamedEntityGraphs; -import javax.persistence.NamedSubgraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.eclipse.hawkbit.cache.CacheField; -import org.eclipse.hawkbit.cache.CacheKeys; -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - *

- * Applicable transition changes of the {@link SoftwareModule}s state of a - * {@link Target}, e.g. install, uninstall, update and preparations for the - * transition change, i.e. download. - *

- * - *

- * Actions are managed by the SP server and applied to the targets by the - * client. - *

- */ -@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), - @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), - @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) -@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), - @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), - @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) -@Entity -public class Action extends TenantAwareBaseEntity { - private static final long serialVersionUID = 1L; +public interface Action extends TenantAwareBaseEntity { /** * indicating that target action has no force time {@link #hasForcedTime()}. */ public static final long NO_FORCE_TIME = 0L; - /** - * the {@link DistributionSet} which should be installed by this action. - */ - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) - private DistributionSet distributionSet; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) - private Target target; - - @Column(name = "active") - private boolean active; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @OneToMany(mappedBy = "action", targetEntity = ActionStatus.class, fetch = FetchType.LAZY, cascade = { - CascadeType.REMOVE }) - private List actionStatus; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) - private RolloutGroup rolloutGroup; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) - private Rollout rollout; - - /** - * Note: filled only in {@link Status#DOWNLOAD}. - */ - @Transient - @CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT) - private int downloadProgressPercent; - /** * @return the distributionSet */ - public DistributionSet getDistributionSet() { - return distributionSet; - } + DistributionSet getDistributionSet(); /** * @param distributionSet * the distributionSet to set */ - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = distributionSet; - } + void setDistributionSet(DistributionSet distributionSet); /** * @return true when action is in state {@link Status#CANCELING} or * {@link Status#CANCELED}, false otherwise */ - public boolean isCancelingOrCanceled() { - return status == Status.CANCELING || status == Status.CANCELED; - } + boolean isCancelingOrCanceled(); - public void setActive(final boolean active) { - this.active = active; - } + void setActive(boolean active); - public Status getStatus() { - return status; - } + Status getStatus(); - public void setStatus(final Status status) { - this.status = status; - } + void setStatus(Status status); - public int getDownloadProgressPercent() { - return downloadProgressPercent; - } + int getDownloadProgressPercent(); - public void setDownloadProgressPercent(final int downloadProgressPercent) { - this.downloadProgressPercent = downloadProgressPercent; - } + void setDownloadProgressPercent(int downloadProgressPercent); - public boolean isActive() { - return active; - } + boolean isActive(); - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } + void setActionType(ActionType actionType); /** * @return the actionType */ - public ActionType getActionType() { - return actionType; - } + ActionType getActionType(); - public List getActionStatus() { - return actionStatus; - } + List getActionStatus(); - public void setTarget(final Target target) { - this.target = target; - } + void setTarget(Target target); - public Target getTarget() { - return target; - } + Target getTarget(); - public long getForcedTime() { - return forcedTime; - } + long getForcedTime(); - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } + void setForcedTime(long forcedTime); - public RolloutGroup getRolloutGroup() { - return rolloutGroup; - } + RolloutGroup getRolloutGroup(); - public void setRolloutGroup(final RolloutGroup rolloutGroup) { - this.rolloutGroup = rolloutGroup; - } + void setRolloutGroup(RolloutGroup rolloutGroup); - public Rollout getRollout() { - return rollout; - } + Rollout getRollout(); - public void setRollout(final Rollout rollout) { - this.rollout = rollout; - } + void setRollout(Rollout rollout); /** * checks if the {@link #forcedTime} is hit by the given @@ -210,12 +83,7 @@ public class Action extends TenantAwareBaseEntity { * {@link ActionType#TIMEFORCED} and the given {@code hitTimeMillis} * is greater than the {@link #forcedTime} otherwise {@code false} */ - public boolean isHitAutoForceTime(final long hitTimeMillis) { - if (actionType == ActionType.TIMEFORCED) { - return hitTimeMillis >= forcedTime; - } - return false; - } + boolean isHitAutoForceTime(long hitTimeMillis); /** * @return {@code true} if either the {@link #type} is @@ -223,28 +91,12 @@ public class Action extends TenantAwareBaseEntity { * then if the {@link #forcedTime} has been exceeded otherwise * always {@code false} */ - public boolean isForce() { - switch (actionType) { - case FORCED: - return true; - case TIMEFORCED: - return isHitAutoForceTime(System.currentTimeMillis()); - default: - return false; - } - } + boolean isForce(); /** * @return true when action is forced, false otherwise */ - public boolean isForced() { - return actionType == ActionType.FORCED; - } - - @Override - public String toString() { - return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; - } + boolean isForced(); /** * Action status as reported by the controller. @@ -309,4 +161,5 @@ public class Action extends TenantAwareBaseEntity { public enum ActionType { FORCED, SOFT, TIMEFORCED; } -} + +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java index c8d320abd..05f6966d8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java @@ -8,107 +8,15 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.ArrayList; import java.util.List; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.Table; - import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import com.google.common.base.Splitter; +public interface ActionStatus extends TenantAwareBaseEntity { -/** - * Entity to store the status for a specific action. - */ -@Table(name = "sp_action_status", indexes = { @Index(name = "sp_idx_action_status_01", columnList = "tenant,action"), - @Index(name = "sp_idx_action_status_02", columnList = "tenant,action,status"), - @Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") }) -@Entity -public class ActionStatus extends TenantAwareBaseEntity { - private static final long serialVersionUID = 1L; + Long getOccurredAt(); - @Column(name = "target_occurred_at") - private Long occurredAt; - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "action", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_act_stat_action")) - private Action action; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class) - @CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = { - @Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") }) - @Column(name = "detail_message", length = 512) - private final List messages = new ArrayList<>(); - - /** - * Creates a new {@link ActionStatus} object. - * - * @param action - * the action for this action status - * @param status - * the status for this action status - * @param occurredAt - * the occurred timestamp - */ - public ActionStatus(final Action action, final Status status, final Long occurredAt) { - this.action = action; - this.status = status; - this.occurredAt = occurredAt; - } - - /** - * Creates a new {@link ActionStatus} object. - * - * @param action - * the action for this action status - * @param status - * the status for this action status - * @param occurredAt - * the occurred timestamp - * @param messages - * the messages which should be added to this action status - */ - public ActionStatus(final Action action, final Status status, final Long occurredAt, final String... messages) { - this.action = action; - this.status = status; - this.occurredAt = occurredAt; - for (final String msg : messages) { - addMessage(msg); - } - } - - /** - * JPA default constructor. - */ - public ActionStatus() { - // JPA default constructor. - } - - public Long getOccurredAt() { - return occurredAt; - } - - public void setOccurredAt(final Long occurredAt) { - this.occurredAt = occurredAt; - } + void setOccurredAt(Long occurredAt); /** * Adds message including splitting in case it exceeds 512 length. @@ -116,28 +24,16 @@ public class ActionStatus extends TenantAwareBaseEntity { * @param message * to add */ - public final void addMessage(final String message) { - Splitter.fixedLength(512).split(message).forEach(messages::add); - } + void addMessage(String message); - public List getMessages() { - return messages; - } + List getMessages(); - public Action getAction() { - return action; - } + Action getAction(); - public void setAction(final Action action) { - this.action = action; - } + void setAction(Action action); - public Status getStatus() { - return status; - } + Status getStatus(); - public void setStatus(final Status status) { - this.status = status; - } + void setStatus(Status status); -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java index 73eab32f9..4b81320e8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.model; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; @@ -16,6 +17,7 @@ import org.eclipse.hawkbit.repository.model.Action.Status; * action's {@link ActionStatus}. * */ +// TODO: create interface public class ActionWithStatusCount { private final Long actionStatusCount; private final Long actionId; @@ -28,7 +30,7 @@ public class ActionWithStatusCount { private final Long dsId; private final String dsName; private final String dsVersion; - private final Action action; + private final JpaAction action; private final String rolloutName; /** @@ -78,7 +80,7 @@ public class ActionWithStatusCount { this.actionStatusCount = actionStatusCount; this.rolloutName = rolloutName; - action = new Action(); + action = new JpaAction(); action.setActionType(actionType); action.setActive(actionActive); action.setForcedTime(actionForceTime); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java index b384a3100..a4db06d25 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java @@ -8,49 +8,16 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +public interface Artifact extends TenantAwareBaseEntity { -/** - * Tenant specific locally stored artifact representation that is used by - * {@link SoftwareModule}. - */ -@MappedSuperclass -public abstract class Artifact extends TenantAwareBaseEntity { - private static final long serialVersionUID = 1L; + SoftwareModule getSoftwareModule(); - @Column(name = "sha1_hash", length = 40, nullable = true) - private String sha1Hash; + void setSoftwareModule(SoftwareModule softwareModule); - @Column(name = "md5_hash", length = 32, nullable = true) - private String md5Hash; + String getMd5Hash(); - @Column(name = "file_size") - private Long size; + String getSha1Hash(); - public abstract SoftwareModule getSoftwareModule(); + Long getSize(); - public String getMd5Hash() { - return md5Hash; - } - - public String getSha1Hash() { - return sha1Hash; - } - - public void setMd5Hash(final String md5Hash) { - this.md5Hash = md5Hash; - } - - public void setSha1Hash(final String sha1Hash) { - this.sha1Hash = sha1Hash; - } - - public Long getSize() { - return size; - } - - public void setSize(final Long size) { - this.size = size; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java index 65300c6c4..0b8a8c5ee 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java @@ -10,171 +10,18 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Column; -import javax.persistence.EntityListeners; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; -import javax.persistence.Version; - -import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener; -import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener; -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.hateoas.Identifiable; -/** - * Holder of the base attributes common to all entities. - * - */ -@MappedSuperclass -@Access(AccessType.FIELD) -@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) -public abstract class BaseEntity implements Serializable, Identifiable { - private static final long serialVersionUID = 1L; +public interface BaseEntity extends Serializable, Identifiable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; + Long getCreatedAt(); - private String createdBy; - private String lastModifiedBy; - private Long createdAt; - private Long lastModifiedAt; + String getCreatedBy(); - @Version - @Column(name = "optlock_revision") - private long optLockRevision; + Long getLastModifiedAt(); - /** - * Default constructor needed for JPA entities. - */ - public BaseEntity() { - // Default constructor needed for JPA entities. - } + String getLastModifiedBy(); - @Access(AccessType.PROPERTY) - @Column(name = "created_at", insertable = true, updatable = false) - public Long getCreatedAt() { - return createdAt; - } + long getOptLockRevision(); - @Access(AccessType.PROPERTY) - @Column(name = "created_by", insertable = true, updatable = false, length = 40) - public String getCreatedBy() { - return createdBy; - } - - @Access(AccessType.PROPERTY) - @Column(name = "last_modified_at", insertable = false, updatable = true) - public Long getLastModifiedAt() { - return lastModifiedAt; - } - - @Access(AccessType.PROPERTY) - @Column(name = "last_modified_by", insertable = false, updatable = true, length = 40) - public String getLastModifiedBy() { - return lastModifiedBy; - } - - @CreatedBy - public void setCreatedBy(final String createdBy) { - this.createdBy = createdBy; - } - - @LastModifiedBy - public void setLastModifiedBy(final String lastModifiedBy) { - this.lastModifiedBy = lastModifiedBy; - } - - @CreatedDate - public void setCreatedAt(final Long createdAt) { - this.createdAt = createdAt; - } - - @LastModifiedDate - public void setLastModifiedAt(final Long lastModifiedAt) { - this.lastModifiedAt = lastModifiedAt; - } - - public long getOptLockRevision() { - return optLockRevision; - } - - // for test purposes only - void setOptLockRevision(final long optLockRevision) { - this.optLockRevision = optLockRevision; - } - - @Override - public Long getId() { - return id; - } - - @Override - public String toString() { - return "BaseEntity [id=" + id + "]"; - } - - public void setId(final Long id) { - this.id = id; - } - - /** - * Defined equals/hashcode strategy for the repository in general is that an - * entity is equal if it has the same {@link #getId()} and - * {@link #getOptLockRevision()} and class. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { // NOSONAR - as this is generated code - final int prime = 31; - int result = 1; - result = prime * result + (id == null ? 0 : id.hashCode()); - result = prime * result + (int) (optLockRevision ^ optLockRevision >>> 32); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - /** - * Defined equals/hashcode strategy for the repository in general is that an - * entity is equal if it has the same {@link #getId()} and - * {@link #getOptLockRevision()} and class. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(final Object obj) { // NOSONAR - as this is generated - // code - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(this.getClass().isInstance(obj))) { - return false; - } - final BaseEntity other = (BaseEntity) obj; - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (optLockRevision != other.optLockRevision) { - return false; - } - return true; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java index a9d390284..41b1e5f5d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java @@ -8,198 +8,47 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface DistributionSet extends NamedVersionedEntity { -import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; -import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.persistence.annotations.CascadeOnDelete; + Set getTags(); -/** - *

- * The {@link DistributionSet} is defined in the SP repository and contains at - * least an OS and an Agent Hub. - *

- * - *

- * A {@link Target} has exactly one target {@link DistributionSet} assigned. - *

- * - */ -@Entity -@Table(name = "sp_distribution_set", uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { - @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), - @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), - @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), - @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) -public class DistributionSet extends NamedVersionedEntity { - private static final long serialVersionUID = 1L; - - @Column(name = "required_migration_step") - private boolean requiredMigrationStep = false; - - @ManyToMany(targetEntity = SoftwareModule.class, fetch = FetchType.LAZY) - @JoinTable(name = "sp_ds_module", joinColumns = { - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) - private final Set modules = new HashSet<>(); - - @ManyToMany(targetEntity = DistributionSetTag.class) - @JoinTable(name = "sp_ds_dstag", joinColumns = { - @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) - private Set tags = new HashSet<>(); - - @Column(name = "deleted") - private boolean deleted = false; - - @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = Target.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - @OneToMany(mappedBy = "installedDistributionSet", targetEntity = TargetInfo.class, fetch = FetchType.LAZY) - private List installedAtTargets; - - @OneToMany(mappedBy = "distributionSet", targetEntity = Action.class, fetch = FetchType.LAZY) - private List actions; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }) - @JoinColumn(name = "ds_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) - private DistributionSetType type; - - @Column(name = "complete") - private boolean complete = false; - - /** - * Default constructor. - */ - public DistributionSet() { - super(); - } - - /** - * Parameterized constructor. - * - * @param name - * of the {@link DistributionSet} - * @param version - * of the {@link DistributionSet} - * @param description - * of the {@link DistributionSet} - * @param type - * of the {@link DistributionSet} - * @param moduleList - * {@link SoftwareModule}s of the {@link DistributionSet} - */ - public DistributionSet(final String name, final String version, final String description, - final DistributionSetType type, final Iterable moduleList) { - super(name, version, description); - - this.type = type; - if (moduleList != null) { - moduleList.forEach(this::addModule); - } - if (this.type != null) { - complete = this.type.checkComplete(this); - } - } - - public Set getTags() { - return tags; - } - - public boolean isDeleted() { - return deleted; - } + boolean isDeleted(); /** * @return immutable list of meta data elements. */ - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } + List getMetadata(); - public List getActions() { - return actions; - } + List getActions(); - public boolean isRequiredMigrationStep() { - return requiredMigrationStep; - } + boolean isRequiredMigrationStep(); - public DistributionSet setDeleted(final boolean deleted) { - this.deleted = deleted; - return this; - } + DistributionSet setDeleted(boolean deleted); - public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { - requiredMigrationStep = isRequiredMigrationStep; - return this; - } + DistributionSet setRequiredMigrationStep(boolean isRequiredMigrationStep); - public DistributionSet setTags(final Set tags) { - this.tags = tags; - return this; - } + DistributionSet setTags(Set tags); /** * @return the assignedTargets */ - public List getAssignedTargets() { - return assignedToTargets; - } + List getAssignedTargets(); /** * @return the installedTargets */ - public List getInstalledTargets() { - return installedAtTargets; - } - - @Override - public String toString() { - return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() - + ", getId()=" + getId() + "]"; - } + List getInstalledTargets(); /** * * @return unmodifiableSet of {@link SoftwareModule}. */ - public Set getModules() { - return Collections.unmodifiableSet(modules); - } + Set getModules(); - public DistributionSetIdName getDistributionSetIdName() { - return new DistributionSetIdName(getId(), getName(), getVersion()); - } + DistributionSetIdName getDistributionSetIdName(); /** * @param softwareModule @@ -207,41 +56,7 @@ public class DistributionSet extends NamedVersionedEntity { * if it already existed in the set * */ - public boolean addModule(final SoftwareModule softwareModule) { - - // we cannot allow that modules are added without a type defined - if (type == null) { - throw new DistributionSetTypeUndefinedException(); - } - - // check if it is allowed to such a module to this DS type - if (!type.containsModuleType(softwareModule.getType())) { - throw new UnsupportedSoftwareModuleForThisDistributionSetException(); - } - - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - return false; - } - - final long allready = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); - - if (allready >= softwareModule.getType().getMaxAssignments()) { - final Optional sameKey = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); - modules.remove(sameKey.get()); - } - - if (modules.add(softwareModule)) { - complete = type.checkComplete(this); - return true; - } - - return false; - } + boolean addModule(SoftwareModule softwareModule); /** * Removed given {@link SoftwareModule} from this DS instance. @@ -250,19 +65,7 @@ public class DistributionSet extends NamedVersionedEntity { * to remove * @return true if element was found and removed */ - public boolean removeModule(final SoftwareModule softwareModule) { - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - modules.remove(found.get()); - complete = type.checkComplete(this); - return true; - } - - return false; - - } + boolean removeModule(SoftwareModule softwareModule); /** * Searches through modules for the given type. @@ -272,26 +75,12 @@ public class DistributionSet extends NamedVersionedEntity { * @return SoftwareModule of given type or null if not in the * list. */ - public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { - final Optional result = modules.stream().filter(module -> module.getType().equals(type)) - .findFirst(); + SoftwareModule findFirstModuleByType(SoftwareModuleType type); - if (result.isPresent()) { - return result.get(); - } + DistributionSetType getType(); - return null; - } + void setType(DistributionSetType type); - public DistributionSetType getType() { - return type; - } + boolean isComplete(); - public void setType(final DistributionSetType type) { - this.type = type; - } - - public boolean isComplete() { - return complete; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java index 67a99506c..187b04e81 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java @@ -8,73 +8,10 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +public interface DistributionSetMetadata extends MetaData { -/** - * Meta data for {@link DistributionSet}. - * - */ -@IdClass(DsMetadataCompositeKey.class) -@Entity -@Table(name = "sp_ds_metadata") -public class DistributionSetMetadata extends MetaData { - private static final long serialVersionUID = 1L; + void setDistributionSet(DistributionSet distributionSet); - @Id - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds")) - private DistributionSet distributionSet; + DistributionSet getDistributionSet(); - public DistributionSetMetadata() { - // default public constructor for JPA - } - - public DistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) { - super(key, value); - this.distributionSet = distributionSet; - } - - public DsMetadataCompositeKey getId() { - return new DsMetadataCompositeKey(distributionSet, getKey()); - } - - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = distributionSet; - } - - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - final DistributionSetMetadata other = (DistributionSetMetadata) obj; - if (distributionSet == null) { - if (other.distributionSet != null) { - return false; - } - } else if (!distributionSet.equals(other.distributionSet)) { - return false; - } - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTag.java index 137fde5b9..cd5ded232 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTag.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTag.java @@ -10,77 +10,8 @@ package org.eclipse.hawkbit.repository.model; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Index; -import javax.persistence.ManyToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface DistributionSetTag extends Tag { -/** - * A {@link DistributionSetTag} is used to describe DistributionSet attributes - * and use them also for filtering the DistributionSet list. - * - */ -@Entity -@Table(name = "sp_distributionset_tag", indexes = { - @Index(name = "sp_idx_distribution_set_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_ds_tag")) -public class DistributionSetTag extends Tag { - private static final long serialVersionUID = 1L; + List getAssignedToDistributionSet(); - @ManyToMany(mappedBy = "tags", targetEntity = DistributionSet.class, fetch = FetchType.LAZY) - private List assignedToDistributionSet; - - /** - * Public constructor. - * - * @param name - * of the {@link DistributionSetTag} - **/ - public DistributionSetTag(final String name) { - super(name, null, null); - } - - /** - * Public constructor. - * - * @param name - * of the {@link DistributionSetTag} - * @param description - * of the {@link DistributionSetTag} - * @param colour - * of tag in UI - */ - public DistributionSetTag(final String name, final String description, final String colour) { - super(name, description, colour); - } - - DistributionSetTag() { - super(); - } - - public List getAssignedToDistributionSet() { - return assignedToDistributionSet; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { // NOSONAR - as this is generated - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof DistributionSetTag)) { - return false; - } - - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetType.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetType.java index 61d2fc58c..f540428a9 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetType.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetType.java @@ -8,109 +8,26 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.HashSet; -import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +import org.eclipse.hawkbit.repository.jpa.model.DistributionSetTypeElement; -/** - * A distribution set type defines which software module types can or have to be - * {@link DistributionSet}. - * - */ -@Entity -@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_prim", columnList = "tenant,id") }, uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_dst_name"), - @UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_dst_key") }) -public class DistributionSetType extends NamedEntity { - private static final long serialVersionUID = 1L; - - @OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = { - CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true) - @JoinColumn(name = "distribution_set_type", insertable = false, updatable = false) - private final Set elements = new HashSet<>(); - - @Column(name = "type_key", nullable = false, length = 64) - private String key; - - @Column(name = "colour", nullable = true, length = 16) - private String colour; - - @Column(name = "deleted") - private boolean deleted = false; - - public DistributionSetType() { - // 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 DistributionSetType(final String key, final String name, final String description) { - this(key, name, description, null); - } - - /** - * Constructor. - * - * @param key - * of the type - * @param name - * of the type - * @param description - * of the type - * @param color - * of the type. It will be null by default - */ - public DistributionSetType(final String key, final String name, final String description, final String color) { - super(name, description); - this.key = key; - colour = color; - } +public interface DistributionSetType extends NamedEntity { /** * @return the deleted */ - public boolean isDeleted() { - return deleted; - } + boolean isDeleted(); /** * @param deleted * the deleted to set */ - public void setDeleted(final boolean deleted) { - this.deleted = deleted; - } + void setDeleted(boolean deleted); - public Set getMandatoryModuleTypes() { - return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType()) - .collect(Collectors.toSet()); - } + Set getMandatoryModuleTypes(); - public Set getOptionalModuleTypes() { - return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType()) - .collect(Collectors.toSet()); - } + Set getOptionalModuleTypes(); /** * Checks if the given {@link SoftwareModuleType} is in this @@ -120,15 +37,7 @@ public class DistributionSetType extends NamedEntity { * search for * @return true if found */ - public boolean containsModuleType(final SoftwareModuleType softwareModuleType) { - for (final DistributionSetTypeElement distributionSetTypeElement : elements) { - if (distributionSetTypeElement.getSmType().equals(softwareModuleType)) { - return true; - } - - } - return false; - } + boolean containsModuleType(SoftwareModuleType softwareModuleType); /** * Checks if the given {@link SoftwareModuleType} is in this @@ -139,11 +48,7 @@ public class DistributionSetType extends NamedEntity { * search for * @return true if found */ - public boolean containsMandatoryModuleType(final SoftwareModuleType softwareModuleType) { - return elements.stream().filter(element -> element.isMandatory()) - .filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent(); - - } + boolean containsMandatoryModuleType(SoftwareModuleType softwareModuleType); /** * Checks if the given {@link SoftwareModuleType} is in this @@ -154,11 +59,7 @@ public class DistributionSetType extends NamedEntity { * search for by {@link SoftwareModuleType#getId()} * @return true if found */ - public boolean containsMandatoryModuleType(final Long softwareModuleTypeId) { - return elements.stream().filter(element -> element.isMandatory()) - .filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent(); - - } + boolean containsMandatoryModuleType(Long softwareModuleTypeId); /** * Checks if the given {@link SoftwareModuleType} is in this @@ -169,11 +70,7 @@ public class DistributionSetType extends NamedEntity { * search for * @return true if found */ - public boolean containsOptionalModuleType(final SoftwareModuleType softwareModuleType) { - return elements.stream().filter(element -> !element.isMandatory()) - .filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent(); - - } + boolean containsOptionalModuleType(SoftwareModuleType softwareModuleType); /** * Checks if the given {@link SoftwareModuleType} is in this @@ -184,11 +81,7 @@ public class DistributionSetType extends NamedEntity { * search by {@link SoftwareModuleType#getId()} * @return true if found */ - public boolean containsOptionalModuleType(final Long softwareModuleTypeId) { - return elements.stream().filter(element -> !element.isMandatory()) - .filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent(); - - } + boolean containsOptionalModuleType(Long softwareModuleTypeId); /** * Compares the modules of this {@link DistributionSetType} and the given @@ -198,9 +91,7 @@ public class DistributionSetType extends NamedEntity { * to compare with * @return true if the lists are identical. */ - public boolean areModuleEntriesIdentical(final DistributionSetType dsType) { - return new HashSet(dsType.elements).equals(elements); - } + boolean areModuleEntriesIdentical(DistributionSetType dsType); /** * Adds {@link SoftwareModuleType} that is optional for the @@ -210,11 +101,7 @@ public class DistributionSetType extends NamedEntity { * to add * @return updated instance */ - public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) { - elements.add(new DistributionSetTypeElement(this, smType, false)); - - return this; - } + DistributionSetType addOptionalModuleType(SoftwareModuleType smType); /** * Adds {@link SoftwareModuleType} that is mandatory for the @@ -224,11 +111,7 @@ public class DistributionSetType extends NamedEntity { * to add * @return updated instance */ - public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) { - elements.add(new DistributionSetTypeElement(this, smType, true)); - - return this; - } + DistributionSetType addMandatoryModuleType(SoftwareModuleType smType); /** * Removes {@link SoftwareModuleType} from the list. @@ -237,25 +120,11 @@ public class DistributionSetType extends NamedEntity { * to remove * @return updated instance */ - public DistributionSetType removeModuleType(final Long smTypeId) { - // we search by id (standard equals compares also revison) - final Optional found = elements.stream() - .filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst(); + DistributionSetType removeModuleType(Long smTypeId); - if (found.isPresent()) { - elements.remove(found.get()); - } + String getKey(); - return this; - } - - public String getKey() { - return key; - } - - public void setKey(final String key) { - this.key = key; - } + void setKey(String key); /** * @param distributionSet @@ -263,26 +132,10 @@ public class DistributionSetType extends NamedEntity { * @return true if the all mandatory software module types are * in the system. */ - public boolean checkComplete(final DistributionSet distributionSet) { - return distributionSet.getModules().stream().map(module -> module.getType()).collect(Collectors.toList()) - .containsAll(getMandatoryModuleTypes()); - } + boolean checkComplete(DistributionSet distributionSet); - public String getColour() { - return colour; - } + String getColour(); - public void setColour(final String colour) { - this.colour = colour; - } + void setColour(final String colour); - public Set getElements() { - return elements; - } - - @Override - public String toString() { - return "DistributionSetType [key=" + key + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]"; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifact.java index 898c685a5..daf0d1ae5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifact.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifact.java @@ -8,125 +8,20 @@ */ package org.eclipse.hawkbit.repository.model; -import java.net.URL; +public interface ExternalArtifact extends Artifact { -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; + ExternalArtifactProvider getExternalArtifactProvider(); -/** - * External artifact representation with all the necessary information to - * generate an artifact {@link URL} at runtime. - * - */ -@Table(name = "sp_external_artifact", indexes = { - @Index(name = "sp_idx_external_artifact_prim", columnList = "id,tenant") }) -@Entity -public class ExternalArtifact extends Artifact { - private static final long serialVersionUID = 1L; + String getUrl(); - @ManyToOne - @JoinColumn(name = "provider", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_art_to_ext_provider")) - private ExternalArtifactProvider externalArtifactProvider; + String getUrlSuffix(); - @Column(name = "url_suffix", length = 512) - private String urlSuffix; - - // CascadeType.PERSIST as we register ourself at the BSM - @ManyToOne(optional = false, cascade = { CascadeType.PERSIST }) - @JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_external_assigned_sm")) - private SoftwareModule softwareModule; - - /** - * Default constructor. - */ - public ExternalArtifact() { - super(); - } - - /** - * Constructs {@link ExternalArtifact}. - * - * @param externalArtifactProvider - * of the artifact - * @param urlSuffix - * of the artifact - * @param softwareModule - * of the artifact - */ - public ExternalArtifact(@NotNull final ExternalArtifactProvider externalArtifactProvider, final String urlSuffix, - final SoftwareModule softwareModule) { - setSoftwareModule(softwareModule); - this.externalArtifactProvider = externalArtifactProvider; - - if (urlSuffix != null) { - this.urlSuffix = urlSuffix; - } else { - this.urlSuffix = externalArtifactProvider.getDefaultSuffix(); - } - } - - /** - * @return the softwareModule - */ - @Override - public SoftwareModule getSoftwareModule() { - return softwareModule; - } - - public final void setSoftwareModule(final SoftwareModule softwareModule) { - this.softwareModule = softwareModule; - this.softwareModule.addArtifact(this); - } - - public ExternalArtifactProvider getExternalArtifactProvider() { - return externalArtifactProvider; - } - - public String getUrl() { - return new StringBuilder().append(externalArtifactProvider.getBasePath()).append(urlSuffix).toString(); - } - - public String getUrlSuffix() { - return urlSuffix; - } - - public void setExternalArtifactProvider(final ExternalArtifactProvider externalArtifactProvider) { - this.externalArtifactProvider = externalArtifactProvider; - } + void setExternalArtifactProvider(ExternalArtifactProvider externalArtifactProvider); /** * @param urlSuffix * the urlSuffix to set */ - public void setUrlSuffix(final String urlSuffix) { - this.urlSuffix = urlSuffix; - } + void setUrlSuffix(String urlSuffix); - @Override - public int hashCode() { // NOSONAR - as this is generated - final int prime = 31; - int result = super.hashCode(); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { // NOSONAR - as this is generated - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof ExternalArtifact)) { - return false; - } - - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifactProvider.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifactProvider.java index 9fa8714ac..bb9f2fbea 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifactProvider.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ExternalArtifactProvider.java @@ -8,69 +8,14 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Index; -import javax.persistence.Table; +public interface ExternalArtifactProvider extends NamedEntity { -/** - * External repositories for artifact storage. The SP server provides URLs for - * the targets to download from these external resources but does not access - * them itself. - * - */ -@Table(name = "sp_external_provider", indexes = { - @Index(name = "sp_idx_external_provider_prim", columnList = "tenant,id") }) -@Entity -public class ExternalArtifactProvider extends NamedEntity { - private static final long serialVersionUID = 1L; + String getBasePath(); - @Column(name = "base_url", length = 512, nullable = false) - private String basePath; + String getDefaultSuffix(); - @Column(name = "default_url_suffix", length = 512, nullable = true) - private String defaultSuffix; + void setBasePath(String basePath); - /** - * Constructs {@link ExternalArtifactProvider} based on given properties. - * - * @param name - * of the provided - * @param description - * which is optional - * @param baseURL - * of all {@link ExternalArtifact}s of the provider - * @param defaultUrlSuffix - * that is used if {@link ExternalArtifact#getUrlSuffix()} is - * empty. - */ - public ExternalArtifactProvider(final String name, final String description, final String baseURL, - final String defaultUrlSuffix) { - super(name, description); - basePath = baseURL; - defaultSuffix = defaultUrlSuffix; - } + void setDefaultSuffix(String defaultSuffix); - ExternalArtifactProvider() { - super(); - defaultSuffix = ""; - basePath = ""; - } - - public String getBasePath() { - return basePath; - } - - public String getDefaultSuffix() { - return defaultSuffix; - } - - public void setBasePath(final String basePath) { - this.basePath = basePath; - } - - public void setDefaultSuffix(final String defaultSuffix) { - this.defaultSuffix = defaultSuffix; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/LocalArtifact.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/LocalArtifact.java index 8afcdc168..0f3a22c41 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/LocalArtifact.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/LocalArtifact.java @@ -8,106 +8,8 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; +public interface LocalArtifact extends Artifact { -import com.mongodb.gridfs.GridFS; -import com.mongodb.gridfs.GridFSFile; + String getFilename(); -/** - * Tenant specific locally stored artifact representation that is used by - * {@link SoftwareModule} . It contains all information that is provided by the - * user while all SP server generated information related to the artifact (hash, - * length) is stored directly with the binary itself. - * - * - * - */ -@Table(name = "sp_artifact", indexes = { @Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"), - @Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") }) -@Entity -public class LocalArtifact extends Artifact { - private static final long serialVersionUID = 1L; - - @NotNull - @Column(name = "gridfs_file_name", length = 40) - private String gridFsFileName; - - @NotNull - @Column(name = "provided_file_name", length = 256) - private String filename; - - @ManyToOne(optional = false, cascade = { CascadeType.PERSIST }) - @JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm")) - private SoftwareModule softwareModule; - - /** - * Default constructor. - */ - public LocalArtifact() { - super(); - } - - /** - * Constructs artifact. - * - * @param gridFsFileName - * that is the link to the {@link GridFS} entity. - * @param filename - * that is used by {@link GridFSFile} store. - * @param softwareModule - * of this artifact - */ - public LocalArtifact(@NotNull final String gridFsFileName, @NotNull final String filename, - final SoftwareModule softwareModule) { - setSoftwareModule(softwareModule); - this.gridFsFileName = gridFsFileName; - this.filename = filename; - } - - @Override - public int hashCode() { // NOSONAR - as this is generated - final int prime = 31; - int result = super.hashCode(); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { // NOSONAR - as this is generated - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof LocalArtifact)) { - return false; - } - - return true; - } - - @Override - public SoftwareModule getSoftwareModule() { - return softwareModule; - } - - public final void setSoftwareModule(final SoftwareModule softwareModule) { - this.softwareModule = softwareModule; - this.softwareModule.addArtifact(this); - } - - public String getGridFsFileName() { - return gridFsFileName; - } - - public String getFilename() { - return filename; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java index c41a0e8c9..8d6e6eed6 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java @@ -10,89 +10,14 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; +public interface MetaData extends Serializable { -/** - * Meta data for entities. - * - */ -@MappedSuperclass -public abstract class MetaData implements Serializable { - private static final long serialVersionUID = 1L; + String getKey(); - @Id - @Column(name = "meta_key", length = 128) - private String key; + void setKey(String key); - @Column(name = "meta_value", length = 4000) - @Basic - private String value; + String getValue(); - public MetaData(final String key, final String value) { - super(); - this.key = key; - this.value = value; - } + void setValue(String value); - public MetaData() { - // Default constructor needed for JPA entities - } - - public String getKey() { - return key; - } - - public void setKey(final String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(final String value) { - this.value = value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((key == null) ? 0 : key.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(this.getClass().isInstance(obj))) { - return false; - } - final MetaData other = (MetaData) obj; - if (key == null) { - if (other.key != null) { - return false; - } - } else if (!key.equals(other.key)) { - return false; - } - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.equals(other.value)) { - return false; - } - return true; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedEntity.java index e14d88161..1cc84bf8f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedEntity.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedEntity.java @@ -8,56 +8,14 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +public interface NamedEntity extends TenantAwareBaseEntity { -/** - * {@link TenantAwareBaseEntity} extension for all entities that are named in - * addition to their technical ID. - */ -@MappedSuperclass -public abstract class NamedEntity extends TenantAwareBaseEntity { - private static final long serialVersionUID = 1L; + String getDescription(); - @Column(name = "name", nullable = false, length = 64) - private String name; + String getName(); - @Column(name = "description", nullable = true, length = 512) - private String description; + void setDescription(String description); - /** - * Default constructor. - */ - public NamedEntity() { - super(); - } + void setName(String name); - /** - * Parameterized constructor. - * - * @param name - * of the {@link NamedEntity} - * @param description - * of the {@link NamedEntity} - */ - public NamedEntity(final String name, final String description) { - this.name = name; - this.description = description; - } - - public String getDescription() { - return description; - } - - public String getName() { - return name; - } - - public void setDescription(final String description) { - this.description = description; - } - - public void setName(final String name) { - this.name = name; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedVersionedEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedVersionedEntity.java index fa56da197..710980f13 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedVersionedEntity.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/NamedVersionedEntity.java @@ -8,43 +8,10 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +public interface NamedVersionedEntity extends NamedEntity { -/** - * Extension for {@link NamedEntity} that are versioned. - * - */ -@MappedSuperclass -public abstract class NamedVersionedEntity extends NamedEntity { - private static final long serialVersionUID = 1L; + String getVersion(); - @Column(name = "version", nullable = false, length = 64) - private String version; + void setVersion(String version); - /** - * parameterized constructor. - * - * @param name - * of the entity - * @param version - * of the entity - * @param description - */ - public NamedVersionedEntity(final String name, final String version, final String description) { - super(name, description); - this.version = version; - } - - NamedVersionedEntity() { - super(); - } - - public String getVersion() { - return version; - } - - public void setVersion(final String version) { - this.version = version; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Rollout.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Rollout.java index a7f9b10cb..bf696d2fd 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Rollout.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Rollout.java @@ -10,225 +10,53 @@ package org.eclipse.hawkbit.repository.model; import java.util.List; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.cache.CacheField; -import org.eclipse.hawkbit.cache.CacheKeys; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.Action.ActionType; -/** - * @author Michael Hirsch - * - */ -@Entity -@Table(name = "sp_rollout", indexes = { - @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_rollout")) -public class Rollout extends NamedEntity { +public interface Rollout extends NamedEntity { - private static final long serialVersionUID = 1L; + DistributionSet getDistributionSet(); - @OneToMany(targetEntity = RolloutGroup.class) - @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) - private List rolloutGroups; + void setDistributionSet(DistributionSet distributionSet); - @Column(name = "target_filter", length = 1024, nullable = false) - private String targetFilterQuery; + List getRolloutGroups(); - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) - private DistributionSet distributionSet; + void setRolloutGroups(List rolloutGroups); - @Column(name = "status") - private RolloutStatus status = RolloutStatus.CREATING; + String getTargetFilterQuery(); - @Column(name = "last_check") - private long lastCheck = 0L; + void setTargetFilterQuery(String targetFilterQuery); - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType = ActionType.FORCED; + RolloutStatus getStatus(); - @Column(name = "forced_time") - private long forcedTime; + void setStatus(RolloutStatus status); - @Column(name = "total_targets") - private long totalTargets; + long getLastCheck(); - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) - private int rolloutGroupsTotal = 0; + void setLastCheck(long lastCheck); - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) - private int rolloutGroupsCreated = 0; + ActionType getActionType(); - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; + void setActionType(ActionType actionType); - public DistributionSet getDistributionSet() { - return distributionSet; - } + long getForcedTime(); - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = distributionSet; - } + void setForcedTime(long forcedTime); - public List getRolloutGroups() { - return rolloutGroups; - } + long getTotalTargets(); - public void setRolloutGroups(final List rolloutGroups) { - this.rolloutGroups = rolloutGroups; - } + void setTotalTargets(long totalTargets); - public String getTargetFilterQuery() { - return targetFilterQuery; - } + int getRolloutGroupsTotal(); - public void setTargetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = targetFilterQuery; - } + void setRolloutGroupsTotal(int rolloutGroupsTotal); - public RolloutStatus getStatus() { - return status; - } + int getRolloutGroupsCreated(); - public void setStatus(final RolloutStatus status) { - this.status = status; - } + void setRolloutGroupsCreated(int rolloutGroupsCreated); - public long getLastCheck() { - return lastCheck; - } + TotalTargetCountStatus getTotalTargetCountStatus(); - public void setLastCheck(final long lastCheck) { - this.lastCheck = lastCheck; - } + void setTotalTargetCountStatus(TotalTargetCountStatus totalTargetCountStatus); - public ActionType getActionType() { - return actionType; - } - - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - public long getForcedTime() { - return forcedTime; - } - - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public int getRolloutGroupsTotal() { - return rolloutGroupsTotal; - } - - public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { - this.rolloutGroupsTotal = rolloutGroupsTotal; - } - - public int getRolloutGroupsCreated() { - return rolloutGroupsCreated; - } - - public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { - this.rolloutGroupsCreated = rolloutGroupsCreated; - } - - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery - + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck - + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } - - /** - * - * State machine for rollout. - * - */ - public enum RolloutStatus { - - /** - * Rollouts is beeing created. - */ - CREATING, - - /** - * Rollout is ready to start. - */ - READY, - - /** - * Rollout is paused. - */ - PAUSED, - - /** - * Rollout is starting. - */ - STARTING, - - /** - * Rollout is stopped. - */ - STOPPED, - - /** - * Rollout is running. - */ - RUNNING, - - /** - * Rollout is finished. - */ - FINISHED, - - /** - * Rollout could not created due errors, might be database problem due - * asynchronous creating. - */ - ERROR_CREATING, - - /** - * Rollout could not started due errors, might be database problem due - * asynchronous starting. - */ - ERROR_STARTING; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutGroup.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutGroup.java index 5aa30126c..647278b78 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutGroup.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/RolloutGroup.java @@ -8,472 +8,71 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.ArrayList; -import java.util.List; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorCondition; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessCondition; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; +public interface RolloutGroup extends NamedEntity { -/** - * JPA entity definition of persisting a group of an rollout. - * - * @author Michael Hirsch - * - */ -@Entity -@Table(name = "sp_rolloutgroup", indexes = { - @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) -public class RolloutGroup extends NamedEntity { + Rollout getRollout(); - private static final long serialVersionUID = 1L; + void setRollout(Rollout rollout); - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) - private Rollout rollout; + RolloutGroupStatus getStatus(); - @Column(name = "status") - private RolloutGroupStatus status = RolloutGroupStatus.READY; + void setStatus(RolloutGroupStatus status); - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) - @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); + RolloutGroup getParent(); - @ManyToOne(fetch = FetchType.LAZY) - private RolloutGroup parent; + void setParent(RolloutGroup parent); - @Column(name = "success_condition", nullable = false) - private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + RolloutGroupSuccessCondition getSuccessCondition(); - @Column(name = "success_condition_exp", length = 512, nullable = false) - private String successConditionExp = null; + void setSuccessCondition(RolloutGroupSuccessCondition finishCondition); - @Column(name = "success_action", nullable = false) - private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + String getSuccessConditionExp(); - @Column(name = "success_action_exp", length = 512, nullable = false) - private String successActionExp = null; + void setSuccessConditionExp(String finishExp); - @Column(name = "error_condition") - private RolloutGroupErrorCondition errorCondition = null; + RolloutGroupErrorCondition getErrorCondition(); - @Column(name = "error_condition_exp", length = 512) - private String errorConditionExp = null; + void setErrorCondition(RolloutGroupErrorCondition errorCondition); - @Column(name = "error_action") - private RolloutGroupErrorAction errorAction = null; + String getErrorConditionExp(); - @Column(name = "error_action_exp", length = 512) - private String errorActionExp = null; + void setErrorConditionExp(String errorExp); - @Column(name = "total_targets") - private long totalTargets; + RolloutGroupErrorAction getErrorAction(); - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; + void setErrorAction(RolloutGroupErrorAction errorAction); - public Rollout getRollout() { - return rollout; - } + String getErrorActionExp(); - public void setRollout(final Rollout rollout) { - this.rollout = rollout; - } + void setErrorActionExp(String errorActionExp); - public RolloutGroupStatus getStatus() { - return status; - } + RolloutGroupSuccessAction getSuccessAction(); - public void setStatus(final RolloutGroupStatus status) { - this.status = status; - } + String getSuccessActionExp(); - public List getRolloutTargetGroup() { - return rolloutTargetGroup; - } + long getTotalTargets(); - public RolloutGroup getParent() { - return parent; - } + void setTotalTargets(long totalTargets); - public void setParent(final RolloutGroup parent) { - this.parent = parent; - } + void setSuccessAction(RolloutGroupSuccessAction successAction); - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - public String getSuccessConditionExp() { - return successConditionExp; - } - - public void setSuccessConditionExp(final String finishExp) { - successConditionExp = finishExp; - } - - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - public String getErrorConditionExp() { - return errorConditionExp; - } - - public void setErrorConditionExp(final String errorExp) { - errorConditionExp = errorExp; - } - - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - public String getErrorActionExp() { - return errorActionExp; - } - - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - public String getSuccessActionExp() { - return successActionExp; - } - - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } + void setSuccessActionExp(String successActionExp); /** * @return the totalTargetCountStatus */ - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } + TotalTargetCountStatus getTotalTargetCountStatus(); /** * @param totalTargetCountStatus * the totalTargetCountStatus to set */ - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } + void setTotalTargetCountStatus(TotalTargetCountStatus totalTargetCountStatus); - @Override - public String toString() { - return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup - + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp - + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() - + ", getId()=" + getId() + "]"; - } - - /** - * Rollout goup state machine. - * - */ - public enum RolloutGroupStatus { - - /** - * Ready to start the group. - */ - READY, - - /** - * Group is scheduled and started sometime, e.g. trigger of group - * before. - */ - SCHEDULED, - - /** - * Group is finished. - */ - FINISHED, - - /** - * Group is finished and has errors. - */ - ERROR, - - /** - * Group is running. - */ - RUNNING; - } - - /** - * The condition to evaluate if an group is success state. - */ - public enum RolloutGroupSuccessCondition { - THRESHOLD("thresholdRolloutGroupSuccessCondition"); - - private final String beanName; - - private RolloutGroupSuccessCondition(final String beanName) { - this.beanName = beanName; - } - - /** - * @return the beanName - */ - public String getBeanName() { - return beanName; - } - } - - /** - * The condition to evaluate if an group is in error state. - */ - public enum RolloutGroupErrorCondition { - THRESHOLD("thresholdRolloutGroupErrorCondition"); - - private final String beanName; - - private RolloutGroupErrorCondition(final String beanName) { - this.beanName = beanName; - } - - /** - * @return the beanName - */ - public String getBeanName() { - return beanName; - } - } - - /** - * The actions executed when the {@link RolloutGroup#errorCondition} is hit. - */ - public enum RolloutGroupErrorAction { - PAUSE("pauseRolloutGroupAction"); - - private final String beanName; - - private RolloutGroupErrorAction(final String beanName) { - this.beanName = beanName; - } - - /** - * @return the beanName - */ - public String getBeanName() { - return beanName; - } - } - - /** - * The actions executed when the {@link RolloutGroup#successCondition} is - * hit. - */ - public enum RolloutGroupSuccessAction { - NEXTGROUP("startNextRolloutGroupAction"); - - private final String beanName; - - private RolloutGroupSuccessAction(final String beanName) { - this.beanName = beanName; - } - - /** - * @return the beanName - */ - public String getBeanName() { - return beanName; - } - } - - /** - * Object which holds all {@link RolloutGroup} conditions together which can - * easily built. - */ - public static class RolloutGroupConditions { - private RolloutGroupSuccessCondition successCondition = null; - private String successConditionExp = null; - private RolloutGroupSuccessAction successAction = null; - private String successActionExp = null; - private RolloutGroupErrorCondition errorCondition = null; - private String errorConditionExp = null; - private RolloutGroupErrorAction errorAction = null; - private String errorActionExp = null; - - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - public String getSuccessConditionExp() { - return successConditionExp; - } - - public void setSuccessConditionExp(final String finishConditionExp) { - successConditionExp = finishConditionExp; - } - - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public String getSuccessActionExp() { - return successActionExp; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } - - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - public String getErrorConditionExp() { - return errorConditionExp; - } - - public void setErrorConditionExp(final String errorConditionExp) { - this.errorConditionExp = errorConditionExp; - } - - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - public String getErrorActionExp() { - return errorActionExp; - } - - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - } - - /** - * Builder to build easily the {@link RolloutGroupConditions}. - * - */ - public static class RolloutGroupConditionBuilder { - private final RolloutGroupConditions conditions = new RolloutGroupConditions(); - - public RolloutGroupConditions build() { - return conditions; - } - - /** - * Sets the finish condition and expression on the builder. - * - * @param condition - * the finish condition - * @param expression - * the finish expression - * @return the builder itself - */ - public RolloutGroupConditionBuilder successCondition(final RolloutGroupSuccessCondition condition, - final String expression) { - conditions.setSuccessCondition(condition); - conditions.setSuccessConditionExp(expression); - return this; - } - - /** - * Sets the success action and expression on the builder. - * - * @param action - * the success action - * @param expression - * the error expression - * @return the builder itself - */ - public RolloutGroupConditionBuilder successAction(final RolloutGroupSuccessAction action, - final String expression) { - conditions.setSuccessAction(action); - conditions.setSuccessActionExp(expression); - return this; - } - - /** - * Sets the error condition and expression on the builder. - * - * @param condition - * the error condition - * @param expression - * the error expression - * @return the builder itself - */ - public RolloutGroupConditionBuilder errorCondition(final RolloutGroupErrorCondition condition, - final String expression) { - conditions.setErrorCondition(condition); - conditions.setErrorConditionExp(expression); - return this; - } - - /** - * Sets the error action and expression on the builder. - * - * @param action - * the error action - * @param expression - * the error expression - * @return the builder itself - */ - public RolloutGroupConditionBuilder errorAction(final RolloutGroupErrorAction action, final String expression) { - conditions.setErrorAction(action); - conditions.setErrorActionExp(expression); - return this; - } - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModule.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModule.java index 327bff3db..67e1027a1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModule.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModule.java @@ -8,236 +8,79 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - * Base Software Module that is supported by OS level provisioning mechanism on - * the edge controller, e.g. OS, JVM, AgentHub. - * - */ -@Entity -@Table(name = "sp_base_software_module", uniqueConstraints = @UniqueConstraint(columnNames = { "module_type", "name", - "version", "tenant" }, name = "uk_base_sw_mod"), indexes = { - @Index(name = "sp_idx_base_sw_module_01", columnList = "tenant,deleted,name,version"), - @Index(name = "sp_idx_base_sw_module_02", columnList = "tenant,deleted,module_type"), - @Index(name = "sp_idx_base_sw_module_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "SoftwareModule.artifacts", attributeNodes = { @NamedAttributeNode("artifacts") }) -public class SoftwareModule extends NamedVersionedEntity { - private static final long serialVersionUID = 1L; - - @ManyToOne - @JoinColumn(name = "module_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_module_type")) - private SoftwareModuleType type; - - @ManyToMany(mappedBy = "modules", targetEntity = DistributionSet.class, fetch = FetchType.LAZY) - private final List assignedTo = new ArrayList<>(); - - @Column(name = "deleted") - private boolean deleted = false; - - @Column(name = "vendor", nullable = true, length = 256) - private String vendor; - - @OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = LocalArtifact.class) - private List artifacts; - - @OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = ExternalArtifact.class) - private List externalArtifacts; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }) - @JoinColumn(name = "sw_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - /** - * Default constructor. - */ - public SoftwareModule() { - super(); - } - - /** - * parameterized constructor. - * - * @param type - * of the {@link SoftwareModule} - * @param name - * abstract name of the {@link SoftwareModule} - * @param version - * of the {@link SoftwareModule} - * @param description - * of the {@link SoftwareModule} - * @param vendor - * of the {@link SoftwareModule} - */ - public SoftwareModule(final SoftwareModuleType type, final String name, final String version, - final String description, final String vendor) { - super(name, version, description); - this.vendor = vendor; - this.type = type; - } +public interface SoftwareModule extends NamedVersionedEntity { /** * @param artifact * is added to the assigned {@link Artifact}s. */ - public void addArtifact(final LocalArtifact artifact) { - if (null == artifacts) { - artifacts = new ArrayList<>(4); - } - - if (!artifacts.contains(artifact)) { - artifacts.add(artifact); - } - } + void addArtifact(LocalArtifact artifact); /** * @param artifact * is added to the assigned {@link Artifact}s. */ - public void addArtifact(final ExternalArtifact artifact) { - if (null == externalArtifacts) { - externalArtifacts = new ArrayList<>(4); - } - - if (!externalArtifacts.contains(artifact)) { - externalArtifacts.add(artifact); - } - - } + void addArtifact(ExternalArtifact artifact); /** * @param artifactId * to look for * @return found {@link Artifact} */ - public Optional getLocalArtifact(final Long artifactId) { - if (null == artifacts) { - return Optional.empty(); - } - - return artifacts.stream().filter(artifact -> artifact.getId().equals(artifactId)).findFirst(); - } + Optional getLocalArtifact(Long artifactId); /** * @param fileName * to look for * @return found {@link Artifact} */ - public Optional getLocalArtifactByFilename(final String fileName) { - if (null == artifacts) { - return Optional.empty(); - } - - return artifacts.stream().filter(artifact -> artifact.getFilename().equalsIgnoreCase(fileName.trim())) - .findFirst(); - } + Optional getLocalArtifactByFilename(String fileName); /** * @return the artifacts */ - public List getArtifacts() { - final List result = new ArrayList<>(); - result.addAll(artifacts); - result.addAll(externalArtifacts); - - return result; - } + List getArtifacts(); /** * @return local artifacts only */ - public List getLocalArtifacts() { - if (artifacts == null) { - return Collections.emptyList(); - } + List getLocalArtifacts(); - return artifacts; - } - - public String getVendor() { - return vendor; - } + String getVendor(); /** * @param artifact * is removed from the assigned {@link LocalArtifact}s. */ - public void removeArtifact(final LocalArtifact artifact) { - if (null != artifacts) { - artifacts.remove(artifact); - } - } + void removeArtifact(LocalArtifact artifact); /** * @param artifact * is removed from the assigned {@link ExternalArtifact}s. */ - public void removeArtifact(final ExternalArtifact artifact) { - if (null != externalArtifacts) { - externalArtifacts.remove(artifact); - } - } + void removeArtifact(ExternalArtifact artifact); - public void setVendor(final String vendor) { - this.vendor = vendor; - } + void setVendor(String vendor); - public SoftwareModuleType getType() { - return type; - } + SoftwareModuleType getType(); - public boolean isDeleted() { - return deleted; - } + boolean isDeleted(); - public void setDeleted(final boolean deleted) { - this.deleted = deleted; - } + void setDeleted(boolean deleted); - public void setType(final SoftwareModuleType type) { - this.type = type; - } + void setType(SoftwareModuleType type); /** * @return immutable list of meta data elements. */ - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } - - @Override - public String toString() { - return "SoftwareModule [deleted=" + deleted + ", name=" + getName() + ", version=" + getVersion() - + ", revision=" + getOptLockRevision() + ", Id=" + getId() + ", type=" + getType().getName() + "]"; - } + List getMetadata(); /** * @return the assignedTo */ - public List getAssignedTo() { - return assignedTo; - } + List getAssignedTo(); -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java index 5ddd273d3..8cece2a39 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java @@ -8,73 +8,10 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +public interface SoftwareModuleMetadata extends MetaData { -/** - * Metadata for {@link SoftwareModule}. - * - */ -@IdClass(SwMetadataCompositeKey.class) -@Entity -@Table(name = "sp_sw_metadata") -public class SoftwareModuleMetadata extends MetaData { - private static final long serialVersionUID = 1L; + SoftwareModule getSoftwareModule(); - @Id - @ManyToOne(targetEntity = SoftwareModule.class, fetch = FetchType.LAZY) - @JoinColumn(name = "sw_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_sw")) - private SoftwareModule softwareModule; + void setSoftwareModule(SoftwareModule softwareModule); - public SoftwareModuleMetadata() { - // default public constructor for JPA - } - - public SoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) { - super(key, value); - this.softwareModule = softwareModule; - } - - public SwMetadataCompositeKey getId() { - return new SwMetadataCompositeKey(softwareModule, getKey()); - } - - public SoftwareModule getSoftwareModule() { - return softwareModule; - } - - public void setSoftwareModule(final SoftwareModule softwareModule) { - this.softwareModule = softwareModule; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((softwareModule == null) ? 0 : softwareModule.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - final SoftwareModuleMetadata other = (SoftwareModuleMetadata) obj; - if (softwareModule == null) { - if (other.softwareModule != null) { - return false; - } - } else if (!softwareModule.equals(other.softwareModule)) { - return false; - } - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleType.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleType.java index f31b74ff6..534d45fa3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleType.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleType.java @@ -8,110 +8,18 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Index; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface SoftwareModuleType extends NamedEntity { -/** - * Type of a software modules. - * - */ -@Entity -@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_prim", columnList = "tenant,id") }, uniqueConstraints = { - @UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_smt_type_key"), - @UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_smt_name") }) -public class SoftwareModuleType extends NamedEntity { - private static final long serialVersionUID = 1L; + String getKey(); - @Column(name = "type_key", nullable = false, length = 64) - private String key; + int getMaxAssignments(); - @Column(name = "max_ds_assignments", nullable = false) - private int maxAssignments; + boolean isDeleted(); - @Column(name = "colour", nullable = true, length = 16) - private String colour; + void setDeleted(boolean deleted); - @Column(name = "deleted") - private boolean deleted = false; + String getColour(); - /** - * Constructor. - * - * @param key - * of the type - * @param name - * of the type - * @param description - * of the type - * @param maxAssignments - * assignments to a DS - */ - public SoftwareModuleType(final String key, final String name, final String description, final int maxAssignments) { - this(key, name, description, maxAssignments, null); - } + void setColour(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 SoftwareModuleType(final String key, final String name, final String description, final int maxAssignments, - final String colour) { - super(); - this.key = key; - this.maxAssignments = maxAssignments; - setDescription(description); - setName(name); - this.colour = colour; - } - - /** - * Default Constructor. - */ - public SoftwareModuleType() { - super(); - } - - public String getKey() { - return key; - } - - public int getMaxAssignments() { - return maxAssignments; - } - - public boolean isDeleted() { - return deleted; - } - - public void setDeleted(final boolean deleted) { - this.deleted = deleted; - } - - public String getColour() { - return colour; - } - - public void setColour(final String colour) { - this.colour = colour; - } - - @Override - public String toString() { - return "SoftwareModuleType [key=" + key + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Tag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Tag.java index 23489ea12..236ff2d3d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Tag.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Tag.java @@ -8,52 +8,10 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +public interface Tag extends NamedEntity { -import org.springframework.hateoas.Identifiable; + String getColour(); -/** - * A Tag can be used as describing and organizational meta information for any - * kind of entity. - * - */ -@MappedSuperclass -public abstract class Tag extends NamedEntity implements Identifiable { - private static final long serialVersionUID = 1L; + void setColour(String colour); - @Column(name = "colour", nullable = true, length = 16) - private String colour; - - protected Tag() { - super(); - } - - /** - * Public constructor. - * - * @param name - * of the {@link Tag} - * @param description - * of the {@link Tag} - * @param colour - * of tag in UI - */ - public Tag(final String name, final String description, final String colour) { - super(name, description); - this.colour = colour; - } - - public String getColour() { - return colour; - } - - public void setColour(final String colour) { - this.colour = colour; - } - - @Override - public String toString() { - return "Tag [getOptLockRevision()=" + getOptLockRevision() + ", getId()=" + getId() + "]"; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index 5f37fb653..ba6f8c42c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -8,211 +8,47 @@ */ package org.eclipse.hawkbit.repository.model; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +public interface Target extends NamedEntity { -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.model.helper.SecurityChecker; -import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.springframework.data.domain.Persistable; + DistributionSet getAssignedDistributionSet(); -/** - *

- * The {@link Target} is the target of all provisioning operations. It contains - * the currently installed {@link DistributionSet} (i.e. current state). In - * addition it holds the target {@link DistributionSet} that has to be - * provisioned next (i.e. target state). - *

- * - *

- * {@link #getStatus()}s() shows if the {@link Target} is - * {@link TargetStatus#IN_SYNC} or a provisioning is - * {@link TargetStatus#PENDING} or the target is only - * {@link TargetStatus#REGISTERED}, i.e. a target {@link DistributionSet} . - *

- * - */ -@Entity -@Table(name = "sp_target", indexes = { - @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), - @Index(name = "sp_idx_target_02", columnList = "tenant,name"), - @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), - @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), - @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id")) -@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), - @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) -public class Target extends NamedEntity implements Persistable { - private static final long serialVersionUID = 1L; + String getControllerId(); - @Column(name = "controller_id", length = 64) - @Size(min = 1) - @NotNull - private String controllerId; + Set getTags(); - @Transient - private boolean entityNew = false; + void setAssignedDistributionSet(DistributionSet assignedDistributionSet); - @ManyToMany(targetEntity = TargetTag.class) - @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) - private Set tags = new HashSet<>(); + void setControllerId(String controllerId); - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REMOVE }) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) - private final List actions = new ArrayList<>(); + void setTags(Set tags); - @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = DistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) - private DistributionSet assignedDistributionSet; + List getActions(); - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = TargetInfo.class) - @PrimaryKeyJoinColumn - private TargetInfo targetInfo = null; - - /** - * the security token of the target which allows if enabled to authenticate - * with this security token. - */ - @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) - private String securityToken = null; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) - @JoinColumn(name = "target_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - */ - public Target(final String controllerId) { - this.controllerId = controllerId; - setName(controllerId); - securityToken = SecurityTokenGeneratorHolder.getInstance().generateToken(); - targetInfo = new TargetInfo(this); - } - - /** - * empty constructor for JPA. - */ - Target() { - controllerId = null; - securityToken = null; - } - - public DistributionSet getAssignedDistributionSet() { - return assignedDistributionSet; - } - - public String getControllerId() { - return controllerId; - } - - public Set getTags() { - return tags; - } - - public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { - this.assignedDistributionSet = assignedDistributionSet; - } - - public void setControllerId(final String controllerId) { - this.controllerId = controllerId; - } - - public void setTags(final Set tags) { - this.tags = tags; - } - - public List getActions() { - return actions; - } - - public TargetIdName getTargetIdName() { - return new TargetIdName(getId(), getControllerId(), getName()); - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } + TargetIdName getTargetIdName(); /** * @return the targetInfo */ - public TargetInfo getTargetInfo() { - return targetInfo; - } + TargetInfo getTargetInfo(); /** * @param targetInfo * the targetInfo to set */ - public void setTargetInfo(final TargetInfo targetInfo) { - this.targetInfo = targetInfo; - } + void setTargetInfo(TargetInfo targetInfo); /** * @return the securityToken */ - public String getSecurityToken() { - if (SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { - return securityToken; - } - return null; - } + String getSecurityToken(); /** * @param securityToken * the securityToken to set */ - public void setSecurityToken(final String securityToken) { - this.securityToken = securityToken; - } + void setSecurityToken(String securityToken); - @Override - public String toString() { - return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetFilterQuery.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetFilterQuery.java index 021b9ca7f..03508555a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetFilterQuery.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetFilterQuery.java @@ -8,51 +8,14 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Index; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface TargetFilterQuery extends TenantAwareBaseEntity { -/** - * Stored target filter. - * - */ -@Entity -@Table(name = "sp_target_filter_query", indexes = { - @Index(name = "sp_idx_target_filter_query_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_tenant_custom_filter_name")) -public class TargetFilterQuery extends TenantAwareBaseEntity { - private static final long serialVersionUID = 7493966984413479089L; + String getName(); - @Column(name = "name", length = 64) - private String name; + void setName(String name); - @Column(name = "query", length = 1024) - private String query; + String getQuery(); - public TargetFilterQuery() { - // Default constructor for JPA. - } + void setQuery(String query); - public TargetFilterQuery(final String name, final String query) { - this.name = name; - this.query = query; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public String getQuery() { - return query; - } - - public void setQuery(final String query) { - this.query = query; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index 00a501540..657b95c41 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -10,231 +10,30 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapKeyColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Transient; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo.PollStatus; -import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Persistable; +public interface TargetInfo extends Serializable { -/** - * A table which contains all the information inserted, updated by the - * controller itself. So this entity does not provide audit information because - * changes on this entity are mostly only done by controller requests. That's - * the reason that we store these information in a separated table so we don't - * modifying the {@link Target} itself when a controller reports it's - * {@link #lastTargetQuery} for example. - * - */ -@Table(name = "sp_target_info", indexes = { - @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) -@Entity -public class TargetInfo implements Persistable, Serializable { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); - - @Id - private Long targetId; - - @Transient - private boolean entityNew = false; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = Target.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) - @MapsId - private Target target; - - @Column(name = "address", length = 512) - private String address = null; - - @Column(name = "last_target_query") - private Long lastTargetQuery = null; - - @Column(name = "install_date") - private Long installationDate; - - @Column(name = "update_status", nullable = false, length = 255) - @Enumerated(EnumType.STRING) - private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; - - @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) - private DistributionSet installedDistributionSet; - - /** - * Read only on management API. Are commited by controller. - */ - @ElementCollection - @Column(name = "attribute_value", length = 128) - @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) - @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) - - private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); - - // set default request controller attributes to true, because we want to - // request them the first - // time - @Column(name = "request_controller_attributes", nullable = false) - private boolean requestControllerAttributes = true; - - /** - * Constructor for {@link TargetStatus}. - * - * @param target - * related to this status. - */ - public TargetInfo(final Target target) { - this.target = target; - targetId = target.getId(); - } - - TargetInfo() { - target = null; - targetId = null; - } - - @Override - public Long getId() { - return targetId; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } + Long getId(); /** * @return the ipAddress */ - public URI getAddress() { - if (address == null) { - return null; - } - try { - return URI.create(address); - } catch (final IllegalArgumentException e) { - LOG.warn("Invalid address provided. Cloud not be configured to URI", e); - return null; - } - } + URI getAddress(); - /** - * @param address - * the ipAddress to set - * - * @throws IllegalArgumentException - * If the given string violates RFC 2396 - */ - public void setAddress(final String address) { - // check if this is a real URI - if (address != null) { - URI.create(address); - } + Target getTarget(); - this.address = address; - } + Long getLastTargetQuery(); - public Long getTargetId() { - return targetId; - } + Map getControllerAttributes(); - public void setTargetId(final Long targetId) { - this.targetId = targetId; - } + Long getInstallationDate(); - public Target getTarget() { - return target; - } + TargetUpdateStatus getUpdateStatus(); - public void setTarget(final Target target) { - this.target = target; - } - - public Long getLastTargetQuery() { - return lastTargetQuery; - } - - public void setLastTargetQuery(final Long lastTargetQuery) { - this.lastTargetQuery = lastTargetQuery; - } - - public void setRequestControllerAttributes(final boolean requestControllerAttributes) { - this.requestControllerAttributes = requestControllerAttributes; - } - - public Map getControllerAttributes() { - return controllerAttributes; - } - - public boolean isRequestControllerAttributes() { - return requestControllerAttributes; - } - - public Long getInstallationDate() { - return installationDate; - } - - public void setInstallationDate(final Long installationDate) { - this.installationDate = installationDate; - } - - public TargetUpdateStatus getUpdateStatus() { - return updateStatus; - } - - public void setUpdateStatus(final TargetUpdateStatus updateStatus) { - this.updateStatus = updateStatus; - } - - public DistributionSet getInstalledDistributionSet() { - return installedDistributionSet; - } - - public void setInstalledDistributionSet(final DistributionSet installedDistributionSet) { - this.installedDistributionSet = installedDistributionSet; - } + DistributionSet getInstalledDistributionSet(); /** * @return the poll time which holds the last poll time of the target, the @@ -242,119 +41,6 @@ public class TargetInfo implements Persistable, Serializable { * {@link #lastTargetQuery} is not set e.g. the target never polled * before this method returns {@code null} */ - public PollStatus getPollStatus() { - if (lastTargetQuery == null) { - return null; - } - return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder - .getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration( - TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); - }); - } + PollStatus getPollStatus(); - /** - * The poll time object which holds all the necessary information around the - * target poll time, e.g. the last poll time, the next poll time and the - * overdue poll time. - * - */ - public static final class PollStatus { - private final LocalDateTime lastPollDate; - private final LocalDateTime nextPollDate; - private final LocalDateTime overdueDate; - private final LocalDateTime currentDate; - - private PollStatus(final LocalDateTime lastPollDate, final LocalDateTime nextPollDate, - final LocalDateTime overdueDate, final LocalDateTime currentDate) { - this.lastPollDate = lastPollDate; - this.nextPollDate = nextPollDate; - this.overdueDate = overdueDate; - this.currentDate = currentDate; - } - - /** - * calculates if the target poll time is overdue and the target has not - * been polled in the configured poll time interval. - * - * @return {@code true} if the current time is after the poll time - * overdue date otherwise {@code false}. - */ - public boolean isOverdue() { - return currentDate.isAfter(overdueDate); - } - - /** - * @return the lastPollDate - */ - public LocalDateTime getLastPollDate() { - return lastPollDate; - } - - public LocalDateTime getNextPollDate() { - return nextPollDate; - } - - public LocalDateTime getOverdueDate() { - return overdueDate; - } - - public LocalDateTime getCurrentDate() { - return currentDate; - } - - @Override - public String toString() { - return "PollTime [lastPollDate=" + lastPollDate + ", nextPollDate=" + nextPollDate + ", overdueDate=" - + overdueDate + ", currentDate=" + currentDate + "]"; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TargetInfo)) { - return false; - } - final TargetInfo other = (TargetInfo) obj; - if (target == null) { - if (other.target != null) { - return false; - } - } else if (!target.equals(other.target)) { - return false; - } - if (targetId == null) { - if (other.targetId != null) { - return false; - } - } else if (!targetId.equals(other.targetId)) { - return false; - } - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTag.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTag.java index 5a5a310d0..3abe3cdd5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTag.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTag.java @@ -10,78 +10,8 @@ package org.eclipse.hawkbit.repository.model; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Index; -import javax.persistence.ManyToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface TargetTag extends Tag { -/** - * A {@link TargetTag} is used to describe Target attributes and use them also - * for filtering the target list. - * - */ -@Entity -@Table(name = "sp_target_tag", indexes = { - @Index(name = "sp_idx_target_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_targ_tag")) -public class TargetTag extends Tag { - private static final long serialVersionUID = 1L; + List getAssignedToTargets(); - @ManyToMany(mappedBy = "tags", targetEntity = Target.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - /** - * Constructor. - * - * @param name - * of {@link TargetTag} - * @param description - * of {@link TargetTag} - * @param colour - * of {@link TargetTag} - */ - public TargetTag(final String name, final String description, final String colour) { - super(name, description, colour); - } - - /** - * Public constructor. - * - * @param name - * of the {@link TargetTag} - **/ - public TargetTag(final String name) { - super(name, null, null); - } - - TargetTag() { - super(); - } - - public List getAssignedToTargets() { - return assignedToTargets; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof TargetTag)) { - return false; - } - - return true; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetWithActionStatus.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetWithActionStatus.java index ec09da3d5..987b993e1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetWithActionStatus.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetWithActionStatus.java @@ -19,7 +19,7 @@ public class TargetWithActionStatus { private Target target; - private Status status = null;; + private Status status = null; public TargetWithActionStatus(final Target target) { this.target = target; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantAwareBaseEntity.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantAwareBaseEntity.java index d03a4938a..4b7bf861e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantAwareBaseEntity.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantAwareBaseEntity.java @@ -8,106 +8,8 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; -import javax.persistence.PrePersist; +public interface TenantAwareBaseEntity extends BaseEntity { -import org.eclipse.hawkbit.repository.exception.TenantNotExistException; -import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder; -import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder; -import org.eclipse.persistence.annotations.Multitenant; -import org.eclipse.persistence.annotations.MultitenantType; -import org.eclipse.persistence.annotations.TenantDiscriminatorColumn; + String getTenant(); -/** - * Holder of the base attributes common to all tenant aware entities. - * - */ -@MappedSuperclass -@TenantDiscriminatorColumn(name = "tenant", length = 40) -@Multitenant(MultitenantType.SINGLE_TABLE) -public abstract class TenantAwareBaseEntity extends BaseEntity { - private static final long serialVersionUID = 1L; - - @Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40) - private String tenant; - - /** - * Default constructor needed for JPA entities. - */ - public TenantAwareBaseEntity() { - // Default constructor needed for JPA entities. - } - - /** - * PrePersist listener method for all {@link TenantAwareBaseEntity} - * entities. - */ - @PrePersist - public void prePersist() { - // before persisting the entity check the current ID of the tenant by - // using the TenantAware - // service - final String currentTenant = SystemManagementHolder.getInstance().currentTenant(); - if (currentTenant == null) { - throw new TenantNotExistException("Tenant " - + TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant() - + " does not exists, cannot create entity " + this.getClass() + " with id " + super.getId()); - } - setTenant(currentTenant.toUpperCase()); - } - - public String getTenant() { - return tenant; - } - - public void setTenant(final String tenant) { - this.tenant = tenant; - } - - @Override - public String toString() { - return "BaseEntity [id=" + super.getId() + "]"; - } - - /** - * Tenant aware entities extend the equals/hashcode strategy with the tenant - * name. That would allow for instance in a multi-schema based data - * separation setup to have the same primary key for different entities of - * different tenants. - * - * @see org.eclipse.hawkbit.repository.model.BaseEntity#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (tenant == null ? 0 : tenant.hashCode()); - return result; - } - - /** - * Tenant aware entities extend the equals/hashcode strategy with the tenant - * name. That would allow for instance in a multi-schema based data - * separation setup to have the same primary key for different entities of - * different tenants. - * - * @see org.eclipse.hawkbit.repository.model.BaseEntity#equals(java.lang.Object) - */ - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - final TenantAwareBaseEntity other = (TenantAwareBaseEntity) obj; - if (tenant == null) { - if (other.tenant != null) { - return false; - } - } else if (!tenant.equals(other.tenant)) { - return false; - } - return true; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfiguration.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfiguration.java index 5a938563b..78201410b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfiguration.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfiguration.java @@ -8,64 +8,14 @@ */ package org.eclipse.hawkbit.repository.model; -import java.io.Serializable; +public interface TenantConfiguration extends TenantAwareBaseEntity { -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; + String getKey(); -/** - * A JPA entity which stores the tenant specific configuration. - * - */ -@Entity -@Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key", - "tenant" }, name = "uk_tenant_key")) -public class TenantConfiguration extends TenantAwareBaseEntity implements Serializable { - private static final long serialVersionUID = 1L; + void setKey(String key); - @Column(name = "conf_key", length = 128) - private String key; + String getValue(); - @Column(name = "conf_value", length = 512) - @Basic - private String value; + void setValue(String value); - /** - * JPA default constructor. - */ - public TenantConfiguration() { - // JPA default constructor. - } - - /** - * @param key - * the key of this configuration - * @param value - * the value of this configuration - */ - public TenantConfiguration(final String key, final String value) { - this.key = key; - this.value = value; - - } - - public String getKey() { - return key; - } - - public void setKey(final String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(final String value) { - this.value = value; - } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index a9572c21c..38f9ddbb3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -8,93 +8,12 @@ */ package org.eclipse.hawkbit.repository.model; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +public interface TenantMetaData extends BaseEntity { -/** - * Tenant entity with meta data that is configured globally for the entire - * tenant. This entity is not tenant aware to allow the system to access it - * through the {@link EntityManager} even before the actual tenant exists. - * - * Entities owned by the tenant are based on {@link TenantAwareBaseEntity}. - * - */ -@Table(name = "sp_tenant", indexes = { - @Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = { - @UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") }) -@Entity -public class TenantMetaData extends BaseEntity { - private static final long serialVersionUID = 1L; + DistributionSetType getDefaultDsType(); - @Column(name = "tenant", nullable = false, length = 40) - private String tenant; + void setDefaultDsType(DistributionSetType defaultDsType); - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type")) - private DistributionSetType defaultDsType; + String getTenant(); - /** - * Default constructor needed for JPA entities. - */ - public TenantMetaData() { - // Default constructor needed for JPA entities. - } - - /** - * Standard constructor. - * - * @param defaultDsType - * of this tenant - * @param tenant - */ - public TenantMetaData(final DistributionSetType defaultDsType, final String tenant) { - super(); - this.defaultDsType = defaultDsType; - this.tenant = tenant; - } - - public DistributionSetType getDefaultDsType() { - return defaultDsType; - } - - public void setDefaultDsType(final DistributionSetType defaultDsType) { - this.defaultDsType = defaultDsType; - } - - public String getTenant() { - return tenant; - } - - public void setTenant(final String tenant) { - this.tenant = tenant; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + this.getClass().getName().hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof TenantMetaData)) { - return false; - } - - return true; - } -} +} \ No newline at end of file diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/PauseRolloutGroupAction.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/PauseRolloutGroupAction.java index 3af269819..d80fc5a7b 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/PauseRolloutGroupAction.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/PauseRolloutGroupAction.java @@ -8,13 +8,12 @@ */ package org.eclipse.hawkbit.rollout.condition; -import java.util.concurrent.Callable; - import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.jpa.RolloutGroupRepository; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -42,14 +41,11 @@ public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator { @Override public void eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { - systemSecurityContext.runAsSystem(new Callable() { - @Override - public Void call() throws Exception { - rolloutGroup.setStatus(RolloutGroupStatus.ERROR); - rolloutGroupRepository.save(rolloutGroup); - rolloutManagement.pauseRollout(rollout); - return null; - } + systemSecurityContext.runAsSystem(() -> { + rolloutGroup.setStatus(RolloutGroupStatus.ERROR); + rolloutGroupRepository.save((JpaRolloutGroup) rolloutGroup); + rolloutManagement.pauseRollout(rollout); + return null; }); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java index 224901053..223f20125 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java @@ -12,10 +12,11 @@ import java.util.List; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.jpa.RolloutGroupRepository; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,7 +69,7 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi final RolloutGroup nextGroup = action.getRolloutGroup(); logger.debug("Rolloutgroup {} is now running", nextGroup); nextGroup.setStatus(RolloutGroupStatus.RUNNING); - rolloutGroupRepository.save(nextGroup); + rolloutGroupRepository.save((JpaRolloutGroup) nextGroup); }); } else { logger.info("No actions to start for next rolloutgroup of parent {}", rolloutGroup); @@ -76,8 +77,8 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi // e.g. if targets has been deleted after the group has been // scheduled. If the group is empty now, we just finish the group if // there are not actions available for this group. - final List findByRolloutGroupParent = rolloutGroupRepository - .findByParentAndStatus(rolloutGroup, RolloutGroupStatus.SCHEDULED); + final List findByRolloutGroupParent = rolloutGroupRepository + .findByParentAndStatus((JpaRolloutGroup) rolloutGroup, RolloutGroupStatus.SCHEDULED); findByRolloutGroupParent.forEach(nextGroup -> { logger.debug("Rolloutgroup {} is finished, starting next group", nextGroup); nextGroup.setStatus(RolloutGroupStatus.FINISHED); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/ThresholdRolloutGroupErrorCondition.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/ThresholdRolloutGroupErrorCondition.java index e38cb0f16..32e9725f8 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/ThresholdRolloutGroupErrorCondition.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/rollout/condition/ThresholdRolloutGroupErrorCondition.java @@ -9,6 +9,8 @@ package org.eclipse.hawkbit.rollout.condition; import org.eclipse.hawkbit.repository.jpa.ActionRepository; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; @@ -30,7 +32,8 @@ public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditio @Override public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { - final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup(rollout, rolloutGroup); + final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup((JpaRollout) rollout, + (JpaRolloutGroup) rolloutGroup); final Long error = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(), rolloutGroup.getId(), Action.Status.ERROR); try { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestDataUtil.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestDataUtil.java index 1787d29e4..09959790f 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestDataUtil.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestDataUtil.java @@ -20,6 +20,14 @@ import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.jpa.model.JpaArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetType; @@ -42,10 +50,10 @@ import net._01001111.text.LoremIpsum; public class TestDataUtil { private static final LoremIpsum LOREM = new LoremIpsum(); - public static List generateDistributionSets(final String suffix, final int number, + public static List generateDistributionSets(final String suffix, final int number, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) { - final List sets = new ArrayList(); + final List sets = new ArrayList<>(); for (int i = 0; i < number; i++) { sets.add(generateDistributionSet(suffix, "v1." + i, softwareManagement, distributionSetManagement, false)); } @@ -56,32 +64,32 @@ public class TestDataUtil { public static DistributionSet generateDistributionSetWithNoSoftwareModules(final String name, final String version, final DistributionSetManagement distributionSetManagement) { - final DistributionSet dis = new DistributionSet(); + final DistributionSet dis = new JpaDistributionSet(); dis.setName(name); dis.setVersion(version); dis.setDescription("Test describtion for " + name); return distributionSetManagement.createDistributionSet(dis); } - public static List generateDistributionSets(final int number, + public static List generateDistributionSets(final int number, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) { return generateDistributionSets("", number, softwareManagement, distributionSetManagement); } - public static DistributionSet generateDistributionSet(final String suffix, final String version, + public static JpaDistributionSet generateDistributionSet(final String suffix, final String version, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement, final boolean isRequiredMigrationStep) { - final SoftwareModule ah = softwareManagement.createSoftwareModule(new SoftwareModule( + final SoftwareModule ah = softwareManagement.createSoftwareModule(new JpaSoftwareModule( findOrCreateSoftwareModuleType(softwareManagement, "application"), suffix + "application", version + "." + new Random().nextInt(100), LOREM.words(20), suffix + " vendor Limited, California")); - final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "runtime"), + final SoftwareModule jvm = softwareManagement.createSoftwareModule( + new JpaSoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "runtime"), suffix + "app runtime", version + "." + new Random().nextInt(100), LOREM.words(20), suffix + " vendor GmbH, Stuttgart, Germany")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "os"), + .createSoftwareModule(new JpaSoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "os"), suffix + " Firmware", version + "." + new Random().nextInt(100), LOREM.words(20), suffix + " vendor Limited Inc, California")); @@ -92,7 +100,7 @@ public class TestDataUtil { opt.add(findOrCreateSoftwareModuleType(softwareManagement, "application")); opt.add(findOrCreateSoftwareModuleType(softwareManagement, "runtime")); - return distributionSetManagement.createDistributionSet( + return (JpaDistributionSet) distributionSetManagement.createDistributionSet( buildDistributionSet(suffix != null && suffix.length() > 0 ? suffix : "DS", version, findOrCreateDistributionSetType(distributionSetManagement, "ecl_os_app_jvm", "OS mandatory App/JVM optional", mand, opt), @@ -126,7 +134,7 @@ public class TestDataUtil { public static List generateTargets(final int start, final int number, final String prefix) { final List targets = new ArrayList<>(); for (int i = start; i < start + number; i++) { - targets.add(new Target(prefix + i)); + targets.add(new JpaTarget(prefix + i)); } return targets; @@ -136,7 +144,7 @@ public class TestDataUtil { final List result = new ArrayList<>(); for (int i = 0; i < number; i++) { - result.add(new TargetTag("tag" + i, "tagdesc" + i, "" + i)); + result.add(new JpaTargetTag("tag" + i, "tagdesc" + i, "" + i)); } return result; @@ -146,30 +154,31 @@ public class TestDataUtil { final List result = new ArrayList<>(); for (int i = 0; i < number; i++) { - result.add(new DistributionSetTag("tag" + i, "tagdesc" + i, "" + i)); + result.add(new JpaDistributionSetTag("tag" + i, "tagdesc" + i, "" + i)); } return result; } - public static DistributionSet generateDistributionSet(final String suffix, + public static JpaDistributionSet generateDistributionSet(final String suffix, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement, final boolean isRequiredMigrationStep) { return generateDistributionSet(suffix, "v1.0", softwareManagement, distributionSetManagement, isRequiredMigrationStep); } - public static DistributionSet generateDistributionSet(final String suffix, + public static JpaDistributionSet generateDistributionSet(final String suffix, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) { return generateDistributionSet(suffix, "v1.0", softwareManagement, distributionSetManagement, false); } - public static List generateArtifacts( - final ArtifactManagement artifactManagement, final Long moduleId) { - final List artifacts = new ArrayList<>(); + public static List generateArtifacts(final ArtifactManagement artifactManagement, + final Long moduleId) { + final List artifacts = new ArrayList<>(); for (int i = 0; i < 3; i++) { final InputStream stubInputStream = IOUtils.toInputStream("some test data" + i); - artifacts.add(artifactManagement.createLocalArtifact(stubInputStream, moduleId, "filename" + i, false)); + artifacts.add((JpaArtifact) artifactManagement.createLocalArtifact(stubInputStream, moduleId, + "filename" + i, false)); } @@ -178,7 +187,7 @@ public class TestDataUtil { public static Target createTarget(final TargetManagement targetManagement) { final String targetExist = "targetExist"; - final Target target = new Target(targetExist); + final Target target = new JpaTarget(targetExist); targetManagement.createTarget(target); return target; } @@ -196,7 +205,7 @@ public class TestDataUtil { if (findSoftwareModuleTypeByKey != null) { return findSoftwareModuleTypeByKey; } - return softwareManagement.createSoftwareModuleType(new SoftwareModuleType(softwareModuleType, + return softwareManagement.createSoftwareModuleType(new JpaSoftwareModuleType(softwareModuleType, softwareModuleType, "Standard type " + softwareManagement, 1)); } @@ -210,7 +219,8 @@ public class TestDataUtil { return findDistributionSetTypeByname; } - final DistributionSetType type = new DistributionSetType(dsTypeKey, dsTypeName, "Standard type" + dsTypeName); + final DistributionSetType type = new JpaDistributionSetType(dsTypeKey, dsTypeName, + "Standard type" + dsTypeName); mandatory.forEach(entry -> type.addMandatoryModuleType(entry)); optional.forEach(entry -> type.addOptionalModuleType(entry)); @@ -280,7 +290,7 @@ public class TestDataUtil { * @return the created {@link Target} */ public static Target buildTargetFixture(final String ctrlID, final String description, final TargetTag[] tags) { - final Target target = new Target(ctrlID); + final Target target = new JpaTarget(ctrlID); target.setName("Prov.Target ".concat(ctrlID)); target.setDescription(description); if (tags != null && tags.length > 0) { @@ -322,7 +332,7 @@ public class TestDataUtil { public static DistributionSet buildDistributionSet(final String name, final String version, final DistributionSetType type, final SoftwareModule os, final SoftwareModule jvm, final SoftwareModule agentHub) { - final DistributionSet distributionSet = new DistributionSet(name, version, null, type, + final DistributionSet distributionSet = new JpaDistributionSet(name, version, null, type, Lists.newArrayList(os, jvm, agentHub)); distributionSet.setDescription( String.format("description of DistributionSet; name = '%s', version = '%s'", name, version)); @@ -361,6 +371,6 @@ public class TestDataUtil { * @return the {@link TargetTag} */ public static TargetTag buildTargetTagFixture(final String tagName) { - return new TargetTag(tagName); + return new JpaTargetTag(tagName); } } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ActionTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ActionTest.java index 937a544a7..4fbd46a5c 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ActionTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ActionTest.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.api.Assertions.assertThat; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.junit.Test; @@ -30,7 +31,7 @@ public class ActionTest { // current time + 1 seconds final long sleepTime = 1000; final long timeForceTimeAt = System.currentTimeMillis() + sleepTime; - final Action timeforcedAction = new Action(); + final Action timeforcedAction = new JpaAction(); timeforcedAction.setActionType(ActionType.TIMEFORCED); timeforcedAction.setForcedTime(timeForceTimeAt); assertThat(timeforcedAction.isForce()).isFalse(); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementNoMongoDbTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementNoMongoDbTest.java index 30f4093c2..ee1cb3acd 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementNoMongoDbTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementNoMongoDbTest.java @@ -16,7 +16,7 @@ import java.io.IOException; import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; -import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.junit.BeforeClass; import org.junit.Test; @@ -42,7 +42,7 @@ public class ArtifactManagementNoMongoDbTest extends AbstractIntegrationTest { @Test @Description("Checks if the expected ArtifactUploadFailedException is thrown in case of MongoDB down") public void createLocalArtifactWithMongoDbDown() throws IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java index 7c801a571..7b704af12 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java @@ -27,8 +27,11 @@ import org.eclipse.hawkbit.WithUser; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.Artifact; -import org.eclipse.hawkbit.repository.model.ExternalArtifact; import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -70,15 +73,15 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(softwareModuleRepository.findAll()).hasSize(0); assertThat(artifactRepository.findAll()).hasSize(0); - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); - SoftwareModule sm2 = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", + JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", "version 2", null, null); sm2 = softwareModuleRepository.save(sm2); - SoftwareModule sm3 = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 3", + JpaSoftwareModule sm3 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 3", "version 3", null, null); sm3 = softwareModuleRepository.save(sm3); @@ -96,11 +99,11 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(result).isInstanceOf(LocalArtifact.class); assertThat(result.getSoftwareModule().getId()).isEqualTo(sm.getId()); assertThat(result2.getSoftwareModule().getId()).isEqualTo(sm2.getId()); - assertThat(((LocalArtifact) result).getFilename()).isEqualTo("file1"); - assertThat(((LocalArtifact) result).getGridFsFileName()).isNotNull(); + assertThat(((JpaLocalArtifact) result).getFilename()).isEqualTo("file1"); + assertThat(((JpaLocalArtifact) result).getGridFsFileName()).isNotNull(); assertThat(result).isNotEqualTo(result2); - assertThat(((LocalArtifact) result).getGridFsFileName()) - .isEqualTo(((LocalArtifact) result2).getGridFsFileName()); + assertThat(((JpaLocalArtifact) result).getGridFsFileName()) + .isEqualTo(((JpaLocalArtifact) result2).getGridFsFileName()); assertThat(artifactManagement.findLocalArtifactByFilename("file1").get(0).getSha1Hash()) .isEqualTo(HashGeneratorUtils.generateSHA1(random)); @@ -116,7 +119,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Tests hard delete directly on repository.") public void hardDeleteSoftwareModule() throws NoSuchAlgorithmException, IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); @@ -137,18 +140,19 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Tests the creation of an external artifact metadata element.") public void createExternalArtifact() { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); - SoftwareModule sm2 = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", + JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", "version 2", null, null); sm2 = softwareModuleRepository.save(sm2); final ExternalArtifactProvider provider = artifactManagement.createExternalArtifactProvider("provider X", null, "https://fhghdfjgh", "/{version}/"); - ExternalArtifact result = artifactManagement.createExternalArtifact(provider, null, sm.getId()); + JpaExternalArtifact result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider, null, + sm.getId()); assertNotNull("The result of an external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1); @@ -156,7 +160,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/{version}/"); assertThat(result.getExternalArtifactProvider()).isEqualTo(provider); - result = artifactManagement.createExternalArtifact(provider, "/test", sm2.getId()); + result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider, "/test", sm2.getId()); assertNotNull("The newly created external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(2); assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/test"); @@ -168,14 +172,15 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { public void deleteExternalArtifact() { assertThat(artifactRepository.findAll()).isEmpty(); - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); - final ExternalArtifactProvider provider = artifactManagement.createExternalArtifactProvider("provider X", null, - "https://fhghdfjgh", "/{version}/"); + final JpaExternalArtifactProvider provider = (JpaExternalArtifactProvider) artifactManagement + .createExternalArtifactProvider("provider X", null, "https://fhghdfjgh", "/{version}/"); - final ExternalArtifact result = artifactManagement.createExternalArtifact(provider, null, sm.getId()); + final JpaExternalArtifact result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider, + null, sm.getId()); assertNotNull("The newly created external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1); @@ -194,11 +199,11 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Tests the deletion of a local artifact including metadata.") public void deleteLocalArtifact() throws NoSuchAlgorithmException, IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); - SoftwareModule sm2 = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", + JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", "version 2", null, null); sm2 = softwareModuleRepository.save(sm2); @@ -213,26 +218,25 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(result.getId()).isNotNull(); assertThat(result2.getId()).isNotNull(); - assertThat(((LocalArtifact) result).getGridFsFileName()) - .isNotEqualTo(((LocalArtifact) result2).getGridFsFileName()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) + assertThat(((JpaLocalArtifact) result).getGridFsFileName()) + .isNotEqualTo(((JpaLocalArtifact) result2).getGridFsFileName()); + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))) .isNotNull(); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result2).getGridFsFileName())))) + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName())))) .isNotNull(); artifactManagement.deleteLocalArtifact(result.getId()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) - .isNull(); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result2).getGridFsFileName())))) + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))).isNull(); + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName())))) .isNotNull(); artifactManagement.deleteLocalArtifact(result2.getId()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result2).getGridFsFileName())))) + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName())))) .isNull(); assertThat(artifactRepository.findAll()).hasSize(0); @@ -245,7 +249,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(artifactRepository.findAll()).isEmpty(); // prepare test - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); @@ -272,11 +276,11 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Test the deletion of an artifact metadata where the binary is still linked to another " + "metadata element. The expected result is that the metadata is deleted but the binary kept.") public void deleteDuplicateArtifacts() throws NoSuchAlgorithmException, IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); - SoftwareModule sm2 = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", + JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2", "version 2", null, null); sm2 = softwareModuleRepository.save(sm2); @@ -290,21 +294,20 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(artifactRepository.findAll()).hasSize(2); assertThat(result.getId()).isNotNull(); assertThat(result2.getId()).isNotNull(); - assertThat(((LocalArtifact) result).getGridFsFileName()) - .isEqualTo(((LocalArtifact) result2).getGridFsFileName()); + assertThat(((JpaLocalArtifact) result).getGridFsFileName()) + .isEqualTo(((JpaLocalArtifact) result2).getGridFsFileName()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))) .isNotNull(); artifactManagement.deleteLocalArtifact(result.getId()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))) .isNotNull(); artifactManagement.deleteLocalArtifact(result2.getId()); - assertThat(operations.findOne( - new Query().addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) - .isNull(); + assertThat(operations.findOne(new Query() + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))).isNull(); } /** @@ -318,7 +321,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Loads an artifact based on given ID.") public void findArtifact() throws NoSuchAlgorithmException, IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + SoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -339,7 +342,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Loads an artifact binary based on given ID.") public void loadStreamOfLocalArtifact() throws NoSuchAlgorithmException, IOException { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + SoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -357,7 +360,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown.") public void loadLocalArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() { try { - artifactManagement.loadLocalArtifactBinary(new LocalArtifact()); + artifactManagement.loadLocalArtifactBinary(new JpaLocalArtifact()); fail("Should not have worked with missing permission."); } catch (final InsufficientPermissionException e) { @@ -367,10 +370,10 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Searches an artifact through the relations of a software module.") public void findLocalArtifactBySoftwareModule() { - SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); + SoftwareModule sm = new JpaSoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); - SoftwareModule sm2 = new SoftwareModule(osType, "name 2", "version 2", null, null); + SoftwareModule sm2 = new JpaSoftwareModule(osType, "name 2", "version 2", null, null); sm2 = softwareManagement.createSoftwareModule(sm2); assertThat(artifactManagement.findLocalArtifactBySoftwareModule(pageReq, sm.getId())).isEmpty(); @@ -384,7 +387,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Searches an artifact through the relations of a software module and the filename.") public void findByFilenameAndSoftwareModule() { - SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); + SoftwareModule sm = new JpaSoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); assertThat(artifactManagement.findByFilenameAndSoftwareModule("file1", sm.getId())).isEmpty(); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java index 4c0bc1c19..76286d217 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java @@ -19,6 +19,8 @@ import javax.validation.ConstraintViolationException; import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -38,7 +40,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest { @Test @Description("Controller adds a new action status.") public void controllerAddsActionStatus() { - final Target target = new Target("4712"); + final Target target = new JpaTarget("4712"); final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement); Target savedTarget = targetManagement.createTarget(target); @@ -54,7 +56,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest { assertThat(targetManagement.findTargetByControllerID(savedTarget.getControllerId()).getTargetInfo() .getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING); - ActionStatus actionStatusMessage = new ActionStatus(savedAction, Action.Status.RUNNING, + ActionStatus actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.RUNNING, System.currentTimeMillis()); actionStatusMessage.addMessage("foobar"); savedAction.setStatus(Status.RUNNING); @@ -62,7 +64,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest { assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.PENDING); - actionStatusMessage = new ActionStatus(savedAction, Action.Status.FINISHED, System.currentTimeMillis()); + actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.FINISHED, System.currentTimeMillis()); actionStatusMessage.addMessage(RandomStringUtils.randomAscii(512)); savedAction.setStatus(Status.FINISHED); controllerManagament.addUpdateActionStatus(actionStatusMessage); @@ -98,7 +100,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest { public void tryToFinishUpdateProcessMoreThenOnce() { // mock - final Target target = new Target("Rabbit"); + final Target target = new JpaTarget("Rabbit"); final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement); Target savedTarget = targetManagement.createTarget(target); @@ -108,21 +110,21 @@ public class ControllerManagementTest extends AbstractIntegrationTest { Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0); // test and verify - final ActionStatus actionStatusMessage = new ActionStatus(savedAction, Action.Status.RUNNING, + final ActionStatus actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.RUNNING, System.currentTimeMillis()); actionStatusMessage.addMessage("running"); savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage); assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.PENDING); - final ActionStatus actionStatusMessage2 = new ActionStatus(savedAction, Action.Status.ERROR, + final ActionStatus actionStatusMessage2 = new JpaActionStatus(savedAction, Action.Status.ERROR, System.currentTimeMillis()); actionStatusMessage2.addMessage("error"); savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage2); assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.ERROR); - final ActionStatus actionStatusMessage3 = new ActionStatus(savedAction, Action.Status.FINISHED, + final ActionStatus actionStatusMessage3 = new JpaActionStatus(savedAction, Action.Status.FINISHED, System.currentTimeMillis()); actionStatusMessage3.addMessage("finish"); controllerManagament.addUpdateActionStatus(actionStatusMessage3); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java index 6a6d92bf0..50b929622 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java @@ -13,6 +13,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -28,6 +29,13 @@ import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; import org.eclipse.hawkbit.repository.jpa.TargetRepository; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; @@ -91,8 +99,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final Action action = deploymentManagement.findActionWithDetails( deploymentManagement.assignDistributionSet(testDs, testTarget).getActions().get(0)); // save 2 action status - actionStatusRepository.save(new ActionStatus(action, Status.RETRIEVED, System.currentTimeMillis())); - actionStatusRepository.save(new ActionStatus(action, Status.RUNNING, System.currentTimeMillis())); + actionStatusRepository.save(new JpaActionStatus(action, Status.RETRIEVED, System.currentTimeMillis())); + actionStatusRepository.save(new JpaActionStatus(action, Status.RUNNING, System.currentTimeMillis())); final List findActionsWithStatusCountByTarget = deploymentManagement .findActionsWithStatusCountByTargetOrderByIdDesc(testTarget.get(0)); @@ -112,7 +120,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { } // not exists assignDS.add(Long.valueOf(100)); - final DistributionSetTag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("Tag1")); + final DistributionSetTag tag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag1")); final List assignedDS = distributionSetManagement.assignTag(assignDS, tag); assertThat(assignedDS.size()).as("assigned ds has wrong size").isEqualTo(4); @@ -171,17 +179,17 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { + "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.") public void manualCancelWithMultipleAssignmentsCancelLastOneFirst() { - Target target = new Target("4712"); - final DistributionSet dsFirst = TestDataUtil.generateDistributionSet("", softwareManagement, + JpaTarget target = new JpaTarget("4712"); + final JpaDistributionSet dsFirst = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement, true); dsFirst.setRequiredMigrationStep(true); - final DistributionSet dsSecond = TestDataUtil.generateDistributionSet("2", softwareManagement, + final JpaDistributionSet dsSecond = TestDataUtil.generateDistributionSet("2", softwareManagement, distributionSetManagement, true); - final DistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, + final JpaDistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, distributionSetManagement, true); - target.getTargetInfo().setInstalledDistributionSet(dsInstalled); - target = targetManagement.createTarget(target); + ((JpaTargetInfo) target.getTargetInfo()).setInstalledDistributionSet(dsInstalled); + target = (JpaTarget) targetManagement.createTarget(target); // check initial status assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus()) @@ -201,7 +209,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // confirm cancellation secondAction.setStatus(Status.CANCELED); controllerManagement - .addCancelActionStatus(new ActionStatus(secondAction, Status.CANCELED, System.currentTimeMillis())); + .addCancelActionStatus(new JpaActionStatus(secondAction, Status.CANCELED, System.currentTimeMillis())); assertThat(actionStatusRepository.findAll()).as("wrong size of actions status").hasSize(4); assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()).as("wrong ds") .isEqualTo(dsFirst); @@ -215,7 +223,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // confirm cancellation firstAction.setStatus(Status.CANCELED); controllerManagement - .addCancelActionStatus(new ActionStatus(firstAction, Status.CANCELED, System.currentTimeMillis())); + .addCancelActionStatus(new JpaActionStatus(firstAction, Status.CANCELED, System.currentTimeMillis())); assertThat(actionStatusRepository.findAll()).as("wrong size of action status").hasSize(6); assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()) .as("wrong assigned ds").isEqualTo(dsInstalled); @@ -228,17 +236,17 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { + "actions after canceling the first active action the system switched to second one. After canceling this one " + "also the target goes back to IN_SYNC as no open action is left.") public void manualCancelWithMultipleAssignmentsCancelMiddleOneFirst() { - Target target = new Target("4712"); - final DistributionSet dsFirst = TestDataUtil.generateDistributionSet("", softwareManagement, + JpaTarget target = new JpaTarget("4712"); + final JpaDistributionSet dsFirst = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement, true); dsFirst.setRequiredMigrationStep(true); - final DistributionSet dsSecond = TestDataUtil.generateDistributionSet("2", softwareManagement, + final JpaDistributionSet dsSecond = TestDataUtil.generateDistributionSet("2", softwareManagement, distributionSetManagement, true); - final DistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, + final JpaDistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, distributionSetManagement, true); - target.getTargetInfo().setInstalledDistributionSet(dsInstalled); - target = targetManagement.createTarget(target); + ((JpaTargetInfo) target.getTargetInfo()).setInstalledDistributionSet(dsInstalled); + target = (JpaTarget) targetManagement.createTarget(target); // check initial status assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus()) @@ -258,7 +266,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { firstAction = deploymentManagement.findActionWithDetails(firstAction.getId()); firstAction.setStatus(Status.CANCELED); controllerManagement - .addCancelActionStatus(new ActionStatus(firstAction, Status.CANCELED, System.currentTimeMillis())); + .addCancelActionStatus(new JpaActionStatus(firstAction, Status.CANCELED, System.currentTimeMillis())); assertThat(actionStatusRepository.findAll()).as("wrong size of action status").hasSize(4); assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()) .as("wrong assigned ds").isEqualTo(dsSecond); @@ -275,7 +283,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // confirm cancellation secondAction.setStatus(Status.CANCELED); controllerManagement - .addCancelActionStatus(new ActionStatus(secondAction, Status.CANCELED, System.currentTimeMillis())); + .addCancelActionStatus(new JpaActionStatus(secondAction, Status.CANCELED, System.currentTimeMillis())); // cancelled success -> back to dsInstalled assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()) .as("wrong installed ds").isEqualTo(dsInstalled); @@ -287,15 +295,15 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { @Description("Force Quit an Assignment. Expected behaviour is that the action is canceled and is marked as deleted. The assigned Software module") public void forceQuitSetActionToInactive() throws InterruptedException { - Target target = new Target("4712"); - final DistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, + JpaTarget target = new JpaTarget("4712"); + final JpaDistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, distributionSetManagement, true); - target.getTargetInfo().setInstalledDistributionSet(dsInstalled); - target = targetManagement.createTarget(target); + ((JpaTargetInfo) target.getTargetInfo()).setInstalledDistributionSet(dsInstalled); + target = (JpaTarget) targetManagement.createTarget(target); - final DistributionSet ds = TestDataUtil - .generateDistributionSet("newDS", softwareManagement, distributionSetManagement, true) - .setRequiredMigrationStep(true); + final JpaDistributionSet ds = TestDataUtil.generateDistributionSet("newDS", softwareManagement, + distributionSetManagement, true); + ds.setRequiredMigrationStep(true); // verify initial status assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus()) @@ -307,7 +315,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { assertThat(actionRepository.findAll()).as("wrong size of action").hasSize(1); assertThat(actionStatusRepository.findAll()).as("wrong size of action status").hasSize(1); - target = targetManagement.findTargetByControllerID(target.getControllerId()); + target = (JpaTarget) targetManagement.findTargetByControllerID(target.getControllerId()); // force quit assignment deploymentManagement.cancelAction(assigningAction, target); @@ -329,15 +337,15 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { @Description("Force Quit an not canceled Assignment. Expected behaviour is that the action can not be force quit and there is thrown an exception.") public void forceQuitNotAllowedThrowsException() { - Target target = new Target("4712"); - final DistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, + JpaTarget target = new JpaTarget("4712"); + final JpaDistributionSet dsInstalled = TestDataUtil.generateDistributionSet("installed", softwareManagement, distributionSetManagement, true); - target.getTargetInfo().setInstalledDistributionSet(dsInstalled); - target = targetManagement.createTarget(target); + ((JpaTargetInfo) target.getTargetInfo()).setInstalledDistributionSet(dsInstalled); + target = (JpaTarget) targetManagement.createTarget(target); - final DistributionSet ds = TestDataUtil - .generateDistributionSet("newDS", softwareManagement, distributionSetManagement, true) - .setRequiredMigrationStep(true); + final JpaDistributionSet ds = TestDataUtil.generateDistributionSet("newDS", softwareManagement, + distributionSetManagement, true); + ds.setRequiredMigrationStep(true); // verify initial status assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus()) @@ -357,7 +365,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { } } - private Action assignSet(final Target target, final DistributionSet ds) { + private Action assignSet(final JpaTarget target, final JpaDistributionSet ds) { deploymentManagement.assignDistributionSet(ds.getId(), new String[] { target.getControllerId() }); assertThat( targetManagement.findTargetByControllerID(target.getControllerId()).getTargetInfo().getUpdateStatus()) @@ -442,14 +450,14 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final List targets = targetManagement.createTargets(TestDataUtil.generateTargets(10)); final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, "")); final DistributionSet incomplete = distributionSetManagement.createDistributionSet( - new DistributionSet("incomplete", "v1", "", standardDsType, Lists.newArrayList(ah, jvm))); + new JpaDistributionSet("incomplete", "v1", "", standardDsType, Lists.newArrayList(ah, jvm))); try { deploymentManagement.assignDistributionSet(incomplete, targets); @@ -507,7 +515,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final List savedDeployedTargets = deploymentResult.getDeployedTargets(); // retrieving all Actions created by the assignDistributionSet call - final Page page = actionRepository.findAll(pageReq); + final Page page = actionRepository.findAll(pageReq); // and verify the number assertThat(page.getTotalElements()).as("wrong size of actions") .isEqualTo(noOfDeployedTargets * noOfDistributionSets); @@ -515,10 +523,10 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // only records retrieved from the DB can be evaluated to be sure that // all fields are // populated; - final Iterable allFoundTargets = targetRepository.findAll(); + final Iterable allFoundTargets = targetRepository.findAll(); - final Iterable deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs); - final Iterable undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs); + final Iterable deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs); + final Iterable undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs); // test that number of Targets assertThat(allFoundTargets.spliterator().getExactSizeIfKnown()).as("number of target is wrong") @@ -532,10 +540,12 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // test the content of different lists assertThat(allFoundTargets).as("content of founded target is wrong").containsAll(deployedTargetsFromDB) .containsAll(undeployedTargetsFromDB); - assertThat(deployedTargetsFromDB).as("content of deployed target is wrong").containsAll(savedDeployedTargets) - .doesNotContain(Iterables.toArray(undeployedTargetsFromDB, Target.class)); - assertThat(undeployedTargetsFromDB).as("content of undeployed target is wrong").containsAll(savedNakedTargets) - .doesNotContain(Iterables.toArray(deployedTargetsFromDB, Target.class)); + assertThat(deployedTargetsFromDB).as("content of deployed target is wrong") + .containsAll((Iterable) savedDeployedTargets) + .doesNotContain(Iterables.toArray(undeployedTargetsFromDB, JpaTarget.class)); + assertThat(undeployedTargetsFromDB).as("content of undeployed target is wrong") + .containsAll((Iterable) savedNakedTargets) + .doesNotContain(Iterables.toArray(deployedTargetsFromDB, JpaTarget.class)); // For each of the 4 targets 1 distribution sets gets assigned eventHandlerMock.getEvents(10, TimeUnit.SECONDS); @@ -557,9 +567,9 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final DeploymentResult deployResWithDsC = prepareComplexRepo("undep-C-T", 4, "dep-C-T", 6, 1, "dsC"); // keep a reference to the created DistributionSets - final DistributionSet dsA = deployResWithDsA.getDistributionSets().get(0); - final DistributionSet dsB = deployResWithDsB.getDistributionSets().get(0); - final DistributionSet dsC = deployResWithDsC.getDistributionSets().get(0); + final JpaDistributionSet dsA = (JpaDistributionSet) deployResWithDsA.getDistributionSets().get(0); + final JpaDistributionSet dsB = (JpaDistributionSet) deployResWithDsB.getDistributionSets().get(0); + final JpaDistributionSet dsC = (JpaDistributionSet) deployResWithDsC.getDistributionSets().get(0); // retrieving the UpdateActions created by the assignments actionRepository.findByDistributionSet(pageRequest, dsA).getContent().get(0); @@ -722,9 +732,9 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { private List sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable targs, final Status status, final String... msgs) { - final List result = new ArrayList(); + final List result = new ArrayList<>(); for (final Target t : targs) { - final List findByTarget = actionRepository.findByTarget(t); + final List findByTarget = actionRepository.findByTarget((JpaTarget) t); for (final Action action : findByTarget) { result.add(sendUpdateActionStatusToTarget(status, action, t, msgs)); } @@ -736,7 +746,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final String... msgs) { updActA.setStatus(status); - final ActionStatus statusMessages = new ActionStatus(); + final ActionStatus statusMessages = new JpaActionStatus(); statusMessages.setAction(updActA); statusMessages.setOccurredAt(System.currentTimeMillis()); statusMessages.setStatus(status); @@ -751,14 +761,14 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { @Description("Testing if changing target and the status without refreshing the entities from the DB (e.g. concurrent changes from UI and from controller) works") public void alternatingAssignmentAndAddUpdateActionStatus() { - final DistributionSet dsA = TestDataUtil.generateDistributionSet("a", softwareManagement, + final JpaDistributionSet dsA = TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement); - final DistributionSet dsB = TestDataUtil.generateDistributionSet("b", softwareManagement, + final JpaDistributionSet dsB = TestDataUtil.generateDistributionSet("b", softwareManagement, distributionSetManagement); Target targ = targetManagement .createTarget(TestDataUtil.buildTargetFixture("target-id-A", "first description")); - List targs = new ArrayList(); + List targs = new ArrayList<>(); targs.add(targ); // doing the assignment @@ -786,7 +796,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { final Page updAct = actionRepository.findByDistributionSet(pageReq, dsA); final Action action = updAct.getContent().get(0); action.setStatus(Status.FINISHED); - final ActionStatus statusMessage = new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), ""); + final ActionStatus statusMessage = new JpaActionStatus((JpaAction) action, Status.FINISHED, + System.currentTimeMillis(), ""); controllerManagament.addUpdateActionStatus(statusMessage); targ = targetManagement.findTargetByControllerID(targ.getControllerId()); @@ -842,7 +853,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { @Description("Tests the switch from a soft to hard update by API") public void forceSoftAction() { // prepare - final Target target = targetManagement.createTarget(new Target("knownControllerId")); + final Target target = targetManagement.createTarget(new JpaTarget("knownControllerId")); final DistributionSet ds = TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement); // assign ds to create an action @@ -865,7 +876,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { @Description("Tests the switch from a hard to hard update by API, e.g. which in fact should not change anything.") public void forceAlreadyForcedActionNothingChanges() { // prepare - final Target target = targetManagement.createTarget(new Target("knownControllerId")); + final Target target = targetManagement.createTarget(new JpaTarget("knownControllerId")); final DistributionSet ds = TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement); // assign ds to create an action @@ -919,8 +930,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { TestDataUtil.buildTargetFixtures(noOfDeployedTargets, deployedTargetPrefix, "first description")); // creating 10 DistributionSets - final List dsList = TestDataUtil.generateDistributionSets(distributionSetPrefix, - noOfDistributionSets, softwareManagement, distributionSetManagement); + final Collection dsList = (Collection) TestDataUtil.generateDistributionSets( + distributionSetPrefix, noOfDistributionSets, softwareManagement, distributionSetManagement); String time = String.valueOf(System.currentTimeMillis()); time = time.substring(time.length() - 5); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java index 8faae175e..3ed4e703e 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java @@ -12,6 +12,7 @@ import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -24,6 +25,13 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -56,7 +64,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Tests the successfull module update of unused distribution set type which is in fact allowed.") public void updateUnassignedDistributionSetTypeModules() { DistributionSetType updatableType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("updatableType", "to be deleted", "")); + .createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deleted", "")); assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes()) .isEmpty(); @@ -83,11 +91,11 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Tests the successfull update of used distribution set type meta data hich is in fact allowed.") public void updateAssignedDistributionSetTypeMetaData() { final DistributionSetType nonUpdatableType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("updatableType", "to be deletd", "")); + .createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", "")); assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes()) .isEmpty(); distributionSetManagement - .createDistributionSet(new DistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); nonUpdatableType.setDescription("a new description"); nonUpdatableType.setColour("test123"); @@ -104,11 +112,11 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Tests the unsuccessfull update of used distribution set type (module addition).") public void addModuleToAssignedDistributionSetTypeFails() { final DistributionSetType nonUpdatableType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("updatableType", "to be deletd", "")); + .createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", "")); assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes()) .isEmpty(); distributionSetManagement - .createDistributionSet(new DistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); nonUpdatableType.addMandatoryModuleType(osType); @@ -125,14 +133,14 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Tests the unsuccessfull update of used distribution set type (module removal).") public void removeModuleToAssignedDistributionSetTypeFails() { DistributionSetType nonUpdatableType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("updatableType", "to be deletd", "")); + .createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", "")); assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes()) .isEmpty(); nonUpdatableType.addMandatoryModuleType(osType); nonUpdatableType = distributionSetManagement.updateDistributionSetType(nonUpdatableType); distributionSetManagement - .createDistributionSet(new DistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null)); nonUpdatableType.removeModuleType(osType.getId()); try { @@ -146,8 +154,8 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Test @Description("Tests the successfull deletion of unused (hard delete) distribution set types.") public void deleteUnassignedDistributionSetType() { - final DistributionSetType hardDelete = distributionSetManagement - .createDistributionSetType(new DistributionSetType("deleted", "to be deleted", "")); + final JpaDistributionSetType hardDelete = (JpaDistributionSetType) distributionSetManagement + .createDistributionSetType(new JpaDistributionSetType("deleted", "to be deleted", "")); assertThat(distributionSetTypeRepository.findAll()).contains(hardDelete); distributionSetManagement.deleteDistributionSetType(hardDelete); @@ -158,11 +166,12 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Test @Description("Tests the successfull deletion of used (soft delete) distribution set types.") public void deleteAssignedDistributionSetType() { - final DistributionSetType softDelete = distributionSetManagement - .createDistributionSetType(new DistributionSetType("softdeleted", "to be deletd", "")); + final JpaDistributionSetType softDelete = (JpaDistributionSetType) distributionSetManagement + .createDistributionSetType(new JpaDistributionSetType("softdeleted", "to be deletd", "")); assertThat(distributionSetTypeRepository.findAll()).contains(softDelete); - distributionSetManagement.createDistributionSet(new DistributionSet("newtypesoft", "1", "", softDelete, null)); + distributionSetManagement + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", softDelete, null)); distributionSetManagement.deleteDistributionSetType(softDelete); assertThat(distributionSetManagement.findDistributionSetTypeByKey("softdeleted").isDeleted()).isEqualTo(true); @@ -185,7 +194,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Verfies that a DS is of default type if not specified explicitly at creation time.") public void createDistributionSetWithImplicitType() { final DistributionSet set = distributionSetManagement - .createDistributionSet(new DistributionSet("newtypesoft", "1", "", null, null)); + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", null, null)); assertThat(set.getType()).as("Type should be equal to default type of tenant") .isEqualTo(systemManagement.getTenantMetadata().getDefaultDsType()); @@ -198,7 +207,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { List sets = new ArrayList<>(); for (int i = 0; i < 10; i++) { - sets.add(new DistributionSet("another DS" + i, "X" + i, "", null, null)); + sets.add(new JpaDistributionSet("another DS" + i, "X" + i, "", null, null)); } sets = distributionSetManagement.createDistributionSets(sets); @@ -216,7 +225,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Verfies that a DS entity cannot be used for creation.") public void createDistributionSetFailsOnExistingEntity() { final DistributionSet set = distributionSetManagement - .createDistributionSet(new DistributionSet("newtypesoft", "1", "", null, null)); + .createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", null, null)); try { distributionSetManagement.createDistributionSet(set); @@ -235,8 +244,8 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { final DistributionSet ds = TestDataUtil.generateDistributionSet("testDs", softwareManagement, distributionSetManagement); - final DistributionSetMetadata metadata = new DistributionSetMetadata(knownKey, ds, knownValue); - final DistributionSetMetadata createdMetadata = distributionSetManagement + final DistributionSetMetadata metadata = new JpaDistributionSetMetadata(knownKey, ds, knownValue); + final JpaDistributionSetMetadata createdMetadata = (JpaDistributionSetMetadata) distributionSetManagement .createDistributionSetMetadata(metadata); assertThat(createdMetadata).isNotNull(); @@ -249,11 +258,11 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Ensures that updates concerning the internal software structure of a DS are not possible if the DS is already assigned.") public void updateDistributionSetForbiddedWithIllegalUpdate() { // prepare data - Target target = new Target("4711"); + Target target = new JpaTarget("4711"); target = targetManagement.createTarget(target); - SoftwareModule ah2 = new SoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); - SoftwareModule os2 = new SoftwareModule(osType, "poky2", "3.0.3", null, ""); + SoftwareModule ah2 = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); + SoftwareModule os2 = new JpaSoftwareModule(osType, "poky2", "3.0.3", null, ""); DistributionSet ds = TestDataUtil.generateDistributionSet("ds-1", softwareManagement, distributionSetManagement); @@ -303,8 +312,8 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that it is not possible to add a software module to a set that has no type defined.") public void updateDistributionSetModuleWithUndefinedTypeFails() { - final DistributionSet testSet = new DistributionSet(); - final SoftwareModule module = new SoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); + final DistributionSet testSet = new JpaDistributionSet(); + final SoftwareModule module = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); // update data try { @@ -318,9 +327,9 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that it is not possible to add a software module that is not defined of the DS's type.") public void updateDistributionSetUnsupportedModuleFails() { - final DistributionSet set = new DistributionSet("agent-hub2", "1.0.5", "desc", - new DistributionSetType("test", "test", "test").addMandatoryModuleType(osType), null); - final SoftwareModule module = new SoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); + final DistributionSet set = new JpaDistributionSet("agent-hub2", "1.0.5", "desc", + new JpaDistributionSetType("test", "test", "test").addMandatoryModuleType(osType), null); + final SoftwareModule module = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, ""); // update data try { @@ -335,11 +344,11 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Legal updates of a DS, e.g. name or description and module addition, removal while still unassigned.") public void updateDistributionSet() { // prepare data - Target target = new Target("4711"); + Target target = new JpaTarget("4711"); target = targetManagement.createTarget(target); - SoftwareModule os2 = new SoftwareModule(osType, "poky2", "3.0.3", null, ""); - final SoftwareModule app2 = new SoftwareModule(appType, "app2", "3.0.3", null, ""); + SoftwareModule os2 = new JpaSoftwareModule(osType, "poky2", "3.0.3", null, ""); + final SoftwareModule app2 = new JpaSoftwareModule(appType, "app2", "3.0.3", null, ""); DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement); @@ -387,7 +396,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { // create an DS meta data entry final DistributionSetMetadata dsMetadata = distributionSetManagement - .createDistributionSetMetadata(new DistributionSetMetadata(knownKey, ds, knownValue)); + .createDistributionSetMetadata(new JpaDistributionSetMetadata(knownKey, ds, knownValue)); DistributionSet changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId()); assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2L); @@ -400,7 +409,8 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { Thread.sleep(100); // update the DS metadata - final DistributionSetMetadata updated = distributionSetManagement.updateDistributionSetMetadata(dsMetadata); + final JpaDistributionSetMetadata updated = (JpaDistributionSetMetadata) distributionSetManagement + .updateDistributionSetMetadata(dsMetadata); // we are updating the sw meta data so also modifying the base software // module so opt lock // revision must be three @@ -419,13 +429,13 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.") public void findDistributionSetsAllOrderedByLinkTarget() { - final List buildDistributionSets = TestDataUtil.generateDistributionSets("dsOrder", 10, + final List buildDistributionSets = TestDataUtil.generateDistributionSets("dsOrder", 10, softwareManagement, distributionSetManagement); final List buildTargetFixtures = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(5, "tOrder", "someDesc")); - final Iterator dsIterator = buildDistributionSets.iterator(); + final Iterator dsIterator = buildDistributionSets.iterator(); final Iterator tIterator = buildTargetFixtures.iterator(); final DistributionSet dsFirst = dsIterator.next(); final DistributionSet dsSecond = dsIterator.next(); @@ -466,29 +476,29 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { @Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.") public void searchDistributionSetsOnFilters() { DistributionSetTag dsTagA = tagManagement - .createDistributionSetTag(new DistributionSetTag("DistributionSetTag-A")); + .createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-A")); final DistributionSetTag dsTagB = tagManagement - .createDistributionSetTag(new DistributionSetTag("DistributionSetTag-B")); + .createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-B")); final DistributionSetTag dsTagC = tagManagement - .createDistributionSetTag(new DistributionSetTag("DistributionSetTag-C")); + .createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-C")); final DistributionSetTag dsTagD = tagManagement - .createDistributionSetTag(new DistributionSetTag("DistributionSetTag-D")); + .createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-D")); - List ds100Group1 = TestDataUtil.generateDistributionSets("", 100, softwareManagement, - distributionSetManagement); - List ds100Group2 = TestDataUtil.generateDistributionSets("test2", 100, softwareManagement, - distributionSetManagement); + Collection ds100Group1 = (Collection) TestDataUtil.generateDistributionSets("", 100, + softwareManagement, distributionSetManagement); + Collection ds100Group2 = (Collection) TestDataUtil.generateDistributionSets("test2", 100, + softwareManagement, distributionSetManagement); DistributionSet dsDeleted = TestDataUtil.generateDistributionSet("deleted", softwareManagement, distributionSetManagement); final DistributionSet dsInComplete = distributionSetManagement - .createDistributionSet(new DistributionSet("notcomplete", "1", "", standardDsType, null)); + .createDistributionSet(new JpaDistributionSet("notcomplete", "1", "", standardDsType, null)); - final DistributionSetType newType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("foo", "bar", "test").addMandatoryModuleType(osType) + final DistributionSetType newType = distributionSetManagement.createDistributionSetType( + new JpaDistributionSetType("foo", "bar", "test").addMandatoryModuleType(osType) .addOptionalModuleType(appType).addOptionalModuleType(runtimeType)); final DistributionSet dsNewType = distributionSetManagement - .createDistributionSet(new DistributionSet("newtype", "1", "", newType, dsDeleted.getModules())); + .createDistributionSet(new JpaDistributionSet("newtype", "1", "", newType, dsDeleted.getModules())); deploymentManagement.assignDistributionSet(dsDeleted, targetManagement.createTargets(Lists.newArrayList(TestDataUtil.generateTargets(5)))); @@ -705,7 +715,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { final Status status, final String... msgs) { final List result = new ArrayList<>(); for (final Target t : targs) { - final List findByTarget = actionRepository.findByTarget(t); + final List findByTarget = actionRepository.findByTarget((JpaTarget) t); for (final Action action : findByTarget) { result.add(sendUpdateActionStatusToTarget(status, action, t, msgs)); } @@ -753,14 +763,14 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { for (int index = 0; index < 10; index++) { ds1 = distributionSetManagement - .createDistributionSetMetadata(new DistributionSetMetadata("key" + index, ds1, "value" + index)) + .createDistributionSetMetadata(new JpaDistributionSetMetadata("key" + index, ds1, "value" + index)) .getDistributionSet(); } for (int index = 0; index < 20; index++) { ds2 = distributionSetManagement - .createDistributionSetMetadata(new DistributionSetMetadata("key" + index, ds2, "value" + index)) + .createDistributionSetMetadata(new JpaDistributionSetMetadata("key" + index, ds2, "value" + index)) .getDistributionSet(); } @@ -794,7 +804,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { // create assigned DS dsAssigned = distributionSetManagement.findDistributionSetByNameAndVersion(dsAssigned.getName(), dsAssigned.getVersion()); - final Target target = new Target("4712"); + final Target target = new JpaTarget("4712"); final Target savedTarget = targetManagement.createTarget(target); final List toAssign = new ArrayList<>(); toAssign.add(savedTarget); @@ -814,7 +824,7 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest { final String... msgs) { updActA.setStatus(status); - final ActionStatus statusMessages = new ActionStatus(); + final ActionStatus statusMessages = new JpaActionStatus(); statusMessages.setAction(updActA); statusMessages.setOccurredAt(System.currentTimeMillis()); statusMessages.setStatus(status); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ReportManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ReportManagementTest.java index e41491962..0a18c0b03 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ReportManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ReportManagementTest.java @@ -29,13 +29,16 @@ import org.eclipse.hawkbit.report.model.DataReportSeriesItem; import org.eclipse.hawkbit.report.model.InnerOuterDataReportSeries; import org.eclipse.hawkbit.report.model.SeriesTime; import org.eclipse.hawkbit.repository.ReportManagement.DateTypes; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.junit.After; import org.junit.Test; @@ -83,7 +86,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) { dynamicDateTimeProvider.nowMinusMonths(month); - targetManagement.createTarget(new Target("t" + month)); + targetManagement.createTarget(new JpaTarget("t" + month)); } final LocalDateTime to = LocalDateTime.now(); @@ -105,7 +108,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { // check cache evict for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) { dynamicDateTimeProvider.nowMinusMonths(month); - targetManagement.createTarget(new Target("t2" + month)); + targetManagement.createTarget(new JpaTarget("t2" + month)); } targetsCreatedOverPeriod = reportManagement.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to); for (final DataReportSeriesItem reportItem : targetsCreatedOverPeriod.getData()) { @@ -135,7 +138,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) { dynamicDateTimeProvider.nowMinusMonths(month); - final Target createTarget = targetManagement.createTarget(new Target("t" + month)); + final Target createTarget = targetManagement.createTarget(new JpaTarget("t" + month)); final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(distributionSet, Lists.newArrayList(createTarget)); controllerManagament.registerRetrieved( @@ -157,7 +160,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { // check cache evict for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) { dynamicDateTimeProvider.nowMinusMonths(month); - final Target createTarget = targetManagement.createTarget(new Target("t2" + month)); + final Target createTarget = targetManagement.createTarget(new JpaTarget("t2" + month)); final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(distributionSet, Lists.newArrayList(createTarget)); controllerManagament.registerRetrieved( @@ -174,18 +177,18 @@ public class ReportManagementTest extends AbstractIntegrationTest { @Test @Description("Tests correct statistics calculation including a correct cache evict.") public void distributionUsageInstalled() { - final Target knownTarget1 = targetManagement.createTarget(new Target("t1")); - final Target knownTarget2 = targetManagement.createTarget(new Target("t2")); - final Target knownTarget3 = targetManagement.createTarget(new Target("t3")); - final Target knownTarget4 = targetManagement.createTarget(new Target("t4")); - final Target knownTarget5 = targetManagement.createTarget(new Target("t5")); + final Target knownTarget1 = targetManagement.createTarget(new JpaTarget("t1")); + final Target knownTarget2 = targetManagement.createTarget(new JpaTarget("t2")); + final Target knownTarget3 = targetManagement.createTarget(new JpaTarget("t3")); + final Target knownTarget4 = targetManagement.createTarget(new JpaTarget("t4")); + final Target knownTarget5 = targetManagement.createTarget(new JpaTarget("t5")); final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, "")); final DistributionSet distributionSet1 = distributionSetManagement .createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.0", standardDsType, os, jvm, ah)); @@ -250,7 +253,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { } // Test cache evict - final Target knownTarget6 = targetManagement.createTarget(new Target("t6")); + final Target knownTarget6 = targetManagement.createTarget(new JpaTarget("t6")); deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget6.getControllerId()); sendUpdateActionStatusToTargets(distributionSet1, Lists.newArrayList(knownTarget6), Status.FINISHED, "some message"); @@ -349,17 +352,17 @@ public class ReportManagementTest extends AbstractIntegrationTest { @Description("Tests correct statistics calculation including a correct cache evict.") public void topXDistributionUsage() { - final Target knownTarget1 = targetManagement.createTarget(new Target("t1")); - final Target knownTarget2 = targetManagement.createTarget(new Target("t2")); - final Target knownTarget3 = targetManagement.createTarget(new Target("t3")); - final Target knownTarget4 = targetManagement.createTarget(new Target("t4")); + final Target knownTarget1 = targetManagement.createTarget(new JpaTarget("t1")); + final Target knownTarget2 = targetManagement.createTarget(new JpaTarget("t2")); + final Target knownTarget3 = targetManagement.createTarget(new JpaTarget("t3")); + final Target knownTarget4 = targetManagement.createTarget(new JpaTarget("t4")); final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, "")); final DistributionSet distributionSet1 = distributionSetManagement .createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.0", standardDsType, os, jvm, ah)); @@ -419,7 +422,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { } // test cache evict - final Target knownTarget5 = targetManagement.createTarget(new Target("t5")); + final Target knownTarget5 = targetManagement.createTarget(new JpaTarget("t5")); deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget5.getControllerId()); distributionUsage = reportManagement.distributionUsageAssigned(100); for (final InnerOuterDataReportSeries innerOuterDataReportSeries : distributionUsage) { @@ -490,7 +493,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { // create targets for another tenant securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "anotherTenant"), () -> { for (int index = 0; index < targetCreateAmount; index++) { - targetManagement.createTarget(new Target("t" + index)); + targetManagement.createTarget(new JpaTarget("t" + index)); } return null; }); @@ -513,10 +516,10 @@ public class ReportManagementTest extends AbstractIntegrationTest { private void createTargets(final String prefix, final int amount, final LocalDateTime lastTargetQuery) { for (int index = 0; index < amount; index++) { - final Target target = new Target(prefix + index); - final Target createTarget = targetManagement.createTarget(target); + final Target target = new JpaTarget(prefix + index); + final JpaTarget createTarget = (JpaTarget) targetManagement.createTarget(target); if (lastTargetQuery != null) { - final TargetInfo targetInfo = createTarget.getTargetInfo(); + final JpaTargetInfo targetInfo = (JpaTargetInfo) createTarget.getTargetInfo(); targetInfo.setNew(false); targetInfo .setLastTargetQuery(lastTargetQuery.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); @@ -527,9 +530,9 @@ public class ReportManagementTest extends AbstractIntegrationTest { private void createTargetsWithStatus(final String prefix, final long amount, final TargetUpdateStatus status) { for (int index = 0; index < amount; index++) { - final Target target = new Target(prefix + index); + final JpaTarget target = new JpaTarget(prefix + index); final Target sTarget = targetRepository.save(target); - final TargetInfo targetInfo = sTarget.getTargetInfo(); + final JpaTargetInfo targetInfo = (JpaTargetInfo) sTarget.getTargetInfo(); targetInfo.setUpdateStatus(status); targetInfoRepository.save(targetInfo); } @@ -537,9 +540,9 @@ public class ReportManagementTest extends AbstractIntegrationTest { private List sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable targs, final Status status, final String... msgs) { - final List result = new ArrayList(); + final List result = new ArrayList<>(); for (final Target t : targs) { - final List findByTarget = actionRepository.findByTarget(t); + final List findByTarget = actionRepository.findByTarget((JpaTarget) t); for (final Action action : findByTarget) { result.add(sendUpdateActionStatusToTarget(status, action, t, msgs)); } @@ -551,7 +554,7 @@ public class ReportManagementTest extends AbstractIntegrationTest { final String... msgs) { updActA.setStatus(status); - final ActionStatus statusMessages = new ActionStatus(); + final ActionStatus statusMessages = new JpaActionStatus(); statusMessages.setAction(updActA); statusMessages.setOccurredAt(System.currentTimeMillis()); statusMessages.setStatus(status); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java index 88bb26616..e56ce6cd5 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java @@ -19,23 +19,26 @@ import java.util.concurrent.Callable; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.jpa.OffsetBasedPageRequest; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditions; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorCondition; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessCondition; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditions; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.hawkbit.repository.rsql.RSQLUtility; import org.eclipse.hawkbit.repository.utils.MultipleInvokeHelper; import org.eclipse.hawkbit.repository.utils.SuccessCondition; import org.junit.Test; @@ -45,7 +48,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.jpa.domain.Specification; import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Stories; @@ -135,10 +137,10 @@ public class RolloutManagementTest extends AbstractIntegrationTest { Status.RUNNING); // finish one action should be sufficient due the finish condition is at // 50% - final Action action = runningActions.get(0); + final JpaAction action = (JpaAction) runningActions.get(0); action.setStatus(Status.FINISHED); controllerManagament - .addUpdateActionStatus(new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "")); + .addUpdateActionStatus(new JpaActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "")); // check running rollouts again, now the finish condition should be hit // and should start the next group @@ -179,8 +181,8 @@ public class RolloutManagementTest extends AbstractIntegrationTest { // finish actions with error for (final Action action : runningActions) { action.setStatus(Status.ERROR); - controllerManagament - .addUpdateActionStatus(new ActionStatus(action, Status.ERROR, System.currentTimeMillis(), "")); + controllerManagament.addUpdateActionStatus( + new JpaActionStatus((JpaAction) action, Status.ERROR, System.currentTimeMillis(), "")); } // check running rollouts again, now the error condition should be hit @@ -221,8 +223,8 @@ public class RolloutManagementTest extends AbstractIntegrationTest { // finish actions with error for (final Action action : runningActions) { action.setStatus(Status.ERROR); - controllerManagament - .addUpdateActionStatus(new ActionStatus(action, Status.ERROR, System.currentTimeMillis(), "")); + controllerManagament.addUpdateActionStatus( + new JpaActionStatus((JpaAction) action, Status.ERROR, System.currentTimeMillis(), "")); } // check running rollouts again, now the error condition should be hit @@ -835,25 +837,24 @@ public class RolloutManagementTest extends AbstractIntegrationTest { targetManagement.createTargets(TestDataUtil.buildTargetFixtures(amountOtherTargets, "others-", "rollout")); final String rsqlParam = "controllerId==*MyRoll*"; - final Specification rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class); rolloutManagement.startRollout(myRollout); myRollout = rolloutManagement.findRolloutById(myRollout.getId()); final List rolloutGroups = myRollout.getRolloutGroups(); - Page targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(0), - rsqlSpecification, new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "controllerId"))); + Page targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(0), rsqlParam, + new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "controllerId"))); final List targetlistGroup1 = targetPage.getContent(); assertThat(targetlistGroup1.size()).isEqualTo(5); assertThat(targetlistGroup1.get(0).getControllerId()).isEqualTo("MyRollout--00000"); - targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(1), rsqlSpecification, + targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(1), rsqlParam, new OffsetBasedPageRequest(0, 100, new Sort(Direction.DESC, "controllerId"))); final List targetlistGroup2 = targetPage.getContent(); assertThat(targetlistGroup2.size()).isEqualTo(5); assertThat(targetlistGroup2.get(0).getControllerId()).isEqualTo("MyRollout--00009"); - targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(2), rsqlSpecification, + targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(2), rsqlParam, new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "controllerId"))); final List targetlistGroup3 = targetPage.getContent(); assertThat(targetlistGroup3.size()).isEqualTo(5); @@ -875,11 +876,11 @@ public class RolloutManagementTest extends AbstractIntegrationTest { softwareManagement, distributionSetManagement); targetManagement.createTargets( TestDataUtil.buildTargetFixtures(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName)); - final RolloutGroupConditions conditions = new RolloutGroup.RolloutGroupConditionBuilder() + final RolloutGroupConditions conditions = new JpaRolloutGroup.RolloutGroupConditionBuilder() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition) .errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition) .errorAction(RolloutGroupErrorAction.PAUSE, null).build(); - Rollout myRollout = new Rollout(); + Rollout myRollout = new JpaRollout(); myRollout.setName(rolloutName); myRollout.setDescription("This is a test description for the rollout"); myRollout.setTargetFilterQuery("controllerId==" + targetPrefixName + "-*"); @@ -933,11 +934,11 @@ public class RolloutManagementTest extends AbstractIntegrationTest { final int amountOtherTargets, final int groupSize, final String successCondition, final String errorCondition) { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, "")); final DistributionSet rolloutDS = distributionSetManagement.createDistributionSet( TestDataUtil.buildDistributionSet("rolloutDS", "0.0.0", standardDsType, os, jvm, ah)); targetManagement @@ -962,11 +963,11 @@ public class RolloutManagementTest extends AbstractIntegrationTest { private Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription, final int groupSize, final String filterQuery, final DistributionSet distributionSet, final String successCondition, final String errorCondition) { - final RolloutGroupConditions conditions = new RolloutGroup.RolloutGroupConditionBuilder() + final RolloutGroupConditions conditions = new JpaRolloutGroup.RolloutGroupConditionBuilder() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition) .errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition) .errorAction(RolloutGroupErrorAction.PAUSE, null).build(); - final Rollout rolloutToCreate = new Rollout(); + final Rollout rolloutToCreate = new JpaRollout(); rolloutToCreate.setName(rolloutName); rolloutToCreate.setDescription(rolloutDescription); rolloutToCreate.setTargetFilterQuery(filterQuery); @@ -978,8 +979,8 @@ public class RolloutManagementTest extends AbstractIntegrationTest { final List runningActions = deploymentManagement.findActionsByRolloutAndStatus(rollout, Status.RUNNING); for (final Action action : runningActions) { action.setStatus(status); - controllerManagament - .addUpdateActionStatus(new ActionStatus(action, status, System.currentTimeMillis(), "")); + controllerManagament.addUpdateActionStatus( + new JpaActionStatus((JpaAction) action, status, System.currentTimeMillis(), "")); } return runningActions.size(); } @@ -990,12 +991,12 @@ public class RolloutManagementTest extends AbstractIntegrationTest { assertThat(runningActions.size()).isGreaterThanOrEqualTo(amountOfTargetsToGetChanged); for (int i = 0; i < amountOfTargetsToGetChanged; i++) { controllerManagament.addUpdateActionStatus( - new ActionStatus(runningActions.get(i), status, System.currentTimeMillis(), "")); + new JpaActionStatus((JpaAction) runningActions.get(i), status, System.currentTimeMillis(), "")); } return runningActions.size(); } - private Map createInitStatusMap() { + private static Map createInitStatusMap() { final Map map = new HashMap<>(); for (final TotalTargetCountStatus.Status status : TotalTargetCountStatus.Status.values()) { map.put(status, 0L); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java index 04eccb13e..300fe78dc 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java @@ -26,16 +26,22 @@ import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.WithUser; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.CustomSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.junit.Test; @@ -59,7 +65,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Try to update non updatable fields results in repository doing nothing.") public void updateTypeNonUpdateableFieldsFails() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test-key", "test-name", "test-desc", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test-key", "test-name", "test-desc", 1)); created.setName("a new name"); final SoftwareModuleType updated = softwareManagement.updateSoftwareModuleType(created); @@ -73,7 +79,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Calling update without changing fields results in no recorded change in the repository including unchanged audit fields.") public void updateNothingResultsInUnchangedRepositoryForType() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test-key", "test-name", "test-desc", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test-key", "test-name", "test-desc", 1)); final SoftwareModuleType updated = softwareManagement.updateSoftwareModuleType(created); @@ -86,7 +92,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Calling update for changed fields results in change in the repository.") public void updateSoftareModuleTypeFieldsToNewValue() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test-key", "test-name", "test-desc", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test-key", "test-name", "test-desc", 1)); created.setDescription("changed"); created.setColour("changed"); @@ -103,7 +109,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Try to update non updatable fields results in repository doing nothing.") public void updateNonUpdateableFieldsFails() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); ah.setName("a new name"); final SoftwareModule updated = softwareManagement.updateSoftwareModule(ah); @@ -117,7 +123,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Calling update without changing fields results in no recorded change in the repository including unchanged audit fields.") public void updateNothingResultsInUnchangedRepository() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule updated = softwareManagement.updateSoftwareModule(ah); @@ -130,7 +136,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Calling update for changed fields results in change in the repository.") public void updateSoftareModuleFieldsToNewValue() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); ah.setDescription("changed"); ah.setVendor("changed"); @@ -146,7 +152,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Create Software Module call fails when called for existing entity.") public void createModuleCallFailsForExistingModule() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); try { softwareManagement.createSoftwareModule(ah); fail("Should not have worked as module already exists."); @@ -159,8 +165,8 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Create Software Modules call fails when called for existing entities.") public void createModulesCallFailsForExistingModule() { final List modules = softwareManagement.createSoftwareModule( - Lists.newArrayList(new SoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor"), - new SoftwareModule(appType, "agent-hub", "1.0.2", "test desc", "test vendor"))); + Lists.newArrayList(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor"), + new JpaSoftwareModule(appType, "agent-hub", "1.0.2", "test desc", "test vendor"))); try { softwareManagement.createSoftwareModule(modules); fail("Should not have worked as module already exists."); @@ -173,7 +179,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Create Software Module Type call fails when called for existing entity.") public void createModuleTypeCallFailsForExistingType() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test-key", "test-name", "test-desc", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test-key", "test-name", "test-desc", 1)); try { softwareManagement.createSoftwareModuleType(created); @@ -187,8 +193,8 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Create Software Module Types call fails when called for existing entities.") public void createModuleTypesCallFailsForExistingTypes() { final List created = softwareManagement.createSoftwareModuleType( - Lists.newArrayList(new SoftwareModuleType("test-key-bumlux", "test-name", "test-desc", 1), - new SoftwareModuleType("test-key-bumlux2", "test-name2", "test-desc", 1))); + Lists.newArrayList(new JpaSoftwareModuleType("test-key-bumlux", "test-name", "test-desc", 1), + new JpaSoftwareModuleType("test-key-bumlux2", "test-name2", "test-desc", 1))); try { softwareManagement.createSoftwareModuleType(created); @@ -202,7 +208,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Calling update for changing fields to null results in change in the repository.") public void eraseSoftareModuleFields() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "test desc", "test vendor")); ah.setDescription(null); ah.setVendor(null); @@ -218,19 +224,19 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("searched for software modules based on the various filter options, e.g. name,desc,type, version.") public void findSoftwareModuleByFilters() { final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, "")); final SoftwareModule ah2 = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.2", null, "")); - DistributionSet ds = distributionSetManagement.createDistributionSet( + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.2", null, "")); + JpaDistributionSet ds = (JpaDistributionSet) distributionSetManagement.createDistributionSet( TestDataUtil.buildDistributionSet("ds-1", "1.0.1", standardDsType, os, jvm, ah2)); - final Target target = targetManagement.createTarget(new Target("test123")); - ds = assignSet(target, ds).getDistributionSet(); + final JpaTarget target = (JpaTarget) targetManagement.createTarget(new JpaTarget("test123")); + ds = (JpaDistributionSet) assignSet(target, ds).getDistributionSet(); // standard searches assertThat(softwareManagement.findSoftwareModuleByFilters(pageReq, "poky", osType).getContent()).hasSize(1); @@ -254,7 +260,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { .isEqualTo(ah); } - private Action assignSet(final Target target, final DistributionSet ds) { + private Action assignSet(final JpaTarget target, final JpaDistributionSet ds) { deploymentManagement.assignDistributionSet(ds.getId(), new String[] { target.getControllerId() }); assertThat( targetManagement.findTargetByControllerID(target.getControllerId()).getTargetInfo().getUpdateStatus()) @@ -272,10 +278,10 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final List modules = new ArrayList<>(); - modules.add(softwareManagement.createSoftwareModule(new SoftwareModule(osType, "poky-una", "3.0.2", null, "")) - .getId()); - modules.add(softwareManagement.createSoftwareModule(new SoftwareModule(osType, "poky-u2na", "3.0.3", null, "")) - .getId()); + modules.add(softwareManagement + .createSoftwareModule(new JpaSoftwareModule(osType, "poky-una", "3.0.2", null, "")).getId()); + modules.add(softwareManagement + .createSoftwareModule(new JpaSoftwareModule(osType, "poky-u2na", "3.0.3", null, "")).getId()); modules.add(624355263L); assertThat(softwareManagement.findSoftwareModulesById(modules)).hasSize(2); @@ -286,13 +292,13 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void findSoftwareModulesByType() { // found in test final SoftwareModule one = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "one", "one", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "one", "one", null, "")); final SoftwareModule two = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "two", "two", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "two", "two", null, "")); // ignored softwareManagement.deleteSoftwareModule( - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "deleted", "deleted", null, ""))); - softwareManagement.createSoftwareModule(new SoftwareModule(appType, "three", "3.0.2", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "deleted", "deleted", null, ""))); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(appType, "three", "3.0.2", null, "")); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent()) .as("Expected to find the following number of modules:").hasSize(2).as("with the following elements") @@ -303,11 +309,11 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Counts all software modules in the repsitory that are not marked as deleted.") public void countSoftwareModulesAll() { // found in test - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "one", "one", null, "")); - softwareManagement.createSoftwareModule(new SoftwareModule(appType, "two", "two", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "one", "one", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(appType, "two", "two", null, "")); // ignored softwareManagement.deleteSoftwareModule( - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "deleted", "deleted", null, ""))); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "deleted", "deleted", null, ""))); assertThat(softwareManagement.countSoftwareModulesAll()).as("Expected to find the following number of modules:") .isEqualTo(2); @@ -317,13 +323,13 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Counts for software modules by type.") public void countSoftwareModulesByType() { // found in test - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "one", "one", null, "")); - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "two", "two", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "one", "one", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "two", "two", null, "")); // ignored softwareManagement.deleteSoftwareModule( - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "deleted", "deleted", null, ""))); - softwareManagement.createSoftwareModule(new SoftwareModule(appType, "three", "3.0.2", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "deleted", "deleted", null, ""))); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(appType, "three", "3.0.2", null, "")); assertThat(softwareManagement.countSoftwareModulesByType(osType)) .as("Expected to find the following number of modules:").isEqualTo(2); @@ -336,7 +342,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { appType); SoftwareModuleType type = softwareManagement.createSoftwareModuleType( - new SoftwareModuleType("bundle", "OSGi Bundle", "fancy stuff", Integer.MAX_VALUE)); + new JpaSoftwareModuleType("bundle", "OSGi Bundle", "fancy stuff", Integer.MAX_VALUE)); assertThat(softwareManagement.findSoftwareModuleTypesAll(pageReq)).hasSize(4).contains(osType, runtimeType, appType, type); @@ -345,23 +351,25 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { softwareManagement.deleteSoftwareModuleType(type); assertThat(softwareManagement.findSoftwareModuleTypesAll(pageReq)).hasSize(3).contains(osType, runtimeType, appType); - assertThat(softwareModuleTypeRepository.findAll()).hasSize(3).contains(osType, runtimeType, appType); + assertThat(softwareModuleTypeRepository.findAll()).hasSize(3).contains((JpaSoftwareModuleType) osType, + (JpaSoftwareModuleType) runtimeType, (JpaSoftwareModuleType) appType); type = softwareManagement.createSoftwareModuleType( - new SoftwareModuleType("bundle2", "OSGi Bundle2", "fancy stuff", Integer.MAX_VALUE)); + new JpaSoftwareModuleType("bundle2", "OSGi Bundle2", "fancy stuff", Integer.MAX_VALUE)); assertThat(softwareManagement.findSoftwareModuleTypesAll(pageReq)).hasSize(4).contains(osType, runtimeType, appType, type); softwareManagement - .createSoftwareModule(new SoftwareModule(type, "Test SM", "1.0", "cool module", "from meeee")); + .createSoftwareModule(new JpaSoftwareModule(type, "Test SM", "1.0", "cool module", "from meeee")); // delete assigned softwareManagement.deleteSoftwareModuleType(type); assertThat(softwareManagement.findSoftwareModuleTypesAll(pageReq)).hasSize(3).contains(osType, runtimeType, appType); - assertThat(softwareModuleTypeRepository.findAll()).hasSize(4).contains(osType, runtimeType, appType, + assertThat(softwareModuleTypeRepository.findAll()).hasSize(4).contains((JpaSoftwareModuleType) osType, + (JpaSoftwareModuleType) runtimeType, (JpaSoftwareModuleType) appType, softwareModuleTypeRepository.findOne(type.getId())); } @@ -397,7 +405,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // Init DistributionSet final DistributionSet disSet = distributionSetManagement - .createDistributionSet(new DistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); + .createDistributionSet(new JpaDistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); // [STEP1]: Create SoftwareModuleX with ArtifactX SoftwareModule assignedModule = createSoftwareModuleWithArtifacts(osType, "moduleX", "3.0.2", 2); @@ -431,9 +439,9 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void softDeleteOfHistoricalAssignedArtifact() { // Init target and DistributionSet - final Target target = targetManagement.createTarget(new Target("test123")); + final Target target = targetManagement.createTarget(new JpaTarget("test123")); final DistributionSet disSet = distributionSetManagement - .createDistributionSet(new DistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); + .createDistributionSet(new JpaDistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); // [STEP1]: Create SoftwareModuleX and include the new ArtifactX SoftwareModule assignedModule = createSoftwareModuleWithArtifacts(osType, "moduleX", "3.0.2", 2); @@ -525,11 +533,11 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // Init artifact binary data, target and DistributionSets final byte[] source = RandomUtils.nextBytes(1024); - final Target target = targetManagement.createTarget(new Target("test123")); + final Target target = targetManagement.createTarget(new JpaTarget("test123")); final DistributionSet disSetX = distributionSetManagement - .createDistributionSet(new DistributionSet("dsX", "v1.0", "test dsX", standardDsType, null)); + .createDistributionSet(new JpaDistributionSet("dsX", "v1.0", "test dsX", standardDsType, null)); final DistributionSet disSetY = distributionSetManagement - .createDistributionSet(new DistributionSet("dsY", "v1.0", "test dsY", standardDsType, null)); + .createDistributionSet(new JpaDistributionSet("dsY", "v1.0", "test dsY", standardDsType, null)); // [STEP1]: Create SoftwareModuleX and add a new ArtifactX SoftwareModule moduleX = createSoftwareModuleWithArtifacts(osType, "modulex", "v1.0", 0); @@ -587,8 +595,8 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final long countSoftwareModule = softwareModuleRepository.count(); // create SoftwareModule - SoftwareModule softwareModule = softwareManagement - .createSoftwareModule(new SoftwareModule(type, name, version, "description of artifact " + name, "")); + SoftwareModule softwareModule = softwareManagement.createSoftwareModule( + new JpaSoftwareModule(type, name, version, "description of artifact " + name, "")); for (int i = 0; i < numberArtifacts; i++) { artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024), softwareModule.getId(), @@ -617,7 +625,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { for (final Artifact result : results) { assertThat(result.getId()).isNotNull(); assertThat(operations.findOne(new Query() - .addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))) .isNotNull(); } } @@ -625,7 +633,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { private void assertArtfiactNull(final Artifact... results) { for (final Artifact result : results) { assertThat(operations.findOne(new Query() - .addCriteria(Criteria.where("filename").is(((LocalArtifact) result).getGridFsFileName())))) + .addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))) .isNull(); } } @@ -635,28 +643,28 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void findSoftwareModuleOrderByDistributionModuleNameAscModuleVersionAsc() { // test meta data final SoftwareModuleType testType = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); final DistributionSetType testDsType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("key", "name", "desc").addMandatoryModuleType(osType) - .addOptionalModuleType(testType)); + .createDistributionSetType(new JpaDistributionSetType("key", "name", "desc") + .addMandatoryModuleType(osType).addOptionalModuleType(testType)); // found in test final SoftwareModule unassigned = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "asis", "found", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "asis", "found", null, "")); final SoftwareModule one = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "b", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "b", null, "")); final SoftwareModule two = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "c", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "c", null, "")); final SoftwareModule differentName = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "differentname", "d", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "differentname", "d", null, "")); // ignored final SoftwareModule deleted = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "deleted", "deleted", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "deleted", "deleted", null, "")); final SoftwareModule four = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "sdfjhsdj", "e", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "sdfjhsdj", "e", null, "")); - final DistributionSet set = distributionSetManagement.createDistributionSet(new DistributionSet("set", "1", + final DistributionSet set = distributionSetManagement.createDistributionSet(new JpaDistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(one, two, deleted, four, differentName))); softwareManagement.deleteSoftwareModule(deleted); @@ -688,26 +696,26 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // test meta data final SoftwareModuleType testType = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); final DistributionSetType testDsType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("key", "name", "desc").addMandatoryModuleType(osType) - .addOptionalModuleType(testType)); + .createDistributionSetType(new JpaDistributionSetType("key", "name", "desc") + .addMandatoryModuleType(osType).addOptionalModuleType(testType)); // test modules - softwareManagement.createSoftwareModule(new SoftwareModule(testType, "asis", "found", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(testType, "asis", "found", null, "")); final SoftwareModule one = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "b", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "b", null, "")); final SoftwareModule two = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "c", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "c", null, "")); final SoftwareModule differentName = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "differentname", "d", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "differentname", "d", null, "")); final SoftwareModule four = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "found", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "found", "3.0.2", null, "")); // one soft deleted final SoftwareModule deleted = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "deleted", "deleted", null, "")); - distributionSetManagement.createDistributionSet(new DistributionSet("set", "1", "desc", testDsType, + .createSoftwareModule(new JpaSoftwareModule(testType, "deleted", "deleted", null, "")); + distributionSetManagement.createDistributionSet(new JpaDistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(one, two, deleted, four, differentName))); softwareManagement.deleteSoftwareModule(deleted); @@ -724,18 +732,18 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Verfies that all undeleted software modules are found in the repository.") public void countSoftwareModuleTypesAll() { final SoftwareModuleType testType = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); final DistributionSetType testDsType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("key", "name", "desc").addMandatoryModuleType(osType) - .addOptionalModuleType(testType)); + .createDistributionSetType(new JpaDistributionSetType("key", "name", "desc") + .addMandatoryModuleType(osType).addOptionalModuleType(testType)); final SoftwareModule four = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "found", "3.0.2", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "found", "3.0.2", null, "")); // one soft deleted final SoftwareModule deleted = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "deleted", "deleted", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "deleted", "deleted", null, "")); distributionSetManagement.createDistributionSet( - new DistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(deleted, four))); + new JpaDistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(deleted, four))); softwareManagement.deleteSoftwareModule(deleted); assertThat(softwareManagement.countSoftwareModulesAll()).as("Number of undeleted modules").isEqualTo(1); @@ -746,8 +754,8 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Checks that software module typeis found based on given name.") public void findSoftwareModuleTypeByName() { final SoftwareModuleType found = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); - softwareManagement.createSoftwareModuleType(new SoftwareModuleType("thetype2", "anothername", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); + softwareManagement.createSoftwareModuleType(new JpaSoftwareModuleType("thetype2", "anothername", "desc", 100)); assertThat(softwareManagement.findSoftwareModuleTypeByName("thename")).as("Type with given name") .isEqualTo(found); @@ -757,7 +765,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Verfies that it is not possible to create a type that alrady exists.") public void createSoftwareModuleTypeFailsWithExistingEntity() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); try { softwareManagement.createSoftwareModuleType(created); fail("should not have worked as module type already exists"); @@ -771,10 +779,10 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Description("Verfies that it is not possible to create a list of types where one already exists.") public void createSoftwareModuleTypesFailsWithExistingEntity() { final SoftwareModuleType created = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); try { softwareManagement.createSoftwareModuleType( - Lists.newArrayList(created, new SoftwareModuleType("anothertype", "anothername", "desc", 100))); + Lists.newArrayList(created, new JpaSoftwareModuleType("anothertype", "anothername", "desc", 100))); fail("should not have worked as module type already exists"); } catch (final EntityAlreadyExistsException e) { @@ -784,9 +792,9 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Verfies that multiple types are created as requested.") public void createMultipleoftwareModuleTypes() { - final List created = softwareManagement - .createSoftwareModuleType(Lists.newArrayList(new SoftwareModuleType("thetype", "thename", "desc", 100), - new SoftwareModuleType("thetype2", "thename2", "desc2", 100))); + final List created = softwareManagement.createSoftwareModuleType( + Lists.newArrayList(new JpaSoftwareModuleType("thetype", "thename", "desc", 100), + new JpaSoftwareModuleType("thetype2", "thename2", "desc2", 100))); assertThat(created.size()).as("Number of created types").isEqualTo(2); assertThat(softwareManagement.countSoftwareModuleTypesAll()).as("Number of types in repository").isEqualTo(5); @@ -797,23 +805,23 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void findSoftwareModuleByAssignedTo() { // test meta data final SoftwareModuleType testType = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("thetype", "thename", "desc", 100)); + .createSoftwareModuleType(new JpaSoftwareModuleType("thetype", "thename", "desc", 100)); final DistributionSetType testDsType = distributionSetManagement - .createDistributionSetType(new DistributionSetType("key", "name", "desc").addMandatoryModuleType(osType) - .addOptionalModuleType(testType)); + .createDistributionSetType(new JpaDistributionSetType("key", "name", "desc") + .addMandatoryModuleType(osType).addOptionalModuleType(testType)); // test modules - softwareManagement.createSoftwareModule(new SoftwareModule(testType, "asis", "found", null, "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(testType, "asis", "found", null, "")); final SoftwareModule one = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "b", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "b", null, "")); final SoftwareModule two = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "found", "c", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "found", "c", null, "")); // one soft deleted final SoftwareModule deleted = softwareManagement - .createSoftwareModule(new SoftwareModule(testType, "deleted", "deleted", null, "")); + .createSoftwareModule(new JpaSoftwareModule(testType, "deleted", "deleted", null, "")); final DistributionSet set = distributionSetManagement.createDistributionSet( - new DistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(one, deleted))); + new JpaDistributionSet("set", "1", "desc", testDsType, Lists.newArrayList(one, deleted))); softwareManagement.deleteSoftwareModule(deleted); assertThat(softwareManagement.findSoftwareModuleByAssignedTo(pageReq, set).getContent()) @@ -831,13 +839,13 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final String knownValue2 = "myKnownValue2"; final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); assertThat(ah.getOptLockRevision()).isEqualTo(1L); - final SoftwareModuleMetadata swMetadata1 = new SoftwareModuleMetadata(knownKey1, ah, knownValue1); + final SoftwareModuleMetadata swMetadata1 = new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1); - final SoftwareModuleMetadata swMetadata2 = new SoftwareModuleMetadata(knownKey2, ah, knownValue2); + final SoftwareModuleMetadata swMetadata2 = new JpaSoftwareModuleMetadata(knownKey2, ah, knownValue2); final List softwareModuleMetadata = softwareManagement .createSoftwareModuleMetadata(Lists.newArrayList(swMetadata1, swMetadata2)); @@ -848,7 +856,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(softwareModuleMetadata).hasSize(2); assertThat(softwareModuleMetadata.get(0)).isNotNull(); assertThat(softwareModuleMetadata.get(0).getValue()).isEqualTo(knownValue1); - assertThat(softwareModuleMetadata.get(0).getId().getKey()).isEqualTo(knownKey1); + assertThat(((JpaSoftwareModuleMetadata) softwareModuleMetadata.get(0)).getId().getKey()).isEqualTo(knownKey1); assertThat(softwareModuleMetadata.get(0).getSoftwareModule().getId()).isEqualTo(ah.getId()); } @@ -861,12 +869,12 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final String knownValue2 = "myKnownValue2"; final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); - softwareManagement.createSoftwareModuleMetadata(new SoftwareModuleMetadata(knownKey1, ah, knownValue1)); + softwareManagement.createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1)); try { - softwareManagement.createSoftwareModuleMetadata(new SoftwareModuleMetadata(knownKey1, ah, knownValue2)); + softwareManagement.createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue2)); fail("should not have worked as module metadata already exists"); } catch (final EntityAlreadyExistsException e) { @@ -883,13 +891,13 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // create a base software module final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); // initial opt lock revision must be 1 assertThat(ah.getOptLockRevision()).isEqualTo(1L); // create an software module meta data entry final List softwareModuleMetadata = softwareManagement.createSoftwareModuleMetadata( - Collections.singleton(new SoftwareModuleMetadata(knownKey, ah, knownValue))); + Collections.singleton(new JpaSoftwareModuleMetadata(knownKey, ah, knownValue))); assertThat(softwareModuleMetadata).hasSize(1); // base software module should have now the opt lock revision one // because we are modifying the @@ -915,7 +923,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // verify updated meta data contains the updated value assertThat(updated).isNotNull(); assertThat(updated.getValue()).isEqualTo(knownUpdateValue); - assertThat(updated.getId().getKey()).isEqualTo(knownKey); + assertThat(((JpaSoftwareModuleMetadata) updated).getId().getKey()).isEqualTo(knownKey); assertThat(updated.getSoftwareModule().getId()).isEqualTo(ah.getId()); } @@ -926,14 +934,14 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final String knownValue1 = "myKnownValue1"; SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); - ah = softwareManagement.createSoftwareModuleMetadata(new SoftwareModuleMetadata(knownKey1, ah, knownValue1)) + ah = softwareManagement.createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1)) .getSoftwareModule(); assertThat(softwareManagement.findSoftwareModuleById(ah.getId()).getMetadata()) .as("Contains the created metadata element") - .containsExactly(new SoftwareModuleMetadata(knownKey1, ah, knownValue1)); + .containsExactly(new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1)); softwareManagement.deleteSoftwareModuleMetadata(new SwMetadataCompositeKey(ah, knownKey1)); assertThat(softwareManagement.findSoftwareModuleById(ah.getId()).getMetadata()).as("Metadata elemenets are") @@ -947,9 +955,9 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { final String knownValue1 = "myKnownValue1"; SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); - ah = softwareManagement.createSoftwareModuleMetadata(new SoftwareModuleMetadata(knownKey1, ah, knownValue1)) + ah = softwareManagement.createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1)) .getSoftwareModule(); try { @@ -965,20 +973,20 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void findAllSoftwareModuleMetadataBySwId() { SoftwareModule sw1 = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); SoftwareModule sw2 = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "os", "1.0.1", null, "")); + .createSoftwareModule(new JpaSoftwareModule(osType, "os", "1.0.1", null, "")); for (int index = 0; index < 10; index++) { sw1 = softwareManagement - .createSoftwareModuleMetadata(new SoftwareModuleMetadata("key" + index, sw1, "value" + index)) + .createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata("key" + index, sw1, "value" + index)) .getSoftwareModule(); } for (int index = 0; index < 20; index++) { sw2 = softwareManagement - .createSoftwareModuleMetadata(new SoftwareModuleMetadata("key" + index, sw2, "value" + index)) + .createSoftwareModuleMetadata(new JpaSoftwareModuleMetadata("key" + index, sw2, "value" + index)) .getSoftwareModule(); } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java index 1a1632d32..261b921c8 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java @@ -18,8 +18,8 @@ import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.WithSpringAuthorityRule; import org.eclipse.hawkbit.report.model.TenantUsage; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.junit.Test; @@ -132,7 +132,7 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { } private void createTestArtifact(final byte[] random) { - SoftwareModule sm = new SoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", + JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1", "version 1", null, null); sm = softwareModuleRepository.save(sm); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java index 4c6af0d83..66ea38e77 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -21,6 +22,8 @@ import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; @@ -57,26 +60,26 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Full DS tag lifecycle tested. Create tags, assign them to sets and delete the tags.") public void createAndAssignAndDeleteDistributionSetTags() { - final List dsAs = TestDataUtil.generateDistributionSets("DS-A", 20, softwareManagement, - distributionSetManagement); - final List dsBs = TestDataUtil.generateDistributionSets("DS-B", 10, softwareManagement, - distributionSetManagement); - final List dsCs = TestDataUtil.generateDistributionSets("DS-C", 25, softwareManagement, - distributionSetManagement); - final List dsABs = TestDataUtil.generateDistributionSets("DS-AB", 5, softwareManagement, - distributionSetManagement); - final List dsACs = TestDataUtil.generateDistributionSets("DS-AC", 11, softwareManagement, - distributionSetManagement); - final List dsBCs = TestDataUtil.generateDistributionSets("DS-BC", 13, softwareManagement, - distributionSetManagement); - final List dsABCs = TestDataUtil.generateDistributionSets("DS-ABC", 9, softwareManagement, - distributionSetManagement); + final Collection dsAs = (Collection) TestDataUtil.generateDistributionSets("DS-A", 20, + softwareManagement, distributionSetManagement); + final Collection dsBs = (Collection) TestDataUtil.generateDistributionSets("DS-B", 10, + softwareManagement, distributionSetManagement); + final Collection dsCs = (Collection) TestDataUtil.generateDistributionSets("DS-C", 25, + softwareManagement, distributionSetManagement); + final Collection dsABs = (Collection) TestDataUtil.generateDistributionSets("DS-AB", 5, + softwareManagement, distributionSetManagement); + final Collection dsACs = (Collection) TestDataUtil.generateDistributionSets("DS-AC", 11, + softwareManagement, distributionSetManagement); + final Collection dsBCs = (Collection) TestDataUtil.generateDistributionSets("DS-BC", 13, + softwareManagement, distributionSetManagement); + final Collection dsABCs = (Collection) TestDataUtil.generateDistributionSets("DS-ABC", 9, + softwareManagement, distributionSetManagement); - final DistributionSetTag tagA = tagManagement.createDistributionSetTag(new DistributionSetTag("A")); - final DistributionSetTag tagB = tagManagement.createDistributionSetTag(new DistributionSetTag("B")); - final DistributionSetTag tagC = tagManagement.createDistributionSetTag(new DistributionSetTag("C")); - final DistributionSetTag tagX = tagManagement.createDistributionSetTag(new DistributionSetTag("X")); - final DistributionSetTag tagY = tagManagement.createDistributionSetTag(new DistributionSetTag("Y")); + final DistributionSetTag tagA = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A")); + final DistributionSetTag tagB = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("B")); + final DistributionSetTag tagC = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("C")); + final DistributionSetTag tagX = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("X")); + final DistributionSetTag tagY = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Y")); distributionSetManagement.toggleTagAssignment(dsAs, tagA); distributionSetManagement.toggleTagAssignment(dsBs, tagB); @@ -167,20 +170,20 @@ public class TagManagementTest extends AbstractIntegrationTest { @Description("Verifies the toogle mechanism by means on assigning tag if at least on DS in the list does not have" + "the tag yet. Unassign if all of them have the tag already.") public void assignAndUnassignDistributionSetTags() { - final List groupA = TestDataUtil.generateDistributionSets(20, softwareManagement, - distributionSetManagement); - final List groupB = TestDataUtil.generateDistributionSets("unassigned", 20, softwareManagement, - distributionSetManagement); + final Collection groupA = (Collection) TestDataUtil.generateDistributionSets(20, + softwareManagement, distributionSetManagement); + final Collection groupB = (Collection) TestDataUtil.generateDistributionSets("unassigned", 20, + softwareManagement, distributionSetManagement); final DistributionSetTag tag = tagManagement - .createDistributionSetTag(new DistributionSetTag("tag1", "tagdesc1", "")); + .createDistributionSetTag(new JpaDistributionSetTag("tag1", "tagdesc1", "")); // toggle A only -> A is now assigned DistributionSetTagAssignmentResult result = distributionSetManagement.toggleTagAssignment(groupA, tag); assertThat(result.getAlreadyAssigned()).isEqualTo(0); assertThat(result.getAssigned()).isEqualTo(20); - assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails( - groupA.stream().map(set -> set.getId()).collect(Collectors.toList()))); + assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement + .findDistributionSetsAll(groupA.stream().map(set -> set.getId()).collect(Collectors.toList()))); assertThat(result.getUnassigned()).isEqualTo(0); assertThat(result.getUnassignedEntity()).isEmpty(); assertThat(result.getDistributionSetTag()).isEqualTo(tag); @@ -189,8 +192,8 @@ public class TagManagementTest extends AbstractIntegrationTest { result = distributionSetManagement.toggleTagAssignment(concat(groupA, groupB), tag); assertThat(result.getAlreadyAssigned()).isEqualTo(20); assertThat(result.getAssigned()).isEqualTo(20); - assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails( - groupB.stream().map(set -> set.getId()).collect(Collectors.toList()))); + assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement + .findDistributionSetsAll(groupB.stream().map(set -> set.getId()).collect(Collectors.toList()))); assertThat(result.getUnassigned()).isEqualTo(0); assertThat(result.getUnassignedEntity()).isEmpty(); assertThat(result.getDistributionSetTag()).isEqualTo(tag); @@ -201,7 +204,7 @@ public class TagManagementTest extends AbstractIntegrationTest { assertThat(result.getAssigned()).isEqualTo(0); assertThat(result.getAssignedEntity()).isEmpty(); assertThat(result.getUnassigned()).isEqualTo(40); - assertThat(result.getUnassignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails( + assertThat(result.getUnassignedEntity()).containsAll(distributionSetManagement.findDistributionSetsAll( concat(groupB, groupA).stream().map(set -> set.getId()).collect(Collectors.toList()))); assertThat(result.getDistributionSetTag()).isEqualTo(tag); @@ -214,7 +217,7 @@ public class TagManagementTest extends AbstractIntegrationTest { final List groupA = targetManagement.createTargets(TestDataUtil.generateTargets(20, "")); final List groupB = targetManagement.createTargets(TestDataUtil.generateTargets(20, "groupb")); - final TargetTag tag = tagManagement.createTargetTag(new TargetTag("tag1", "tagdesc1", "")); + final TargetTag tag = tagManagement.createTargetTag(new JpaTargetTag("tag1", "tagdesc1", "")); // toggle A only -> A is now assigned TargetTagAssignmentResult result = targetManagement.toggleTagAssignment(groupA, tag); @@ -249,7 +252,7 @@ public class TagManagementTest extends AbstractIntegrationTest { } @SafeVarargs - private final List concat(final List... targets) { + private final Collection concat(final Collection... targets) { final List result = new ArrayList<>(); Arrays.asList(targets).forEach(result::addAll); return result; @@ -258,16 +261,16 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that all tags are retrieved through repository.") public void findAllTargetTags() { - final List tags = createTargetsWithTags(); + final List tags = createTargetsWithTags(); - assertThat(targetTagRepository.findAll()).isEqualTo(tagManagement.findAllTargetTags()).isEqualTo(tags) + assertThat(targetTagRepository.findAll()).isEqualTo(targetTagRepository.findAll()).isEqualTo(tags) .as("Wrong tag size").hasSize(20); } @Test @Description("Ensures that a created tag is persisted in the repository as defined.") public void createTargetTag() { - final Tag tag = tagManagement.createTargetTag(new TargetTag("kai1", "kai2", "colour")); + final Tag tag = tagManagement.createTargetTag(new JpaTargetTag("kai1", "kai2", "colour")); assertThat(targetTagRepository.findByNameEquals("kai1").getDescription()).as("wrong tag ed").isEqualTo("kai2"); assertThat(tagManagement.findTargetTag("kai1").getColour()).as("wrong tag found").isEqualTo("colour"); @@ -279,7 +282,7 @@ public class TagManagementTest extends AbstractIntegrationTest { public void deleteTargetTas() { // create test data - final Iterable tags = createTargetsWithTags(); + final Iterable tags = createTargetsWithTags(); final TargetTag toDelete = tags.iterator().next(); for (final Target target : targetRepository.findAll()) { @@ -296,13 +299,13 @@ public class TagManagementTest extends AbstractIntegrationTest { .doesNotContain(toDelete); } assertThat(targetTagRepository.findOne(toDelete.getId())).as("No tag should be found").isNull(); - assertThat(tagManagement.findAllTargetTags()).as("Wrong target tag size").hasSize(19); + assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(19); } @Test @Description("Tests the name update of a target tag.") public void updateTargetTag() { - final List tags = createTargetsWithTags(); + final List tags = createTargetsWithTags(); // change data final TargetTag savedAssigned = tags.iterator().next(); @@ -312,7 +315,7 @@ public class TagManagementTest extends AbstractIntegrationTest { tagManagement.updateTargetTag(savedAssigned); // check data - assertThat(tagManagement.findAllTargetTags()).as("Wrong target tag size").hasSize(tags.size()); + assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(tags.size()); assertThat(targetTagRepository.findOne(savedAssigned.getId()).getName()).as("wrong target tag is saved") .isEqualTo("test123"); assertThat(targetTagRepository.findOne(savedAssigned.getId()).getOptLockRevision()) @@ -322,7 +325,7 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that a created tag is persisted in the repository as defined.") public void createDistributionSetTag() { - final Tag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("kai1", "kai2", "colour")); + final Tag tag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("kai1", "kai2", "colour")); assertThat(distributionSetTagRepository.findByNameEquals("kai1").getDescription()).as("wrong tag found") .isEqualTo("kai2"); @@ -366,10 +369,10 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).") public void failedDuplicateTargetTagNameException() { - tagManagement.createTargetTag(new TargetTag("A")); + tagManagement.createTargetTag(new JpaTargetTag("A")); try { - tagManagement.createTargetTag(new TargetTag("A")); + tagManagement.createTargetTag(new JpaTargetTag("A")); fail("should not have worked as tag already exists"); } catch (final EntityAlreadyExistsException e) { @@ -379,8 +382,8 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).") public void failedDuplicateTargetTagNameExceptionAfterUpdate() { - tagManagement.createTargetTag(new TargetTag("A")); - final TargetTag tag = tagManagement.createTargetTag(new TargetTag("B")); + tagManagement.createTargetTag(new JpaTargetTag("A")); + final TargetTag tag = tagManagement.createTargetTag(new JpaTargetTag("B")); tag.setName("A"); try { @@ -394,9 +397,9 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).") public void failedDuplicateDsTagNameException() { - tagManagement.createDistributionSetTag(new DistributionSetTag("A")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A")); try { - tagManagement.createDistributionSetTag(new DistributionSetTag("A")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A")); fail("should not have worked as tag already exists"); } catch (final EntityAlreadyExistsException e) { @@ -406,8 +409,8 @@ public class TagManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).") public void failedDuplicateDsTagNameExceptionAfterUpdate() { - tagManagement.createDistributionSetTag(new DistributionSetTag("A")); - final DistributionSetTag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("B")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A")); + final DistributionSetTag tag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("B")); tag.setName("A"); try { @@ -448,19 +451,19 @@ public class TagManagementTest extends AbstractIntegrationTest { assertThat(distributionSetTagRepository.findAll()).as("Wrong size of tags").hasSize(20); } - private List createTargetsWithTags() { - targetManagement.createTargets(TestDataUtil.generateTargets(20)); + private List createTargetsWithTags() { + final List targets = targetManagement.createTargets(TestDataUtil.generateTargets(20)); final Iterable tags = tagManagement.createTargetTags(TestDataUtil.generateTargetTags(20)); - tags.forEach(tag -> targetManagement.toggleTagAssignment(targetRepository.findAll(), tag)); + tags.forEach(tag -> targetManagement.toggleTagAssignment(targets, tag)); - return tagManagement.findAllTargetTags(); + return targetTagRepository.findAll(); } private List createDsSetsWithTags() { - final List sets = TestDataUtil.generateDistributionSets(20, softwareManagement, - distributionSetManagement); + final Collection sets = (Collection) TestDataUtil.generateDistributionSets(20, + softwareManagement, distributionSetManagement); final Iterable tags = tagManagement .createDistributionSetTags(TestDataUtil.generateDistributionSetTags(20)); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagenmentTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagenmentTest.java index 99e08f331..498364cf9 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagenmentTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagenmentTest.java @@ -13,6 +13,7 @@ import static org.junit.Assert.fail; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.junit.Test; @@ -33,7 +34,7 @@ public class TargetFilterQueryManagenmentTest extends AbstractIntegrationTest { public void createTargetFilterQuery() { final String filterName = "new target filter"; final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement - .createTargetFilterQuery(new TargetFilterQuery(filterName, "name==PendingTargets001")); + .createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001")); assertEquals("Retrieved newly created custom target filter", targetFilterQuery, targetFilterQueryManagement.findTargetFilterQueryByName(filterName)); } @@ -43,11 +44,11 @@ public class TargetFilterQueryManagenmentTest extends AbstractIntegrationTest { public void createDuplicateTargetFilterQuery() { final String filterName = "new target filter duplicate"; targetFilterQueryManagement - .createTargetFilterQuery(new TargetFilterQuery(filterName, "name==PendingTargets001")); + .createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001")); try { targetFilterQueryManagement - .createTargetFilterQuery(new TargetFilterQuery(filterName, "name==PendingTargets001")); + .createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001")); fail("should not have worked as query already exists"); } catch (final EntityAlreadyExistsException e) { @@ -59,7 +60,7 @@ public class TargetFilterQueryManagenmentTest extends AbstractIntegrationTest { public void deleteTargetFilterQuery() { final String filterName = "delete_target_filter_query"; final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement - .createTargetFilterQuery(new TargetFilterQuery(filterName, "name==PendingTargets001")); + .createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001")); targetFilterQueryManagement.deleteTargetFilterQuery(targetFilterQuery.getId()); assertEquals("Returns null as the target filter is deleted", null, targetFilterQueryManagement.findTargetFilterQueryById(targetFilterQuery.getId())); @@ -71,7 +72,7 @@ public class TargetFilterQueryManagenmentTest extends AbstractIntegrationTest { public void updateTargetFilterQuery() { final String filterName = "target_filter_01"; final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement - .createTargetFilterQuery(new TargetFilterQuery(filterName, "name==PendingTargets001")); + .createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001")); final String newQuery = "status==UNKNOWN"; targetFilterQuery.setQuery(newQuery); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java index 6b509b257..4ff845e1a 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java @@ -19,17 +19,20 @@ import java.util.stream.Collectors; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.eclipse.hawkbit.repository.specifications.TargetSpecifications; import org.junit.Test; import org.springframework.data.domain.Slice; @@ -50,10 +53,10 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { + "That includes both the test itself, as a count operation with the same filters " + "and query definitions by RSQL (named and un-named).") public void targetSearchWithVariousFilterCombinations() { - final TargetTag targTagX = tagManagement.createTargetTag(new TargetTag("TargTag-X")); - final TargetTag targTagY = tagManagement.createTargetTag(new TargetTag("TargTag-Y")); - final TargetTag targTagZ = tagManagement.createTargetTag(new TargetTag("TargTag-Z")); - final TargetTag targTagW = tagManagement.createTargetTag(new TargetTag("TargTag-W")); + final TargetTag targTagX = tagManagement.createTargetTag(new JpaTargetTag("TargTag-X")); + final TargetTag targTagY = tagManagement.createTargetTag(new JpaTargetTag("TargTag-Y")); + final TargetTag targTagZ = tagManagement.createTargetTag(new JpaTargetTag("TargTag-Z")); + final TargetTag targTagW = tagManagement.createTargetTag(new JpaTargetTag("TargTag-W")); final DistributionSet setA = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement); @@ -96,7 +99,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { final Action action = deploymentManagement.findActionWithDetails(actionId); action.setStatus(Status.FINISHED); controllerManagament.addUpdateActionStatus( - new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); + new JpaActionStatus((JpaAction) action, Status.FINISHED, System.currentTimeMillis(), "message")); deploymentManagement.assignDistributionSet(setA.getId(), installedC); final List unknown = new ArrayList<>(); @@ -174,13 +177,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, installedSet.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1) .as("and contains the following elements").containsExactly(expectedIdName) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @@ -200,13 +203,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, both, null, null, Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(200).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } private static List convertToIdNames(final List expected) { @@ -234,13 +237,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -260,13 +263,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -286,13 +289,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-B%", setA.getId(), Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements") .containsExactly(expectedIdName).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -312,13 +315,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements") .containsExactly(expectedIdName).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -337,13 +340,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -361,14 +364,14 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat( targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE, new String[0])) .as("has number of elements").hasSize(3).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -388,13 +391,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-B%", null, Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(99).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -412,13 +415,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-A%", null, Boolean.FALSE, new String[0])).as("has number of elements").hasSize(99).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -435,12 +438,12 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size()) .as("and NAMED filter query returns the same result").hasSize(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent().size()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, setA.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(0) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @Step @@ -459,13 +462,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE, targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(198) .as("and contains the following elements").containsAll(expectedIdNames) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @Step @@ -483,14 +486,14 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat( targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE, new String[0])) .as("has number of elements").hasSize(397).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -509,13 +512,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements") .containsExactly(expectedIdName).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -532,13 +535,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, setA.getId(), Boolean.FALSE, new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -554,12 +557,12 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size()) .as("and NAMED filter query returns the same result").hasSize(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent().size()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagX.getName())).as("has number of elements").hasSize(0) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @Step @@ -575,12 +578,12 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size()) .as("and NAMED filter query returns the same result").hasSize(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent().size()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(0) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @Step @@ -599,13 +602,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements") .containsExactly(expectedIdName).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @Step @@ -623,13 +626,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-B%", null, Boolean.FALSE, targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(100) .as("and contains the following elements").containsAll(expectedIdNames) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findAllTargetIdsByTargetFilterQuery(pageReq, new TargetFilterQuery("test", query))); + .findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query))); } @@ -653,13 +656,13 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { .as("and filter query returns the same result") .containsAll(targetManagement.findTargetsAll(query, pageReq).getContent()) .as("and NAMED filter query returns the same result").containsAll(targetManagement - .findTargetsAll(new TargetFilterQuery("test", query), pageReq).getContent()); + .findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent()); assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, null, Boolean.FALSE, targTagD.getName())).as("has number of elements").hasSize(200).as("and contains the following elements") .containsAll(expectedIdNames).as("and NAMED filter query returns the same result") .containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq, - new TargetFilterQuery("test", query))); + new JpaTargetFilterQuery("test", query))); } @@ -698,7 +701,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { final Comparator byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId()); assertThat(result.getNumberOfElements()).isEqualTo(9); - final List expected = new ArrayList(); + final List expected = new ArrayList<>(); Collections.sort(targInstalled, byId); Collections.sort(targAssigned, byId); Collections.sort(notAssigned, byId); @@ -730,34 +733,6 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { } - @Test - @Description("Verfies that targets with given assigned DS and additonal specification are returned from repository.") - public void findTargetByAssignedDistributionSetWithAdditonalSpecification() { - final DistributionSet assignedSet = TestDataUtil.generateDistributionSet("", softwareManagement, - distributionSetManagement); - final DistributionSet installedSet = TestDataUtil.generateDistributionSet("another", softwareManagement, - distributionSetManagement); - targetManagement.createTargets(TestDataUtil.generateTargets(10, "unassigned")); - List assignedtargets = targetManagement.createTargets(TestDataUtil.generateTargets(10, "assigned")); - - // set on installed and assign another one - deploymentManagement.assignDistributionSet(installedSet, assignedtargets).getActions().forEach(actionId -> { - final Action action = deploymentManagement.findActionWithDetails(actionId); - action.setStatus(Status.FINISHED); - controllerManagament.addUpdateActionStatus( - new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); - }); - deploymentManagement.assignDistributionSet(assignedSet, assignedtargets); - - assignedtargets = targetManagement.findTargetByControllerID( - assignedtargets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())); - - assertThat(targetManagement.findTargetByAssignedDistributionSet(assignedSet.getId(), - TargetSpecifications.hasInstalledDistributionSet(installedSet.getId()), pageReq)) - .as("Contains the assigned targets").containsAll(assignedtargets) - .as("and that means the following expected amount").hasSize(10); - } - @Test @Description("Verfies that targets with given installed DS are returned from repository.") public void findTargetByInstalledDistributionSet() { @@ -773,7 +748,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { final Action action = deploymentManagement.findActionWithDetails(actionId); action.setStatus(Status.FINISHED); controllerManagament.addUpdateActionStatus( - new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); + new JpaActionStatus((JpaAction) action, Status.FINISHED, System.currentTimeMillis(), "message")); }); deploymentManagement.assignDistributionSet(assignedSet, installedtargets); @@ -787,41 +762,11 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { } - @Test - @Description("Verfies that targets with given installed DS and additonal specification are returned from repository.") - public void findTargetByInstalledDistributionSetWithAdditonalSpecification() { - final DistributionSet assignedSet = TestDataUtil.generateDistributionSet("", softwareManagement, - distributionSetManagement); - final DistributionSet installedSet = TestDataUtil.generateDistributionSet("another", softwareManagement, - distributionSetManagement); - targetManagement.createTargets(TestDataUtil.generateTargets(10, "unassigned")); - List installedtargets = targetManagement.createTargets(TestDataUtil.generateTargets(10, "assigned")); - - // set on installed and assign another one - deploymentManagement.assignDistributionSet(installedSet, installedtargets).getActions().forEach(actionId -> { - final Action action = deploymentManagement.findActionWithDetails(actionId); - action.setStatus(Status.FINISHED); - controllerManagament.addUpdateActionStatus( - new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); - }); - deploymentManagement.assignDistributionSet(assignedSet, installedtargets); - - // get final updated version of targets - installedtargets = targetManagement.findTargetByControllerID( - installedtargets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())); - - assertThat(targetManagement.findTargetByInstalledDistributionSet(installedSet.getId(), - TargetSpecifications.hasAssignedDistributionSet(assignedSet.getId()), pageReq)) - .as("Contains the assigned targets").containsAll(installedtargets) - .as("and that means the following expected amount").hasSize(10); - - } - private List sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable targs, final Status status, final String... msgs) { final List result = new ArrayList(); for (final Target t : targs) { - final List findByTarget = actionRepository.findByTarget(t); + final List findByTarget = actionRepository.findByTarget((JpaTarget) t); for (final Action action : findByTarget) { result.add(sendUpdateActionStatusToTarget(status, action, t, msgs)); } @@ -833,7 +778,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest { final String... msgs) { updActA.setStatus(status); - final ActionStatus statusMessages = new ActionStatus(); + final ActionStatus statusMessages = new JpaActionStatus(); statusMessages.setAction(updActA); statusMessages.setOccurredAt(System.currentTimeMillis()); statusMessages.setStatus(status); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java index ae4447fc6..c2d7a0a4f 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java @@ -34,14 +34,16 @@ import org.eclipse.hawkbit.WithSpringAuthorityRule; import org.eclipse.hawkbit.WithUser; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.TenantNotExistException; -import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetIdName; -import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetTag; import org.junit.Test; import org.springframework.data.domain.PageRequest; @@ -61,7 +63,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { @WithUser(tenantId = "tenantWhichDoesNotExists", allSpPermissions = true, autoCreateTenant = false) public void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() { try { - targetManagement.createTarget(new Target("targetId123")); + targetManagement.createTarget(new JpaTarget("targetId123")); fail("should not be possible as the tenant does not exist"); } catch (final TenantNotExistException e) { // ok @@ -72,14 +74,14 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Description("Verify that a target with empty controller id cannot be created") public void createTargetWithNoControllerId() { try { - targetManagement.createTarget(new Target("")); + targetManagement.createTarget(new JpaTarget("")); fail("target with empty controller id should not be created"); } catch (final ConstraintViolationException e) { // ok } try { - targetManagement.createTarget(new Target(null)); + targetManagement.createTarget(new JpaTarget(null)); fail("target with empty controller id should not be created"); } catch (final ConstraintViolationException e) { // ok @@ -90,13 +92,13 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Description("Ensures that targets can assigned and unassigned to a target tag. Not exists target will be ignored for the assignment.") public void assignAndUnassignTargetsToTag() { final List assignTarget = new ArrayList(); - assignTarget.add(targetManagement.createTarget(new Target("targetId123")).getControllerId()); - assignTarget.add(targetManagement.createTarget(new Target("targetId1234")).getControllerId()); - assignTarget.add(targetManagement.createTarget(new Target("targetId1235")).getControllerId()); - assignTarget.add(targetManagement.createTarget(new Target("targetId1236")).getControllerId()); + assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId123")).getControllerId()); + assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1234")).getControllerId()); + assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1235")).getControllerId()); + assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1236")).getControllerId()); assignTarget.add("NotExist"); - final TargetTag targetTag = tagManagement.createTargetTag(new TargetTag("Tag1")); + final TargetTag targetTag = tagManagement.createTargetTag(new JpaTargetTag("Tag1")); final List assignedTargets = targetManagement.assignTag(assignTarget, targetTag); assertThat(assignedTargets.size()).as("Assigned targets are wrong").isEqualTo(4); @@ -125,7 +127,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Test @Description("Ensures that targets can deleted e.g. test all cascades") public void deleteAndCreateTargets() { - Target target = targetManagement.createTarget(new Target("targetId123")); + Target target = targetManagement.createTarget(new JpaTarget("targetId123")); assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1); targetManagement.deleteTargets(target.getId()); assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0); @@ -137,7 +139,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { final List targets = new ArrayList(); for (int i = 0; i < 5; i++) { - target = targetManagement.createTarget(new Target("" + i)); + target = targetManagement.createTarget(new JpaTarget("" + i)); targets.add(target.getId()); targets.add(createTargetWithAttributes("" + (i * i + 1000)).getId()); } @@ -147,7 +149,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { } private Target createTargetWithAttributes(final String controllerId) { - Target target = new Target(controllerId); + Target target = new JpaTarget(controllerId); final Map testData = new HashMap<>(); testData.put("test1", "testdata1"); @@ -184,10 +186,10 @@ public class TargetManagementTest extends AbstractIntegrationTest { final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(set.getId(), "4711"); - final Action action = deploymentManagement.findActionWithDetails(result.getActions().get(0)); + final JpaAction action = (JpaAction) deploymentManagement.findActionWithDetails(result.getActions().get(0)); action.setStatus(Status.FINISHED); controllerManagament.addUpdateActionStatus( - new ActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); + new JpaActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message")); deploymentManagement.assignDistributionSet(set2.getId(), "4711"); target = targetManagement.findTargetByControllerIDWithDetails("4711"); @@ -231,9 +233,9 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Test @Description("Checks if the EntityAlreadyExistsException is thrown if a single target with the same controller ID are created twice.") public void createTargetDuplicate() { - targetManagement.createTarget(new Target("4711")); + targetManagement.createTarget(new JpaTarget("4711")); try { - targetManagement.createTarget(new Target("4711")); + targetManagement.createTarget(new JpaTarget("4711")); fail("Target already exists"); } catch (final EntityAlreadyExistsException e) { } @@ -338,7 +340,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { final Target savedExtra = targetManagement.createTarget(extra); - Iterable allFound = targetRepository.findAll(); + final Iterable allFound = targetRepository.findAll(); assertThat(Long.valueOf(firstList.size())).as("List size of targets") .isEqualTo(firstSaved.spliterator().getExactSizeIfKnown()); @@ -391,11 +393,11 @@ public class TargetManagementTest extends AbstractIntegrationTest { targetManagement.deleteTargets(deletedTargetIDs); - allFound = targetManagement.findTargetsAll(new PageRequest(0, 200)).getContent(); + final List found = targetManagement.findTargetsAll(new PageRequest(0, 200)).getContent(); assertThat(firstSaved.spliterator().getExactSizeIfKnown() - nr2Del).as("Size of splited list") - .isEqualTo(allFound.spliterator().getExactSizeIfKnown()); + .isEqualTo(found.spliterator().getExactSizeIfKnown()); - assertThat(allFound).as("Not all undeleted found").doesNotContain(deletedTargets); + assertThat(found).as("Not all undeleted found").doesNotContain(deletedTargets); } @Test @@ -404,18 +406,18 @@ public class TargetManagementTest extends AbstractIntegrationTest { Iterable ts = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(100, "myCtrlID", "first description")); - final Map attribs = new HashMap(); + final Map attribs = new HashMap<>(); attribs.put("a.b.c", "abc"); attribs.put("x.y.z", ""); attribs.put("1.2.3", "123"); attribs.put("1.2.3.4", "1234"); attribs.put("1.2.3.4.5", "12345"); - final Set attribs2Del = new HashSet(); + final Set attribs2Del = new HashSet<>(); attribs2Del.add("x.y.z"); attribs2Del.add("1.2.3"); for (final Target t : ts) { - TargetInfo targetInfo = t.getTargetInfo(); + JpaTargetInfo targetInfo = (JpaTargetInfo) t.getTargetInfo(); targetInfo.setNew(false); for (final Entry attrib : attribs.entrySet()) { final String key = attrib.getKey(); @@ -460,7 +462,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { for (final Target ta : ts2DelAllAttribs) { final Target t = targetManagement.findTargetByControllerIDWithDetails(ta.getControllerId()); - final TargetInfo targetStatus = t.getTargetInfo(); + final JpaTargetInfo targetStatus = (JpaTargetInfo) t.getTargetInfo(); targetStatus.getControllerAttributes().clear(); targetInfoRepository.save(targetStatus); } @@ -468,7 +470,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { for (final Target ta : ts2DelAttribs) { final Target t = targetManagement.findTargetByControllerIDWithDetails(ta.getControllerId()); - final TargetInfo targetStatus = t.getTargetInfo(); + final JpaTargetInfo targetStatus = (JpaTargetInfo) t.getTargetInfo(); for (final String attribKey : attribs2Del) { targetStatus.getControllerAttributes().remove(attribKey); } @@ -477,7 +479,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { // only the number of the remaining targets and controller attributes // are checked - final Iterable restTS = targetRepository.findAll(); + final Iterable restTS = targetRepository.findAll(); restTarget_: for (final Target targetl : restTS) { final Target target = targetManagement.findTargetByControllerIDWithDetails(targetl.getControllerId()); @@ -552,10 +554,10 @@ public class TargetManagementTest extends AbstractIntegrationTest { final List tagABCTargets = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(10, "tagABCTargets", "first description")); - final TargetTag tagA = tagManagement.createTargetTag(new TargetTag("A")); - final TargetTag tagB = tagManagement.createTargetTag(new TargetTag("B")); - final TargetTag tagC = tagManagement.createTargetTag(new TargetTag("C")); - tagManagement.createTargetTag(new TargetTag("X")); + final TargetTag tagA = tagManagement.createTargetTag(new JpaTargetTag("A")); + final TargetTag tagB = tagManagement.createTargetTag(new JpaTargetTag("B")); + final TargetTag tagC = tagManagement.createTargetTag(new JpaTargetTag("C")); + tagManagement.createTargetTag(new JpaTargetTag("X")); // doing different assignments targetManagement.toggleTagAssignment(tagATargets, tagA); @@ -610,9 +612,9 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Test @Description("Tests the unassigment of tags to multiple targets.") public void targetTagBulkUnassignments() { - final TargetTag targTagA = tagManagement.createTargetTag(new TargetTag("Targ-A-Tag")); - final TargetTag targTagB = tagManagement.createTargetTag(new TargetTag("Targ-B-Tag")); - final TargetTag targTagC = tagManagement.createTargetTag(new TargetTag("Targ-C-Tag")); + final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag")); + final TargetTag targTagB = tagManagement.createTargetTag(new JpaTargetTag("Targ-B-Tag")); + final TargetTag targTagC = tagManagement.createTargetTag(new JpaTargetTag("Targ-C-Tag")); final List targAs = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description")); @@ -673,7 +675,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Test @Description("Retrieves targets by ID with lazy loading of the tags. Checks the successfull load.") public void findTargetsByControllerIDsWithTags() { - final TargetTag targTagA = tagManagement.createTargetTag(new TargetTag("Targ-A-Tag")); + final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag")); final List targAs = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description")); @@ -711,7 +713,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Description("Test that NO TAG functionality which gives all targets with no tag assigned.") public void findTargetsWithNoTag() { - final TargetTag targTagA = tagManagement.createTargetTag(new TargetTag("Targ-A-Tag")); + final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag")); final List targAs = targetManagement .createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description")); targetManagement.toggleTagAssignment(targAs, targTagA); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/model/ModelEqualsHashcodeTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/model/ModelEqualsHashcodeTest.java index 45e56167a..c8f34cd48 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/model/ModelEqualsHashcodeTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/model/ModelEqualsHashcodeTest.java @@ -11,6 +11,12 @@ package org.eclipse.hawkbit.repository.model; import static org.fest.assertions.api.Assertions.assertThat; import org.eclipse.hawkbit.AbstractIntegrationTest; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; import org.junit.Test; import ru.yandex.qatools.allure.annotations.Description; @@ -25,29 +31,29 @@ public class ModelEqualsHashcodeTest extends AbstractIntegrationTest { @Description("Verfies that different objects even with identical primary key, version and tenant " + "return different hash codes.") public void differentEntitiesReturnDifferentHashCodes() { - assertThat(new Action().hashCode()).as("action should have different hashcode than action status") - .isNotEqualTo(new ActionStatus().hashCode()); - assertThat(new DistributionSet().hashCode()) + assertThat(new JpaAction().hashCode()).as("action should have different hashcode than action status") + .isNotEqualTo(new JpaActionStatus().hashCode()); + assertThat(new JpaDistributionSet().hashCode()) .as("Distribution set should have different hashcode than software module") - .isNotEqualTo(new SoftwareModule().hashCode()); - assertThat(new DistributionSet().hashCode()) + .isNotEqualTo(new JpaSoftwareModule().hashCode()); + assertThat(new JpaDistributionSet().hashCode()) .as("Distribution set should have different hashcode than action status") - .isNotEqualTo(new ActionStatus().hashCode()); - assertThat(new DistributionSetType().hashCode()) + .isNotEqualTo(new JpaActionStatus().hashCode()); + assertThat(new JpaDistributionSetType().hashCode()) .as("Distribution set type should have different hashcode than action status") - .isNotEqualTo(new ActionStatus().hashCode()); + .isNotEqualTo(new JpaActionStatus().hashCode()); } @Test @Description("Verfies that different object even with identical primary key, version and tenant " + "are not equal.") public void differentEntitiesAreNotEqual() { - assertThat(new Action().equals(new ActionStatus())).as("action equals action status").isFalse(); - assertThat(new DistributionSet().equals(new SoftwareModule())).as("Distribution set equals software module") + assertThat(new JpaAction().equals(new JpaActionStatus())).as("action equals action status").isFalse(); + assertThat(new JpaDistributionSet().equals(new JpaSoftwareModule())) + .as("Distribution set equals software module").isFalse(); + assertThat(new JpaDistributionSet().equals(new JpaActionStatus())).as("Distribution set equals action status") .isFalse(); - assertThat(new DistributionSet().equals(new ActionStatus())).as("Distribution set equals action status") - .isFalse(); - assertThat(new DistributionSetType().equals(new ActionStatus())) + assertThat(new JpaDistributionSetType().equals(new JpaActionStatus())) .as("Distribution set type equals action status").isFalse(); } @@ -55,9 +61,9 @@ public class ModelEqualsHashcodeTest extends AbstractIntegrationTest { @Description("Verfies that updated entities are not equal.") public void changedEntitiesAreNotEqual() { final SoftwareModuleType type = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test", "test", "test", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1)); assertThat(type).as("persited entity is not equal to regular object") - .isNotEqualTo(new SoftwareModuleType("test", "test", "test", 1)); + .isNotEqualTo(new JpaSoftwareModuleType("test", "test", "test", 1)); type.setDescription("another"); final SoftwareModuleType updated = softwareManagement.updateSoftwareModuleType(type); @@ -68,9 +74,9 @@ public class ModelEqualsHashcodeTest extends AbstractIntegrationTest { @Description("Verify that no proxy of the entity manager has an influence on the equals or hashcode result.") public void managedEntityIsEqualToUnamangedObjectWithSameKey() { final SoftwareModuleType type = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test", "test", "test", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1)); - final SoftwareModuleType mock = new SoftwareModuleType("test", "test", "test", 1); + final JpaSoftwareModuleType mock = new JpaSoftwareModuleType("test", "test", "test", 1); mock.setId(type.getId()); mock.setOptLockRevision(type.getOptLockRevision()); mock.setTenant(type.getTenant()); @@ -84,9 +90,9 @@ public class ModelEqualsHashcodeTest extends AbstractIntegrationTest { @Description("Verfies that updated entities do not have the same hashcode.") public void updatedEntitiesHaveDifferentHashcodes() { final SoftwareModuleType type = softwareManagement - .createSoftwareModuleType(new SoftwareModuleType("test", "test", "test", 1)); + .createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1)); assertThat(type.hashCode()).as("persited entity does not have same hashcode as regular object") - .isNotEqualTo(new SoftwareModuleType("test", "test", "test", 1).hashCode()); + .isNotEqualTo(new JpaSoftwareModuleType("test", "test", "test", 1).hashCode()); final int beforeChange = type.hashCode(); type.setDescription("another"); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java index 8b20af27d..b37d70a33 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java @@ -13,6 +13,8 @@ import static org.junit.Assert.fail; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.ActionFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaAction; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Target; @@ -20,7 +22,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -31,20 +32,20 @@ import ru.yandex.qatools.allure.annotations.Stories; public class RSQLActionFieldsTest extends AbstractIntegrationTest { private Target target; - private Action action; + private JpaAction action; @Before public void setupBeforeTest() { - target = new Target("targetId123"); + target = new JpaTarget("targetId123"); target.setDescription("targetId123"); targetManagement.createTarget(target); - action = new Action(); + action = new JpaAction(); action.setActionType(ActionType.SOFT); target.getActions().add(action); action.setTarget(target); actionRepository.save(action); for (int i = 0; i < 10; i++) { - final Action newAction = new Action(); + final JpaAction newAction = new JpaAction(); newAction.setActionType(ActionType.SOFT); newAction.setActive(i % 2 == 0); newAction.setTarget(target); @@ -79,10 +80,9 @@ public class RSQLActionFieldsTest extends AbstractIntegrationTest { private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) { - final Specification parse = RSQLUtility.parse(rsqlParam, ActionFields.class); - final Slice findEnitity = deploymentManagement.findActionsByTarget(parse, target, + final Slice findEnitity = deploymentManagement.findActionsByTarget(rsqlParam, target, new PageRequest(0, 100)); - final long countAllEntities = deploymentManagement.countActionsByTarget(parse, target); + final long countAllEntities = deploymentManagement.countActionsByTarget(rsqlParam, target); assertThat(findEnitity).isNotNull(); assertThat(countAllEntities).isEqualTo(expectedEntities); } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java index 6b1682820..bd46ed387 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java @@ -16,8 +16,9 @@ import java.util.Arrays; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.DistributionSetFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.junit.Before; import org.junit.Test; @@ -39,19 +40,20 @@ public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest { ds.setDescription("DS"); ds = distributionSetManagement.updateDistributionSet(ds); distributionSetManagement - .createDistributionSetMetadata(new DistributionSetMetadata("metaKey", ds, "metaValue")); + .createDistributionSetMetadata(new JpaDistributionSetMetadata("metaKey", ds, "metaValue")); DistributionSet ds2 = TestDataUtil .generateDistributionSets("NewDS", 3, softwareManagement, distributionSetManagement).get(0); ds2.setDescription("DS%"); ds2 = distributionSetManagement.updateDistributionSet(ds2); - distributionSetManagement.createDistributionSetMetadata(new DistributionSetMetadata("metaKey", ds2, "value")); + distributionSetManagement + .createDistributionSetMetadata(new JpaDistributionSetMetadata("metaKey", ds2, "value")); - final DistributionSetTag targetTag = tagManagement.createDistributionSetTag(new DistributionSetTag("Tag1")); - tagManagement.createDistributionSetTag(new DistributionSetTag("Tag2")); - tagManagement.createDistributionSetTag(new DistributionSetTag("Tag3")); - tagManagement.createDistributionSetTag(new DistributionSetTag("Tag4")); + final DistributionSetTag targetTag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag1")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag2")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag3")); + tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag4")); distributionSetManagement.assignTag(Arrays.asList(ds.getId(), ds2.getId()), targetTag); } @@ -137,8 +139,8 @@ public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest { } private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) { - final Page find = distributionSetManagement.findDistributionSetsAll( - RSQLUtility.parse(rsqlParam, DistributionSetFields.class), new PageRequest(0, 100), false); + final Page find = distributionSetManagement.findDistributionSetsAll(rsqlParam, + new PageRequest(0, 100), false); final long countAll = find.getTotalElements(); assertThat(find).as("Founded entity is should not be null").isNotNull(); assertThat(countAll).as("Founded entity size is wrong").isEqualTo(excpectedEntity); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetMetadataFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetMetadataFieldsTest.java index 755e5a61f..09c1e8dd0 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetMetadataFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetMetadataFieldsTest.java @@ -16,6 +16,7 @@ import java.util.List; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.junit.Before; @@ -41,7 +42,7 @@ public class RSQLDistributionSetMetadataFieldsTest extends AbstractIntegrationTe final List metadata = new ArrayList<>(); for (int i = 0; i < 5; i++) { - metadata.add(new DistributionSetMetadata("" + i, distributionSet, "" + i)); + metadata.add(new JpaDistributionSetMetadata("" + i, distributionSet, "" + i)); } distributionSetManagement.createDistributionSetMetadata(metadata); @@ -68,8 +69,7 @@ public class RSQLDistributionSetMetadataFieldsTest extends AbstractIntegrationTe private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) { final Page findEnitity = distributionSetManagement - .findDistributionSetMetadataByDistributionSetId(distributionSetId, - RSQLUtility.parse(rsqlParam, DistributionSetMetadataFields.class), new PageRequest(0, 100)); + .findDistributionSetMetadataByDistributionSetId(distributionSetId, rsqlParam, new PageRequest(0, 100)); final long countAllEntities = findEnitity.getTotalElements(); assertThat(findEnitity).isNotNull(); assertThat(countAllEntities).isEqualTo(expectedEntities); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLRolloutGroupFields.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLRolloutGroupFields.java index 18da430c7..83c31b31a 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLRolloutGroupFields.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLRolloutGroupFields.java @@ -13,11 +13,12 @@ import static org.fest.assertions.api.Assertions.assertThat; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.RolloutGroupFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditionBuilder; +import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditionBuilder; -import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.junit.Before; import org.junit.Test; import org.springframework.data.domain.Page; @@ -75,8 +76,8 @@ public class RSQLRolloutGroupFields extends AbstractIntegrationTest { } private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) { - final Page findTargetPage = rolloutGroupManagement.findRolloutGroupsAll(rollout, - RSQLUtility.parse(rsqlParam, RolloutGroupFields.class), new PageRequest(0, 100)); + final Page findTargetPage = rolloutGroupManagement.findRolloutGroupsAll(rollout, rsqlParam, + new PageRequest(0, 100)); final long countTargetsAll = findTargetPage.getTotalElements(); assertThat(findTargetPage).isNotNull(); assertThat(countTargetsAll).isEqualTo(expcetedTargets); @@ -84,7 +85,7 @@ public class RSQLRolloutGroupFields extends AbstractIntegrationTest { private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, final String targetFilterQuery) { - final Rollout rollout = new Rollout(); + final Rollout rollout = new JpaRollout(); rollout.setDistributionSet(distributionSetManagement.findDistributionSetById(distributionSetId)); rollout.setName(name); rollout.setTargetFilterQuery(targetFilterQuery); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleFieldTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleFieldTest.java index 0c113fd2b..b049daa0c 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleFieldTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleFieldTest.java @@ -12,6 +12,8 @@ import static org.fest.assertions.api.Assertions.assertThat; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.junit.Before; @@ -29,18 +31,18 @@ public class RSQLSoftwareModuleFieldTest extends AbstractIntegrationTest { @Before public void setupBeforeTest() { - final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", "agent-hub", "")); - softwareManagement.createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", "aa", "")); - softwareManagement.createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", "aa", "")); + final JpaSoftwareModule ah = (JpaSoftwareModule) softwareManagement + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "agent-hub", "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", "aa", "")); + softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", "aa", "")); - final SoftwareModule ah2 = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub2", "1.0.1", "agent-hub2", "")); + final JpaSoftwareModule ah2 = (JpaSoftwareModule) softwareManagement + .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub2", "1.0.1", "agent-hub2", "")); - final SoftwareModuleMetadata softwareModuleMetadata = new SoftwareModuleMetadata("metaKey", ah, "metaValue"); + final SoftwareModuleMetadata softwareModuleMetadata = new JpaSoftwareModuleMetadata("metaKey", ah, "metaValue"); softwareManagement.createSoftwareModuleMetadata(softwareModuleMetadata); - final SoftwareModuleMetadata softwareModuleMetadata2 = new SoftwareModuleMetadata("metaKey", ah2, "value"); + final SoftwareModuleMetadata softwareModuleMetadata2 = new JpaSoftwareModuleMetadata("metaKey", ah2, "value"); softwareManagement.createSoftwareModuleMetadata(softwareModuleMetadata2); } @@ -101,8 +103,8 @@ public class RSQLSoftwareModuleFieldTest extends AbstractIntegrationTest { } private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) { - final Page find = softwareManagement.findSoftwareModulesByPredicate( - RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class), new PageRequest(0, 100)); + final Page find = softwareManagement.findSoftwareModulesByPredicate(rsqlParam, + new PageRequest(0, 100)); final long countAll = find.getTotalElements(); assertThat(find).isNotNull(); assertThat(countAll).isEqualTo(excpectedEntity); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleMetadataFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleMetadataFieldsTest.java index 44fa3e3cd..362428887 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleMetadataFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleMetadataFieldsTest.java @@ -16,6 +16,8 @@ import java.util.List; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.junit.Before; @@ -36,13 +38,13 @@ public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractIntegrationTes @Before public void setupBeforeTest() { final SoftwareModule softwareModule = softwareManagement.createSoftwareModule( - new SoftwareModule(TestDataUtil.findOrCreateSoftwareModuleType(softwareManagement, "application"), + new JpaSoftwareModule(TestDataUtil.findOrCreateSoftwareModuleType(softwareManagement, "application"), "application", "1.0.0", "Desc", "vendor Limited, California")); softwareModuleId = softwareModule.getId(); final List metadata = new ArrayList<>(); for (int i = 0; i < 5; i++) { - metadata.add(new SoftwareModuleMetadata("" + i, softwareModule, "" + i)); + metadata.add(new JpaSoftwareModuleMetadata("" + i, softwareModule, "" + i)); } softwareManagement.createSoftwareModuleMetadata(metadata); @@ -70,8 +72,7 @@ public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractIntegrationTes private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) { final Page findEnitity = softwareManagement - .findSoftwareModuleMetadataBySoftwareModuleId(softwareModuleId, - RSQLUtility.parse(rsqlParam, SoftwareModuleMetadataFields.class), new PageRequest(0, 100)); + .findSoftwareModuleMetadataBySoftwareModuleId(softwareModuleId, rsqlParam, new PageRequest(0, 100)); final long countAllEntities = findEnitity.getTotalElements(); assertThat(findEnitity).isNotNull(); assertThat(countAllEntities).isEqualTo(expectedEntities); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java index 268bddf50..37a501a3f 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java @@ -59,8 +59,8 @@ public class RSQLSoftwareModuleTypeFieldsTest extends AbstractIntegrationTest { } private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) { - final Page find = softwareManagement.findSoftwareModuleTypesByPredicate( - RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class), new PageRequest(0, 100)); + final Page find = softwareManagement.findSoftwareModuleTypesByPredicate(rsqlParam, + new PageRequest(0, 100)); final long countAll = find.getTotalElements(); assertThat(find).isNotNull(); assertThat(countAll).isEqualTo(excpectedEntity); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTagFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTagFieldsTest.java index b35ed13d1..85474e70e 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTagFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTagFieldsTest.java @@ -12,6 +12,8 @@ import static org.fest.assertions.api.Assertions.assertThat; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.TagFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.TargetTag; import org.junit.Before; @@ -31,9 +33,9 @@ public class RSQLTagFieldsTest extends AbstractIntegrationTest { public void seuptBeforeTest() { for (int i = 0; i < 5; i++) { - final TargetTag targetTag = new TargetTag("" + i, "" + i, i % 2 == 0 ? "red" : "blue"); + final TargetTag targetTag = new JpaTargetTag("" + i, "" + i, i % 2 == 0 ? "red" : "blue"); tagManagement.createTargetTag(targetTag); - final DistributionSetTag distributionSetTag = new DistributionSetTag("" + i, "" + i, + final DistributionSetTag distributionSetTag = new JpaDistributionSetTag("" + i, "" + i, i % 2 == 0 ? "red" : "blue"); tagManagement.createDistributionSetTag(distributionSetTag); } @@ -101,8 +103,8 @@ public class RSQLTagFieldsTest extends AbstractIntegrationTest { private void assertRSQLQueryDistributionSet(final String rsqlParam, final long expectedEntities) { - final Page findEnitity = tagManagement - .findAllDistributionSetTags(RSQLUtility.parse(rsqlParam, TagFields.class), new PageRequest(0, 100)); + final Page findEnitity = tagManagement.findAllDistributionSetTags(rsqlParam, + new PageRequest(0, 100)); final long countAllEntities = findEnitity.getTotalElements(); assertThat(findEnitity).isNotNull(); assertThat(countAllEntities).isEqualTo(expectedEntities); @@ -110,8 +112,7 @@ public class RSQLTagFieldsTest extends AbstractIntegrationTest { private void assertRSQLQueryTarget(final String rsqlParam, final long expectedEntities) { - final Page findEnitity = tagManagement - .findAllTargetTags(RSQLUtility.parse(rsqlParam, TagFields.class), new PageRequest(0, 100)); + final Page findEnitity = tagManagement.findAllTargetTags(rsqlParam, new PageRequest(0, 100)); final long countAllEntities = findEnitity.getTotalElements(); assertThat(findEnitity).isNotNull(); assertThat(countAllEntities).isEqualTo(expectedEntities); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTargetFieldTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTargetFieldTest.java index 54efab860..37fffec99 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTargetFieldTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLTargetFieldTest.java @@ -16,6 +16,9 @@ import java.util.Arrays; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.repository.TargetFields; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; @@ -40,27 +43,27 @@ public class RSQLTargetFieldTest extends AbstractIntegrationTest { final DistributionSet ds = TestDataUtil.generateDistributionSet("AssignedDs", softwareManagement, distributionSetManagement); - final Target target = new Target("targetId123"); + final JpaTarget target = new JpaTarget("targetId123"); target.setDescription("targetId123"); - final TargetInfo targetInfo = new TargetInfo(target); + final TargetInfo targetInfo = new JpaTargetInfo(target); targetInfo.getControllerAttributes().put("revision", "1.1"); target.setTargetInfo(targetInfo); - target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING); + ((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING); targetManagement.createTarget(target); - final Target target2 = new Target("targetId1234"); + final JpaTarget target2 = new JpaTarget("targetId1234"); target2.setDescription("targetId1234"); - final TargetInfo targetInfo2 = new TargetInfo(target2); + final TargetInfo targetInfo2 = new JpaTargetInfo(target2); targetInfo2.getControllerAttributes().put("revision", "1.2"); target2.setTargetInfo(targetInfo2); targetManagement.createTarget(target2); - targetManagement.createTarget(new Target("targetId1235")); - targetManagement.createTarget(new Target("targetId1236")); + targetManagement.createTarget(new JpaTarget("targetId1235")); + targetManagement.createTarget(new JpaTarget("targetId1236")); - final TargetTag targetTag = tagManagement.createTargetTag(new TargetTag("Tag1")); - tagManagement.createTargetTag(new TargetTag("Tag2")); - tagManagement.createTargetTag(new TargetTag("Tag3")); - tagManagement.createTargetTag(new TargetTag("Tag4")); + final TargetTag targetTag = tagManagement.createTargetTag(new JpaTargetTag("Tag1")); + tagManagement.createTargetTag(new JpaTargetTag("Tag2")); + tagManagement.createTargetTag(new JpaTargetTag("Tag3")); + tagManagement.createTargetTag(new JpaTargetTag("Tag4")); targetManagement.assignTag(Arrays.asList(target.getControllerId(), target2.getControllerId()), targetTag); @@ -163,8 +166,7 @@ public class RSQLTargetFieldTest extends AbstractIntegrationTest { } private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) { - final Page findTargetPage = targetManagement - .findTargetsAll(RSQLUtility.parse(rsqlParam, TargetFields.class), new PageRequest(0, 100)); + final Page findTargetPage = targetManagement.findTargetsAll(rsqlParam, new PageRequest(0, 100)); final long countTargetsAll = findTargetPage.getTotalElements(); assertThat(findTargetPage).isNotNull(); assertThat(countTargetsAll).isEqualTo(expcetedTargets); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java index 73958e6fa..9cacd9a82 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java @@ -33,12 +33,17 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; @@ -129,7 +134,7 @@ public final class RepositoryDataGenerator { public void generateTestTagetGroup(final String group, final int sizeMultiplikator) { final DistributionSetTag dsTag = tagManagement - .createDistributionSetTag(new DistributionSetTag("For " + group + "s")); + .createDistributionSetTag(new JpaDistributionSetTag("For " + group + "s")); auditingHandler.setDateTimeProvider(() -> { final Calendar instance = Calendar.getInstance(); @@ -203,14 +208,14 @@ public final class RepositoryDataGenerator { "Controller retrieved update action and should start now the download."); // download - final ActionStatus download = new ActionStatus(); + final ActionStatus download = new JpaActionStatus(); download.setAction(action); download.setStatus(Status.DOWNLOAD); download.addMessage("Controller started download."); action = controllerManagement.addUpdateActionStatus(download); // warning - final ActionStatus warning = new ActionStatus(); + final ActionStatus warning = new JpaActionStatus(); warning.setAction(action); warning.setStatus(Status.WARNING); warning.addMessage("Some warning: " + jlorem.words(new Random().nextInt(50))); @@ -218,13 +223,13 @@ public final class RepositoryDataGenerator { // garbage for (int i = 0; i < new Random().nextInt(10); i++) { - final ActionStatus running = new ActionStatus(); + final ActionStatus running = new JpaActionStatus(); running.setAction(action); running.setStatus(Status.RUNNING); running.addMessage("Still running: " + jlorem.words(new Random().nextInt(50))); action = controllerManagement.addUpdateActionStatus(running); for (int g = 0; g < new Random().nextInt(5); g++) { - final ActionStatus rand = new ActionStatus(); + final ActionStatus rand = new JpaActionStatus(); rand.setAction(action); rand.setStatus(Status.RUNNING); rand.addMessage(jlorem.words(new Random().nextInt(50))); @@ -233,7 +238,7 @@ public final class RepositoryDataGenerator { } // close - final ActionStatus close = new ActionStatus(); + final ActionStatus close = new JpaActionStatus(); close.setAction(action); // with error @@ -262,7 +267,7 @@ public final class RepositoryDataGenerator { "Controller retrieved update action and should start now the download."); // close - final ActionStatus close = new ActionStatus(); + final ActionStatus close = new JpaActionStatus(); close.setAction(action); close.setStatus(Status.FINISHED); close.addMessage("Controller reported CLOSED with OK!"); @@ -274,7 +279,7 @@ public final class RepositoryDataGenerator { private List createTargetTestGroup(final String group, final int targets) { LOG.debug("createTargetTestGroup: create group {}", group); - final TargetTag targTag = tagManagement.createTargetTag(new TargetTag(group)); + final TargetTag targTag = tagManagement.createTargetTag(new JpaTargetTag(group)); final List targAs = targetManagement.createTargets(buildTargets(targets, group), TargetUpdateStatus.REGISTERED, System.currentTimeMillis() - new Random().nextInt(50_000_000), @@ -291,7 +296,7 @@ public final class RepositoryDataGenerator { final List result = new ArrayList(noOfTgts); for (int i = 0; i < noOfTgts; i++) { - final Target target = new Target(UUID.randomUUID().toString()); + final Target target = new JpaTarget(UUID.randomUUID().toString()); final StringBuilder builder = new StringBuilder(); builder.append(descriptionPrefix); @@ -331,7 +336,7 @@ public final class RepositoryDataGenerator { final String[] modulesTypes = { "HeadUnit_FW", "EDC17_FW", "OSGi_Bundle" }; final DistributionSetTag depTag = tagManagement - .createDistributionSetTag(new DistributionSetTag("deprecated")); + .createDistributionSetTag(new JpaDistributionSetTag("deprecated")); Arrays.stream(targetTestGroups).forEach(group -> { generateTestTagetGroup(group, sizeMultiplikator); @@ -346,11 +351,11 @@ public final class RepositoryDataGenerator { LOG.debug("initDemoRepo - start now Extra Software Modules and types"); Arrays.stream(modulesTypes).forEach(typeName -> { final SoftwareModuleType smtype = softwareManagement.createSoftwareModuleType( - new SoftwareModuleType(typeName.toLowerCase().replaceAll("\\s+", ""), typeName, + new JpaSoftwareModuleType(typeName.toLowerCase().replaceAll("\\s+", ""), typeName, jlorem.words(5), Integer.MAX_VALUE)); for (int i1 = 0; i1 < sizeMultiplikator; i1++) { - softwareManagement.createSoftwareModule(new SoftwareModule(smtype, typeName + i1, "1.0." + i1, + softwareManagement.createSoftwareModule(new JpaSoftwareModule(smtype, typeName + i1, "1.0." + i1, jlorem.words(5), "the " + typeName + " vendor Inc.")); } @@ -371,7 +376,7 @@ public final class RepositoryDataGenerator { // pending final DistributionSetTag dsTag = tagManagement - .createDistributionSetTag(new DistributionSetTag("OnlyAssignedTag")); + .createDistributionSetTag(new JpaDistributionSetTag("OnlyAssignedTag")); final DistributionSet ds = TestDataUtil.generateDistributionSet("Pending DS", "v1.0", softwareManagement, distributionSetManagement, Arrays.asList(new DistributionSetTag[] { dsTag })); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/tenancy/MultiTenancyEntityTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/tenancy/MultiTenancyEntityTest.java index 67b9b5a26..ca0ef3840 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/tenancy/MultiTenancyEntityTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/tenancy/MultiTenancyEntityTest.java @@ -13,8 +13,10 @@ import static org.fest.assertions.api.Assertions.assertThat; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.WithSpringAuthorityRule; import org.eclipse.hawkbit.WithUser; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.Target; import org.junit.Test; import org.springframework.data.domain.Page; @@ -162,7 +164,7 @@ public class MultiTenancyEntityTest extends AbstractIntegrationTest { private Target createTargetForTenant(final String controllerId, final String tenant) throws Exception { return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), - () -> targetManagement.createTarget(new Target(controllerId))); + () -> targetManagement.createTarget(new JpaTarget(controllerId))); } private Slice findTargetsForTenant(final String tenant) throws Exception { @@ -180,12 +182,12 @@ public class MultiTenancyEntityTest extends AbstractIntegrationTest { private DistributionSet createDistributionSetForTenant(final String name, final String version, final String tenant) throws Exception { return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), () -> { - final DistributionSet ds = new DistributionSet(); + final JpaDistributionSet ds = new JpaDistributionSet(); ds.setName(name); ds.setTenant(tenant); ds.setVersion(version); ds.setType(distributionSetManagement - .createDistributionSetType(new DistributionSetType("typetest", "test", "foobar"))); + .createDistributionSetType(new JpaDistributionSetType("typetest", "test", "foobar"))); return distributionSetManagement.createDistributionSet(ds); }); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java index d6e057edd..a36443024 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java @@ -149,7 +149,7 @@ public class ArtifactStoreController { actionStatus.addMessage( ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); } - controllerManagement.addInformationalActionStatus(actionStatus); + controllerManagement.addActionStatusMessage(actionStatus); return action; } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index db5efd37c..14383f30b 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -150,7 +150,7 @@ public class RootController { return new ResponseEntity<>( DataConversionHelper.fromTarget(target, controllerManagement.findActionByTargetAndActive(target), - controllerManagement.getPollingTime(), tenantAware), + controllerManagement.findPollingTime(), tenantAware), HttpStatus.OK); } @@ -222,7 +222,7 @@ public class RootController { statusMessage.addMessage( ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI()); } - controllerManagement.addInformationalActionStatus(statusMessage); + controllerManagement.addActionStatusMessage(statusMessage); return action; } @@ -371,7 +371,8 @@ public class RootController { return new ResponseEntity<>(HttpStatus.GONE); } - controllerManagement.addUpdateActionStatus(generateUpdateStatus(feedback, targetid, feedback.getId(), action)); + controllerManagement.addUpdateActionStatus(generateUpdateStatus(feedback, targetid, feedback.getId(), action), + action); return new ResponseEntity<>(HttpStatus.OK); @@ -545,7 +546,7 @@ public class RootController { } controllerManagement - .addCancelActionStatus(generateActionCancelStatus(feedback, target, feedback.getId(), action)); + .addCancelActionStatus(generateActionCancelStatus(feedback, target, feedback.getId(), action), action); return new ResponseEntity<>(HttpStatus.OK); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java index 1a766c8c4..27231308b 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java @@ -22,8 +22,8 @@ import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.TargetWithActionType; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.TargetWithActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java index 8798f0ec8..f7346a6ff 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java @@ -69,7 +69,7 @@ public class DistributionSetTypeResource implements DistributionSetTypeRestApi { final Slice findModuleTypessAll; Long countModulesAll; if (rsqlParam != null) { - findModuleTypessAll = distributionSetManagement.findDistributionSetTypesAll( + findModuleTypessAll = distributionSetManagement.findDistributionSetTypesByPredicate( RSQLUtility.parse(rsqlParam, DistributionSetTypeFields.class), pageable); countModulesAll = ((Page) findModuleTypessAll).getTotalElements(); } else { diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java index d8821f113..78cfefa0d 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java @@ -178,7 +178,7 @@ public class RolloutResource implements RolloutRestApi { final Page findRolloutGroupsAll; if (rsqlParam != null) { - findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsAll(rollout, + findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByPredicate(rollout, RSQLUtility.parse(rsqlParam, RolloutGroupFields.class), pageable); } else { findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByRolloutId(rolloutId, pageable); diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetResourceTest.java index 3705e8da3..6254da992 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetResourceTest.java @@ -30,12 +30,12 @@ import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.MockMvcResultPrinter; import org.eclipse.hawkbit.TestDataUtil; import org.eclipse.hawkbit.WithUser; +import org.eclipse.hawkbit.repository.ActionRepository; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.ActionRepository; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -890,7 +890,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest { for (final String msg : msgs) { statusMessages.addMessage(msg); } - controllerManagament.addUpdateActionStatus(statusMessages); + controllerManagament.addUpdateActionStatus(statusMessages, updActA); return targetManagement.findTargetByControllerID(t.getControllerId()); } diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java index 2d3a9707e..8d27d5114 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java @@ -108,7 +108,8 @@ public class TargetResourceTest extends AbstractIntegrationTest { final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); actions.get(0).setStatus(Status.FINISHED); controllerManagament.addUpdateActionStatus( - new ActionStatus(actions.get(0), Status.FINISHED, System.currentTimeMillis(), "testmessage")); + new ActionStatus(actions.get(0), Status.FINISHED, System.currentTimeMillis(), "testmessage"), + actions.get(0)); final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionFields.ID.getFieldName()); final ActionStatus status = deploymentManagement @@ -1283,8 +1284,8 @@ public class TargetResourceTest extends AbstractIntegrationTest { final Pageable pageReq = new PageRequest(0, 100); final Action action = actionRepository.findByDistributionSet(pageReq, savedSet).getContent().get(0); - final ActionStatus actionStatus = new ActionStatus(action, Status.FINISHED, 0L); - controllerManagement.addUpdateActionStatus(actionStatus); + final ActionStatus actionStatus = new ActionStatus(action, Status.FINISHED, 0l); + controllerManagement.addUpdateActionStatus(actionStatus, action); } /**