diff --git a/hawkbit-repository/hawkbit-repository-core/pom.xml b/hawkbit-repository/hawkbit-repository-core/pom.xml
index 980dbaee7..bb7163c48 100644
--- a/hawkbit-repository/hawkbit-repository-core/pom.xml
+++ b/hawkbit-repository/hawkbit-repository-core/pom.xml
@@ -29,7 +29,7 @@
org.apache.commons
- commons-lang3
+ commons-text
com.github.ben-manes.caffeine
diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java
index 1d99864ea..ba7b243fe 100644
--- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java
+++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/rsql/VirtualPropertyResolver.java
@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.repository.rsql;
import java.io.Serial;
-import org.apache.commons.lang3.text.StrLookup;
-import org.apache.commons.lang3.text.StrSubstitutor;
+import org.apache.commons.text.StringSubstitutor;
+import org.apache.commons.text.lookup.StringLookupFactory;
import org.eclipse.hawkbit.repository.TimestampCalculator;
/**
@@ -41,31 +41,30 @@ import org.eclipse.hawkbit.repository.TimestampCalculator;
* configuration.
*
*/
-public class VirtualPropertyResolver extends StrLookup implements VirtualPropertyReplacer {
+public class VirtualPropertyResolver implements VirtualPropertyReplacer {
@Serial
private static final long serialVersionUID = 1L;
- private transient StrSubstitutor substitutor;
-
- @Override
- public String lookup(final String rhs) {
- String resolved = null;
-
- if ("now_ts".equalsIgnoreCase(rhs)) {
- resolved = String.valueOf(System.currentTimeMillis());
- } else if ("overdue_ts".equalsIgnoreCase(rhs)) {
- resolved = String.valueOf(TimestampCalculator.calculateOverdueTimestamp());
- }
- return resolved;
- }
+ private transient StringSubstitutor substitutor;
@Override
public String replace(final String input) {
if (substitutor == null) {
- substitutor = new StrSubstitutor(this, StrSubstitutor.DEFAULT_PREFIX, StrSubstitutor.DEFAULT_SUFFIX,
- StrSubstitutor.DEFAULT_ESCAPE);
+ substitutor = new StringSubstitutor(
+ StringLookupFactory.builder().get().functionStringLookup(this::lookup),
+ StringSubstitutor.DEFAULT_PREFIX, StringSubstitutor.DEFAULT_SUFFIX, StringSubstitutor.DEFAULT_ESCAPE);
}
return substitutor.replace(input);
}
+
+ private String lookup(final String rhs) {
+ if ("now_ts".equalsIgnoreCase(rhs)) {
+ return String.valueOf(System.currentTimeMillis());
+ } else if ("overdue_ts".equalsIgnoreCase(rhs)) {
+ return String.valueOf(TimestampCalculator.calculateOverdueTimestamp());
+ } else {
+ return null;
+ }
+ }
}
\ No newline at end of file
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/CustomBaseRepositoryFactoryBean.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/CustomBaseRepositoryFactoryBean.java
index bcea738b2..e8eb42ff4 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/CustomBaseRepositoryFactoryBean.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/CustomBaseRepositoryFactoryBean.java
@@ -12,9 +12,11 @@ package org.eclipse.hawkbit.repository.jpa;
import jakarta.persistence.EntityManager;
import org.eclipse.hawkbit.repository.BaseRepositoryTypeProvider;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
+import org.springframework.lang.NonNull;
/**
* A {@link JpaRepositoryFactoryBean} extension that allow injection of custom repository factories by using a
@@ -23,20 +25,24 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport
@SuppressWarnings("java:S119") // java:S119 - ID is inherited from JpaRepositoryFactoryBean
public class CustomBaseRepositoryFactoryBean, S, ID> extends JpaRepositoryFactoryBean {
- private final BaseRepositoryTypeProvider baseRepoProvider;
+ private BaseRepositoryTypeProvider baseRepoProvider;
/**
* Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
*
* @param repositoryInterface must not be {@literal null}.
*/
- public CustomBaseRepositoryFactoryBean(final Class extends T> repositoryInterface, final BaseRepositoryTypeProvider baseRepoProvider) {
+ public CustomBaseRepositoryFactoryBean(final Class extends T> repositoryInterface) {
super(repositoryInterface);
+ }
+
+ @Autowired // if it is a constructor injection sometimes doesn't work - base repo provider is not available at construct time
+ public void setBaseRepoProvider(final BaseRepositoryTypeProvider baseRepoProvider) {
this.baseRepoProvider = baseRepoProvider;
}
@Override
- protected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {
+ protected RepositoryFactorySupport createRepositoryFactory(@NonNull final EntityManager entityManager) {
final RepositoryFactorySupport rfs = super.createRepositoryFactory(entityManager);
rfs.setRepositoryBaseClass(baseRepoProvider.getBaseRepositoryType(getObjectType()));
return rfs;
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
index 03646054e..51ea38ad3 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
@@ -187,7 +187,6 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.lang.NonNull;
-import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.PlatformTransactionManager;
@@ -459,8 +458,7 @@ public class RepositoryApplicationConfiguration {
}
/**
- * @return the singleton instance of the
- * {@link AfterTransactionCommitExecutorHolder}
+ * @return the singleton instance of the {@link AfterTransactionCommitExecutorHolder}
*/
@Bean
AfterTransactionCommitExecutorHolder afterTransactionCommitExecutorHolder() {
@@ -475,6 +473,17 @@ public class RepositoryApplicationConfiguration {
return new ExceptionMappingAspectHandler();
}
+ /**
+ * Default {@link BaseRepositoryTypeProvider} bean always provides the NoCountBaseRepository
+ *
+ * @return a {@link BaseRepositoryTypeProvider} bean
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ BaseRepositoryTypeProvider baseRepositoryTypeProvider() {
+ return new HawkbitBaseRepository.RepositoryTypeProvider();
+ }
+
/**
* {@link JpaSystemManagement} bean.
*
@@ -1027,18 +1036,6 @@ public class RepositoryApplicationConfiguration {
tenantAware, lockRegistry, systemSecurityContext);
}
- /**
- * Default {@link BaseRepositoryTypeProvider} bean always provides the
- * NoCountBaseRepository
- *
- * @return a {@link BaseRepositoryTypeProvider} bean
- */
- @Bean
- @ConditionalOnMissingBean
- BaseRepositoryTypeProvider baseRepositoryTypeProvider() {
- return new HawkbitBaseRepository.RepositoryTypeProvider();
- }
-
/**
* Default artifact encryption service bean that internally uses
* {@link ArtifactEncryption} and {@link ArtifactEncryptionSecretsStore} beans
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 2366c879d..bdef4fd22 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
@@ -437,10 +437,7 @@ class RSQLUtilityTest {
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
// verification
- verify(macroResolver).lookup(overdueProp);
- // the macro is already replaced when passed to #lessThanOrEqualTo ->
- // the method is never invoked with the
- // placeholder:
+ // the macro is already replaced when passed to #lessThanOrEqualTo -> the method is never invoked with the placeholder:
verify(criteriaBuilderMock, never()).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder);
}
@@ -462,9 +459,7 @@ class RSQLUtilityTest {
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
// verification
- verify(macroResolver).lookup(overdueProp);
- // the macro is unknown and hence never replaced -> #lessThanOrEqualTo
- // is invoked with the placeholder:
+ // the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder:
verify(criteriaBuilderMock).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder);
}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java
index 857736bd0..303b1c471 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java
@@ -17,7 +17,7 @@ import java.util.concurrent.Callable;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
-import org.apache.commons.lang3.text.StrSubstitutor;
+import org.apache.commons.text.StringSubstitutor;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
@@ -31,7 +31,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mockito;
-import org.mockito.Spy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -47,13 +46,12 @@ class VirtualPropertyResolverTest {
private static final TenantConfigurationValue TEST_POLLING_OVERDUE_TIME_INTERVAL =
TenantConfigurationValue. builder().value("00:07:37").build();
- @Spy
- private final VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver();
@MockitoBean
private TenantConfigurationManagement confMgmt;
@MockitoBean
private SystemSecurityContext securityContext;
- private StrSubstitutor substitutor;
+
+ private final VirtualPropertyResolver substitutor = new VirtualPropertyResolver();
@BeforeEach
void before() {
@@ -61,9 +59,6 @@ class VirtualPropertyResolverTest {
.thenReturn(TEST_POLLING_TIME_INTERVAL);
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class))
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
-
- substitutor = new StrSubstitutor(resolverUnderTest, StrSubstitutor.DEFAULT_PREFIX,
- StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
}
@Test
@@ -80,8 +75,8 @@ class VirtualPropertyResolverTest {
@Description("Tests escape mechanism for placeholders (syntax is $${SOME_PLACEHOLDER}).")
void handleEscapedPlaceholder() {
final String placeholder = "${OVERDUE_TS}";
- final String escaptedPlaceholder = StrSubstitutor.DEFAULT_ESCAPE + placeholder;
- final String testString = "lhs=lt=" + escaptedPlaceholder;
+ final String escapedPlaceholder = StringSubstitutor.DEFAULT_ESCAPE + placeholder;
+ final String testString = "lhs=lt=" + escapedPlaceholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat(resolvedPlaceholders).as("Escaped OVERDUE_TS should not be resolved!").contains(placeholder);
@@ -89,14 +84,13 @@ class VirtualPropertyResolverTest {
@ParameterizedTest
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
- @Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
+ @Description("Tests resolution of NOW_TS by using a StringSubstitutor configured with the VirtualPropertyResolver.")
void resolveNowTimestampPlaceholder(final String placeholder) {
when(securityContext.runAsSystem(Mockito.any())).thenAnswer(a -> ((Callable>) a.getArgument(0)).call());
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
- assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder)
- .doesNotContain(placeholder);
+ assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder).doesNotContain(placeholder);
}
@Configuration
@@ -112,4 +106,4 @@ class VirtualPropertyResolverTest {
return SystemSecurityContextHolder.getInstance();
}
}
-}
+}
\ No newline at end of file
diff --git a/hawkbit-repository/hawkbit-repository-test/pom.xml b/hawkbit-repository/hawkbit-repository-test/pom.xml
index bdefde15f..b3f587494 100644
--- a/hawkbit-repository/hawkbit-repository-test/pom.xml
+++ b/hawkbit-repository/hawkbit-repository-test/pom.xml
@@ -104,10 +104,6 @@
org.springframework
spring-tx
-
- org.apache.commons
- commons-lang3
-
org.springframework.boot
spring-boot-starter-test
diff --git a/hawkbit-rest-core/pom.xml b/hawkbit-rest-core/pom.xml
index 5c82cf0e9..40e3583e8 100644
--- a/hawkbit-rest-core/pom.xml
+++ b/hawkbit-rest-core/pom.xml
@@ -65,10 +65,6 @@
provided
-
- org.apache.commons
- commons-lang3
-
commons-io
commons-io
diff --git a/pom.xml b/pom.xml
index d540bd27e..04674181c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,6 +62,7 @@
2.1.0
2.16.1
4.4
+ 1.13.0
1.8.0
5.3.0
@@ -712,6 +713,11 @@
commons-collections4
${commons-collections4.version}
+
+ org.apache.commons
+ commons-text
+ ${commons-text.version}
+