diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 50a3d0b48..e1297e94e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -52,7 +52,6 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyMakroResolver; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; @@ -392,14 +391,4 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { return new JpaEntityFactory(); } - /** - * {@link VirtualPropertyMakroResolver} bean. - * - * @return a new {@link VirtualPropertyMakroResolver} - */ - @Bean - @ConditionalOnMissingBean - public VirtualPropertyMakroResolver virtualPropertyMakroResolver() { - return new VirtualPropertyMakroResolver(); - } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index 5a2c6fdda..54d6dadc0 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -54,6 +54,7 @@ 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.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; @@ -134,6 +135,9 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Autowired private SystemSecurityContext systemSecurityContext; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Override @Transactional(isolation = Isolation.READ_COMMITTED) @Modifying @@ -605,7 +609,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { } private Specification createSpecificationFor(final Target target, final String rsqlParam) { - final Specification spec = RSQLUtility.parse(rsqlParam, ActionFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, ActionFields.class, virtualPropertyLookup); return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb), cb.equal(root.get(JpaAction_.target), target)); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index e170ccad7..d1f9a68ef 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -43,6 +43,7 @@ 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.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification; import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; @@ -107,6 +108,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private TenantAware tenantAware; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -286,7 +290,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public Page findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) { final Specification spec = RSQLUtility.parse(rsqlParam, - DistributionSetTypeFields.class); + DistributionSetTypeFields.class, virtualPropertyLookup); return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable)); } @@ -352,7 +356,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { public Page findDistributionSetsAll(final String rsqlParam, final Pageable pageReq, final Boolean deleted) { - final Specification spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class, + virtualPropertyLookup); final List> specList = new ArrayList<>(); if (deleted != null) { @@ -530,7 +535,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { /** * Method to get the latest distribution set based on ds ID after the * metadata changes for that distribution set. - * + * * @param distributionSet * Distribution set */ @@ -566,7 +571,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { final String rsqlParam, final Pageable pageable) { final Specification spec = RSQLUtility.parse(rsqlParam, - DistributionSetMetadataFields.class); + DistributionSetMetadataFields.class, virtualPropertyLookup); return convertMdPage( distributionSetMetadataRepository diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java index 9f63204b1..c977283dd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java @@ -33,6 +33,7 @@ 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.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; @@ -70,6 +71,9 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { @Autowired private EntityManager entityManager; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Override public RolloutGroup findRolloutGroupById(final Long rolloutGroupId) { return rolloutGroupRepository.findOne(rolloutGroupId); @@ -92,7 +96,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { public Page findRolloutGroupsAll(final Rollout rollout, final String rsqlParam, final Pageable pageable) { - final Specification specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class); + final Specification specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class, + virtualPropertyLookup); return convertPage( rolloutGroupRepository @@ -145,7 +150,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { public Page findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam, final Pageable pageable) { - final Specification rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class); + final Specification rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class, + virtualPropertyLookup); return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> { final ListJoin rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index 3a903ea89..f1138a6d7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -32,6 +32,7 @@ import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup; import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator; import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator; import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -114,6 +115,9 @@ public class JpaRolloutManagement implements RolloutManagement { @Autowired private CacheWriteNotify cacheWriteNotify; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Autowired @Qualifier("asyncExecutor") private Executor executor; @@ -150,7 +154,8 @@ public class JpaRolloutManagement implements RolloutManagement { @Override public Page findAllWithDetailedStatusByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification specification = RSQLUtility.parse(rsqlParam, RolloutFields.class); + final Specification specification = RSQLUtility.parse(rsqlParam, RolloutFields.class, + virtualPropertyLookup); final Page findAll = rolloutRepository.findAll(specification, pageable); setRolloutStatusDetails(findAll); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 3f8c1a54b..9e612bc38 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -42,6 +42,7 @@ 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.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; @@ -102,6 +103,9 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Autowired private ArtifactManagement artifactManagement; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) @@ -312,7 +316,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class, + virtualPropertyLookup); return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); } @@ -320,7 +325,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class, + virtualPropertyLookup); return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); } @@ -609,7 +615,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { final String rsqlParam, final Pageable pageable) { final Specification spec = RSQLUtility.parse(rsqlParam, - SoftwareModuleMetadataFields.class); + SoftwareModuleMetadataFields.class, virtualPropertyLookup); return convertSmMdPage( softwareModuleMetadataRepository .findAll( diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java index e881d8ef8..22eb0914c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java @@ -30,6 +30,7 @@ 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.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.tenancy.TenantAware; @@ -74,6 +75,9 @@ public class JpaTagManagement implements TagManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private VirtualPropertyLookup virtualPropertyLookup; + @Override public TargetTag findTargetTag(final String name) { return targetTagRepository.findByNameEquals(name); @@ -147,7 +151,7 @@ public class JpaTagManagement implements TagManagement { @Override public Page findAllTargetTags(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class, virtualPropertyLookup); return convertTPage(targetTagRepository.findAll(spec, pageable), pageable); } @@ -279,7 +283,8 @@ public class JpaTagManagement implements TagManagement { @Override public Page findAllDistributionSetTags(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class); + final Specification spec = RSQLUtility.parse(rsqlParam, TagFields.class, + virtualPropertyLookup); return convertDsPage(distributionSetTagRepository.findAll(spec, pageable), pageable); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java index 693f9395e..39343d3a4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java @@ -16,7 +16,7 @@ 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.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyMakroResolver; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; @@ -46,7 +46,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme private TargetFilterQueryRepository targetFilterQueryRepository; @Autowired - private VirtualPropertyMakroResolver virtualPropMakroResolver; + private VirtualPropertyLookup virtualPropertyLookup; @Override @Modifying @@ -115,7 +115,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Override public boolean verifyTargetFilterQuerySyntax(final String query) { - RSQLUtility.parse(query, TargetFields.class, virtualPropMakroResolver); + RSQLUtility.parse(query, TargetFields.class, virtualPropertyLookup); return true; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 2528ed5ac..8bfa51d74 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -41,7 +41,7 @@ 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.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyMakroResolver; +import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyLookup; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Target; @@ -104,7 +104,7 @@ public class JpaTargetManagement implements TargetManagement { private AfterTransactionCommitExecutor afterCommit; @Autowired - private VirtualPropertyMakroResolver virtualPropMakroResolver; + private VirtualPropertyLookup virtualPropertyLookup; @Override public Target findTargetByControllerID(final String controllerId) { @@ -157,13 +157,13 @@ public class JpaTargetManagement implements TargetManagement { @Override public Slice findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) { return findTargetsBySpec( - RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropMakroResolver), + RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyLookup), pageable); } @Override public Page findTargetsAll(final String targetFilterQuery, final Pageable pageable) { - return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class, virtualPropMakroResolver), + return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class, virtualPropertyLookup), pageable); } @@ -232,7 +232,7 @@ public class JpaTargetManagement implements TargetManagement { final Pageable pageReq) { final Specification spec = RSQLUtility.parse(rsqlParam, TargetFields.class, - virtualPropMakroResolver); + virtualPropertyLookup); return convertPage( targetRepository @@ -261,7 +261,7 @@ public class JpaTargetManagement implements TargetManagement { final Pageable pageable) { final Specification spec = RSQLUtility.parse(rsqlParam, TargetFields.class, - virtualPropMakroResolver); + virtualPropertyLookup); return convertPage( targetRepository @@ -304,7 +304,7 @@ public class JpaTargetManagement implements TargetManagement { } if (overdueState != null) { specList.add( - TargetSpecifications.isOverdue(new VirtualPropertyMakroResolver().calculateOverdueTimestamp())); + TargetSpecifications.isOverdue(new TimestampCalculator().calculateOverdueTimestamp())); } if (installedOrAssignedDistributionSetId != null) { specList.add( @@ -561,7 +561,7 @@ public class JpaTargetManagement implements TargetManagement { targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty)); final Specification spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, - virtualPropMakroResolver); + virtualPropertyLookup); final List> specList = new ArrayList<>(); specList.add(spec); @@ -645,14 +645,14 @@ public class JpaTargetManagement implements TargetManagement { @Override public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) { final Specification specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, - virtualPropMakroResolver); + virtualPropertyLookup); return targetRepository.count(specs); } @Override public Long countTargetByTargetFilterQuery(final String targetFilterQuery) { final Specification specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class, - virtualPropMakroResolver); + virtualPropertyLookup); return targetRepository.count(specs); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TimestampCalculator.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TimestampCalculator.java new file mode 100644 index 000000000..038ab263d --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TimestampCalculator.java @@ -0,0 +1,45 @@ +package org.eclipse.hawkbit.repository.jpa; + +import java.time.Duration; +import java.time.Instant; + +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.springframework.stereotype.Service; + +@Service +public class TimestampCalculator { + + /** + * Calculates the overdue timestamp (overdue_ts) based on the + * current timestamp and the intervals for polling and poll-overdue: + *

+ * overdue_ts = now_ts - pollingInterval - + * pollingOverdueInterval;
+ * pollingInterval and pollingOverdueInterval are + * retrieved from tenant-specific system configuration. + * + * @return overdue_ts in milliseconds since Unix epoch as long + * value + */ + public long calculateOverdueTimestamp() { + long overdueTs = Instant.now().toEpochMilli() // + - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis() // + - getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis(); + return overdueTs; + } + + private Duration getDurationForKey(TenantConfigurationKey key) { + return DurationHelper.formattedStringToDuration(getRawStringForKey(key)); + } + + private String getRawStringForKey(TenantConfigurationKey key) { + return getTenantConfigurationManagement().getConfigurationValue(key, String.class).getValue(); + } + + protected TenantConfigurationManagement getTenantConfigurationManagement() { + return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement(); + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java index 228091494..a95172636 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java @@ -70,12 +70,12 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor; *

  • name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN
  • * *

    - * There is also a mechanism that allows to refer to known makros that can resolved by an optional {@link StrLookup} - * (cp. {@link VirtualPropertyMakroResolver}).
    + * There is also a mechanism that allows to refer to known macros that can resolved by an optional {@link StrLookup} + * (cp. {@link VirtualPropertyResolver}).
    * An example that queries for all overdue targets using the ${OVERDUE_TS} placeholder introduced by - * {@link VirtualPropertyMakroResolver} looks like this:
    + * {@link VirtualPropertyResolver} looks like this:
    * lastControllerRequestAt=le=${OVERDUE_TS}
    - * It is possible to escape a makro expression by using a second '$': $${OVERDUE_TS} would prevent the ${OVERDUE_TS} + * It is possible to escape a macro expression by using a second '$': $${OVERDUE_TS} would prevent the ${OVERDUE_TS} * token from being expanded. * */ @@ -99,6 +99,9 @@ public final class RSQLUtility { * @param fieldNameProvider * the enum class type which implements the * {@link FieldNameProvider} + * @param virtualPropertyLookup + * holds the logic how the known macros have to be resolved; may + * be null * @return an specification which can be used with JPA * @throws RSQLParameterUnsupportedFieldException * if a field in the RSQL string is used but not provided by the @@ -107,29 +110,8 @@ public final class RSQLUtility { * if the RSQL syntax is wrong */ public static & FieldNameProvider, T> Specification parse(final String rsql, - final Class fieldNameProvider) { - return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider, new VirtualPropertyMakroResolver()); - } - - /** - * parses an RSQL valid string into an JPA {@link Specification} which then can be used to filter for JPA entities - * with the given RSQL query. - * - * @param rsql - * the rsql query - * @param fieldNameProvider - * the enum class type which implements the {@link FieldNameProvider} - * @param makroLookup - * holds the logic how the known makros have to be resolved; may be null - * @return an specification which can be used with JPA - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - public static & FieldNameProvider, T> Specification parse(final String rsql, - final Class fieldNameProvider, StrLookup makroLookup) { - return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider, makroLookup); + final Class fieldNameProvider, VirtualPropertyLookup virtualPropertyLookup) { + return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider, virtualPropertyLookup); } /** @@ -160,12 +142,13 @@ public final class RSQLUtility { private final String rsql; private final Class enumType; - private final StrLookup makroLookup; + private final VirtualPropertyLookup virtualPropertyLookup; - private RSQLSpecification(final String rsql, final Class enumType, StrLookup makroLookup) { + private RSQLSpecification(final String rsql, final Class enumType, + VirtualPropertyLookup virtualPropertyLookup) { this.rsql = rsql; this.enumType = enumType; - this.makroLookup = makroLookup; + this.virtualPropertyLookup = virtualPropertyLookup; } @Override @@ -174,7 +157,7 @@ public final class RSQLUtility { final Node rootNode = parseRsql(rsql); final JpqQueryRSQLVisitor jpqQueryRSQLVisitor = new JpqQueryRSQLVisitor<>(root, cb, enumType, - makroLookup); + virtualPropertyLookup); final List accept = rootNode., String> accept(jpqQueryRSQLVisitor); if (accept != null && !accept.isEmpty()) { @@ -204,18 +187,19 @@ public final class RSQLUtility { private final Root root; private final CriteriaBuilder cb; private final Class enumType; - private final StrLookup makroLookup; + private final VirtualPropertyLookup virtualPropertyLookup; private final StrSubstitutor substitutor; private final SimpleTypeConverter simpleTypeConverter; private JpqQueryRSQLVisitor(final Root root, final CriteriaBuilder cb, final Class enumType, - StrLookup makroLookup) { + VirtualPropertyLookup virtualPropertyLookup) { this.root = root; this.cb = cb; this.enumType = enumType; - this.makroLookup = makroLookup; - this.substitutor = new StrSubstitutor(makroLookup, StrSubstitutor.DEFAULT_PREFIX, + this.virtualPropertyLookup = virtualPropertyLookup; + this.substitutor = new StrSubstitutor(new StrLookupAdapter(virtualPropertyLookup), + StrSubstitutor.DEFAULT_PREFIX, StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE); simpleTypeConverter = new SimpleTypeConverter(); } @@ -387,13 +371,10 @@ public final class RSQLUtility { private Object convertValueIfNecessary(final ComparisonNode node, final A fieldName, final String value, final Path fieldPath) { // in case the value of an rsql query e.g. type==application is an - // enum we need to - // handle it separately because JPA needs the correct java-type to - // build an - // expression. So String and numeric values JPA can do it by it's - // own but not for - // classes like enums. So we need to transform the given value - // string into the enum + // enum we need to handle it separately because JPA needs the + // correct java-type to build an expression. So String and numeric + // values JPA can do it by it's own but not for classes like enums. + // So we need to transform the given value string into the enum // class. final Class javaType = fieldPath.getJavaType(); if (javaType != null && javaType.isEnum()) { @@ -445,8 +426,7 @@ public final class RSQLUtility { return Enum.valueOf(tmpEnumType, value.toUpperCase()); } catch (final IllegalArgumentException e) { // we could not transform the given string value into the enum - // type, so ignore - // it and return null and do not filter + // type, so ignore it and return null and do not filter LOGGER.info("given value {} cannot be transformed into the correct enum type {}", value.toUpperCase(), javaType); LOGGER.debug("value cannot be transformed to an enum", e); @@ -461,12 +441,13 @@ public final class RSQLUtility { private List mapToPredicate(final ComparisonNode node, final Path fieldPath, final List values, final List transformedValues, final A enumField) { // only 'equal' and 'notEqual' can handle transformed value like - // enums. The JPA API - // cannot handle object types for greaterThan etc methods. + // enums. The JPA API cannot handle object types for greaterThan etc + // methods. final Object transformedValue = transformedValues.get(0); final String value; - if (makroLookup != null) { // if substitutor is available, replace makros ... + if (virtualPropertyLookup != null) { // if lookup is available, + // replace macros ... value = substitutor.replace(values.get(0)); } else { value = values.get(0); @@ -611,4 +592,28 @@ public final class RSQLUtility { } } + + /** + * Adapts the VirtualPropertyLookup to StrLookup. + */ + final static class StrLookupAdapter extends StrLookup { + + private VirtualPropertyLookup virtualPropertyLookup; + + /** + * Constructor. + * + * @param virtualPropertyLookup + * the lookup to adapt. + */ + StrLookupAdapter(VirtualPropertyLookup virtualPropertyLookup) { + this.virtualPropertyLookup = virtualPropertyLookup; + } + + @Override + public String lookup(String key) { + return virtualPropertyLookup.lookup(key); + } + + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyLookup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyLookup.java new file mode 100644 index 000000000..09952a4fc --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyLookup.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2016 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.rsql; + +/** + * Implementations map a placeholder to the associated value. + *

    + * This is used in context of string replacement. + */ +public interface VirtualPropertyLookup { + + /** + * Looks up a placeholder to the associated value. + * + * @param placeholder + * the virtual property that should be resolved by a value + * @return the value for the placeholder; may be null if no + * value could be found for the given placeholder; + */ + public String lookup(String placeholder); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolver.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolver.java deleted file mode 100644 index 5ade64630..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolver.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2016 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.rsql; - -import java.time.Duration; -import java.time.Instant; - -import org.apache.commons.lang3.text.StrLookup; -import org.apache.commons.lang3.text.StrSubstitutor; -import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; - -/** - * Adds makro capabilities to RSQL expressions that are used to filter for targets. - *

    - * Some (virtual) properties do not have a representation in the database (in general these properties are time-related, - * or more explicitly, they deal with time intervals).
    - * Such a virtual property needs to be calculated on Java-side before it may be used in a target filter query that is - * passed to the database. Therefore a placeholder is used in the RSQL expression that is expanded in the - * {@link RSQLUtility} by a {@link StrSubstitutor}. This {@link StrSubstitutor} is configured with an instance of - * {@link VirtualPropertyMakroResolver} to resolve the known makros. - *

    - * A virtual property may either be a system value like the current date (aka now_ts) or a value derived from - * (tenant-specific) system configuration (e.g. overdue_ts). - *

    - * Known values are:
    - *

      - *
    • now_ts: maps to system UTC time in milliseconds since Unix epoch as long value
    • - *
    • overdue_ts: is a calculated value: overdue_ts = now_ts - pollingInterval - pollingOverdueInterval - * ; pollingInterval and pollingOverdueInterval are retrieved from tenant-specific system configuration.
    • - *
    - * - */ -public class VirtualPropertyMakroResolver extends StrLookup { - - @Override - public String lookup(String rhs) { - String resolved = null; - - if ("now_ts".equals(rhs.toLowerCase())) { - resolved = String.valueOf(Instant.now().toEpochMilli()); - } else if ("overdue_ts".equals(rhs.toLowerCase())) { - resolved = String.valueOf(calculateOverdueTimestamp()); - } - return resolved; - } - - public long calculateOverdueTimestamp() { - long overdueTs = Instant.now().toEpochMilli() // - - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis() // - - getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis(); - return overdueTs; - } - - private Duration getDurationForKey(TenantConfigurationKey key) { - return DurationHelper.formattedStringToDuration(getRawStringForKey(key)); - } - - private String getRawStringForKey(TenantConfigurationKey key) { - return getTenantConfigurationManagement().getConfigurationValue(key, String.class).getValue(); - } - - TenantConfigurationManagement getTenantConfigurationManagement() { - return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement(); - } - - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolver.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolver.java new file mode 100644 index 000000000..39aed8786 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolver.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016 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.rsql; + +import java.time.Instant; + +import org.eclipse.hawkbit.repository.jpa.TimestampCalculator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Adds macro capabilities to RSQL expressions that are used to filter for + * targets. + *

    + * Some (virtual) properties do not have a representation in the database (in + * general these properties are time-related, or more explicitly, they deal with + * time intervals).
    + * Such a virtual property needs to be calculated on Java-side before it may be + * used in a target filter query that is passed to the database. Therefore a + * placeholder is used in the RSQL expression that is expanded in the + * {@link RSQLUtility}. + *

    + * A virtual property may either be a system value like the current date (aka + * now_ts) or a value derived from (tenant-specific) system + * configuration (e.g. overdue_ts). + *

    + * Known values are:
    + *

      + *
    • now_ts: maps to system UTC time in milliseconds since Unix epoch + * as long value
    • + *
    • overdue_ts: is a calculated value: overdue_ts = now_ts - + * pollingInterval - pollingOverdueInterval; pollingInterval and + * pollingOverdueInterval are retrieved from tenant-specific system + * configuration.
    • + *
    + */ +@Component +public class VirtualPropertyResolver implements VirtualPropertyLookup { + + @Autowired + private TimestampCalculator timestampCalculator; + + @Override + public String lookup(String rhs) { + String resolved = null; + + if ("now_ts".equals(rhs.toLowerCase())) { + resolved = String.valueOf(Instant.now().toEpochMilli()); + } else if ("overdue_ts".equals(rhs.toLowerCase())) { + resolved = String.valueOf(getTimestampCalculator().calculateOverdueTimestamp()); + } + return resolved; + } + + TimestampCalculator getTimestampCalculator() { + return timestampCalculator; + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java index e7b5ba592..1e73bbe24 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java @@ -20,7 +20,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.metamodel.Attribute; -import org.apache.commons.lang3.text.StrLookup; import org.eclipse.hawkbit.repository.DistributionSetFields; import org.eclipse.hawkbit.repository.FieldNameProvider; import org.eclipse.hawkbit.repository.SoftwareModuleFields; @@ -28,6 +27,7 @@ import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.jpa.TimestampCalculator; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -49,11 +49,14 @@ import ru.yandex.qatools.allure.annotations.Stories; public class RSQLUtilityTest { @Spy - VirtualPropertyMakroResolver makroResolver = new VirtualPropertyMakroResolver(); + VirtualPropertyResolver macroResolver = new VirtualPropertyResolver(); @Mock TenantConfigurationManagement confMgmt; + @Mock + TimestampCalculator timestampCalculator; + @Mock private Root baseSoftwareModuleRootMock; @@ -271,7 +274,7 @@ public class RSQLUtilityTest { @Test @Description("Tests the resolution of overdue_ts placeholder in context of a RSQL expression.") - public void correctRsqlWithOverdueMakro() { + public void correctRsqlWithOverdueMacro() { reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); final String overdueProp = "overdue_ts"; final String overduePropPlaceholder = "${" + overdueProp + "}"; @@ -283,12 +286,12 @@ public class RSQLUtilityTest { .thenReturn(mock(Predicate.class)); // test - Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMakroLookup()) + Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup()) .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); // verfication - verify(makroResolver, times(1)).lookup(overdueProp); - // the makro is already replaced when passed to #lessThanOrEqualTo -> the method is never invoked with the + verify(macroResolver, times(1)).lookup(overdueProp); + // the macro is already replaced when passed to #lessThanOrEqualTo -> the method is never invoked with the // placeholder: verify(criteriaBuilderMock, never()).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)), eq(overduePropPlaceholder)); @@ -296,7 +299,7 @@ public class RSQLUtilityTest { @Test @Description("Tests RSQL expression with an unknown placeholder.") - public void correctRsqlWithUnknownMakro() { + public void correctRsqlWithUnknownMacro() { reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); final String overdueProp = "unknown"; final String overduePropPlaceholder = "${" + overdueProp + "}"; @@ -308,24 +311,30 @@ public class RSQLUtilityTest { .thenReturn(mock(Predicate.class)); // test - Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMakroLookup()) + Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup()) .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); // verfication - verify(makroResolver, times(1)).lookup(overdueProp); - // the makro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder: + verify(macroResolver, times(1)).lookup(overdueProp); + // the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder: verify(criteriaBuilderMock, times(1)).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)), eq(overduePropPlaceholder)); } - public StrLookup setupMakroLookup() { + public VirtualPropertyLookup setupMacroLookup() { when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class)) .thenReturn(TEST_POLLING_TIME_INTERVAL); when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)) .thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL); - when(makroResolver.getTenantConfigurationManagement()).thenReturn(confMgmt); - return makroResolver; + when(macroResolver.getTimestampCalculator()).thenReturn(new TimestampCalculator() { + @Override + protected TenantConfigurationManagement getTenantConfigurationManagement() { + return confMgmt; + } + }); + + return macroResolver; } @SuppressWarnings("unchecked") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolverTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java similarity index 81% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolverTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java index f18783d5f..e21ec7bcd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyMakroResolverTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java @@ -15,6 +15,7 @@ import java.time.Instant; import org.apache.commons.lang3.text.StrSubstitutor; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.jpa.TimestampCalculator; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.junit.Before; @@ -31,10 +32,10 @@ import ru.yandex.qatools.allure.annotations.Stories; @Features("Unit Tests - Repository") @Stories("Placeholder resolution for virtual properties") @RunWith(MockitoJUnitRunner.class) -public class VirtualPropertyMakroResolverTest { +public class VirtualPropertyResolverTest { @Spy - VirtualPropertyMakroResolver resolverUnderTest = new VirtualPropertyMakroResolver(); + VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver(); @Mock TenantConfigurationManagement confMgmt; @@ -55,14 +56,21 @@ public class VirtualPropertyMakroResolverTest { .thenReturn(TEST_POLLING_TIME_INTERVAL); when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)) .thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL); - when(resolverUnderTest.getTenantConfigurationManagement()).thenReturn(confMgmt); - this.substitutor = new StrSubstitutor(resolverUnderTest, StrSubstitutor.DEFAULT_PREFIX, + when(resolverUnderTest.getTimestampCalculator()).thenReturn(new TimestampCalculator() { + @Override + protected TenantConfigurationManagement getTenantConfigurationManagement() { + return confMgmt; + } + }); + + this.substitutor = new StrSubstitutor(new RSQLUtility.StrLookupAdapter(resolverUnderTest), + StrSubstitutor.DEFAULT_PREFIX, StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE); } @Test - @Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyMakroResolver.") + @Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.") public void resolveNowTimestampPlaceholder() { String placeholder = "${NOW_TS}"; String testString = "lhs=lt=" + placeholder; @@ -72,7 +80,7 @@ public class VirtualPropertyMakroResolverTest { } @Test - @Description("Tests resolution of OVERDUE_TS by using a StrSubstitutor configured with the VirtualPropertyMakroResolver.") + @Description("Tests resolution of OVERDUE_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.") public void resolveOverdueTimestampPlaceholder() { String placeholder = "${OVERDUE_TS}"; String testString = "lhs=lt=" + placeholder; @@ -82,7 +90,7 @@ public class VirtualPropertyMakroResolverTest { } @Test - @Description("Tests case insensititity of VirtualPropertyMakroResolver.") + @Description("Tests case insensititity of VirtualPropertyResolver.") public void resolveOverdueTimestampPlaceholderLowerCase() { String placeholder = "${overdue_ts}"; String testString = "lhs=lt=" + placeholder; @@ -92,7 +100,7 @@ public class VirtualPropertyMakroResolverTest { } @Test - @Description("Tests VirtualPropertyMakroResolver with a placeholder unknown to VirtualPropertyMakroResolver.") + @Description("Tests VirtualPropertyResolver with a placeholder unknown to VirtualPropertyResolver.") public void handleUnknownPlaceholder() { String placeholder = "${unknown}"; String testString = "lhs=lt=" + placeholder;