diff --git a/engines/base/pom.xml b/engines/base/pom.xml index f6ad0a90..044d38b7 100644 --- a/engines/base/pom.xml +++ b/engines/base/pom.xml @@ -28,6 +28,10 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-aop + org.springframework.retry spring-retry diff --git a/engines/base/src/main/java/org/alfresco/transform/base/Application.java b/engines/base/src/main/java/org/alfresco/transform/base/Application.java index 5c096f07..045aace1 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/Application.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/Application.java @@ -32,9 +32,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskExecutor; @@ -44,10 +42,12 @@ import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableAsync -//@EnableScheduling -//@EnableRetry +@EnableScheduling +@EnableRetry public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; diff --git a/engines/base/src/main/java/org/alfresco/transform/base/config/WebApplicationConfig.java b/engines/base/src/main/java/org/alfresco/transform/base/config/WebApplicationConfig.java index 709ad9e3..d8650c63 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/config/WebApplicationConfig.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/config/WebApplicationConfig.java @@ -61,8 +61,7 @@ public class WebApplicationConfig implements WebMvcConfigurer @Override public void addInterceptors(InterceptorRegistry registry) { - registry - .addInterceptor(new TransformInterceptor()) + registry.addInterceptor(new TransformInterceptor()) .addPathPatterns(ENDPOINT_TRANSFORM, "/live", "/ready"); } diff --git a/engines/base/src/main/java/org/alfresco/transform/base/registry/TransformRegistry.java b/engines/base/src/main/java/org/alfresco/transform/base/registry/TransformRegistry.java index 64d5acbd..60f0c249 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/registry/TransformRegistry.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/registry/TransformRegistry.java @@ -53,7 +53,7 @@ import static org.alfresco.transform.config.CoreVersionDecorator.setCoreVersionO @Service public class TransformRegistry extends AbstractTransformRegistry { - private static final Logger log = LoggerFactory.getLogger(TransformRegistry.class); + private static final Logger logger = LoggerFactory.getLogger(TransformRegistry.class); @Autowired private String coreVersion; @@ -81,7 +81,7 @@ public class TransformRegistry extends AbstractTransformRegistry // Ensures that read operations are blocked while config is being updated private ReadWriteLock configRefreshLock = new ReentrantReadWriteLock(); - @EventListener + @EventListener(ContextRefreshedEvent.class) void handleContextRefreshedEvent(final ContextRefreshedEvent event) { final ApplicationContext context = event.getApplicationContext(); @@ -93,26 +93,36 @@ public class TransformRegistry extends AbstractTransformRegistry * Load the registry on application startup. This allows Components in projects that extend the t-engine base * to use @PostConstruct to add to {@code transformConfigSources}, before the registry is loaded. */ -// @Async -// @Retryable(include = {IllegalStateException.class}, -// maxAttemptsExpression = "#{${transform.engine.config.retry.attempts}}", -// backoff = @Backoff(delayExpression = "#{${transform.engine.config.retry.timeout} * 1000}")) - public void initRegistryOnAppStartup(final ContextRefreshedEvent event) + @Async + @Retryable(include = {IllegalStateException.class}, + maxAttemptsExpression = "#{${transform.engine.config.retry.attempts}}", + backoff = @Backoff(delayExpression = "#{${transform.engine.config.retry.timeout} * 1000}")) + void initRegistryOnAppStartup(final ContextRefreshedEvent event) { - initRegistry(); + retrieveConfig(); + } + + /** + * Recovery method in case all the retries fail. If not specified, the @Retryable method will cause the application + * to stop. + */ + @Recover + void recover(IllegalStateException e) + { + logger.warn(e.getMessage()); } /** * Takes the schedule from a spring-boot property */ -// @Scheduled(cron = "${transformer.engine.config.cron}") + @Scheduled(cron = "${transform.engine.config.cron}") public void retrieveEngineConfigs() { - log.trace("Refresh TransformRegistry"); - initRegistry(); + logger.trace("Refresh TransformRegistry"); + retrieveConfig(); } - void initRegistry() + void retrieveConfig() { CombinedTransformConfig combinedTransformConfig = new CombinedTransformConfig(); @@ -130,16 +140,6 @@ public class TransformRegistry extends AbstractTransformRegistry concurrentUpdate(combinedTransformConfig, transformConfigBeforeIncompleteTransformsAreRemoved); } - /** - * Recovery method in case all the retries fail. If not specified, the @Retryable method will cause the application - * to stop. - */ - // @Recover - private void recover(IllegalStateException e) - { - log.warn(e.getMessage()); - } - public TransformConfig getTransformConfig() { return getData().getTransformConfigBeforeIncompleteTransformsAreRemoved(); @@ -187,12 +187,12 @@ public class TransformRegistry extends AbstractTransformRegistry @Override protected void logError(String msg) { - log.error(msg); + logger.error(msg); } @Override protected void logWarn(String msg) { - log.warn(msg); + logger.warn(msg); } } diff --git a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java index 108e4c36..e2b8e6e7 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java @@ -111,9 +111,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @AutoConfigureMockMvc @SpringBootTest(classes={org.alfresco.transform.base.Application.class}) @ContextConfiguration(classes = { - FakeTransformEngineWithTwoCustomTransformers.class, - FakeTransformerTxT2Pdf.class, - FakeTransformerPdf2Png.class}) + FakeTransformEngineWithTwoCustomTransformers.class, + FakeTransformerTxT2Pdf.class, + FakeTransformerPdf2Png.class}) public class TransformControllerTest { @Autowired diff --git a/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryRefreshTest.java b/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryRefreshTest.java new file mode 100644 index 00000000..e5abceb0 --- /dev/null +++ b/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryRefreshTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015-2022 Alfresco Software, Ltd. All rights reserved. + * + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + */ +package org.alfresco.transform.base.registry; + +import com.google.common.collect.ImmutableMap; +import org.alfresco.transform.base.fakes.FakeTransformEngineWithTwoCustomTransformers; +import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png; +import org.alfresco.transform.base.fakes.FakeTransformerTxT2Pdf; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.verify; + +@AutoConfigureMockMvc +@SpringBootTest(classes={org.alfresco.transform.base.Application.class}, properties={"transform.engine.config.cron=*/1 * * * * *"}) +@ContextConfiguration(classes = { + FakeTransformEngineWithTwoCustomTransformers.class, + FakeTransformerTxT2Pdf.class, + FakeTransformerPdf2Png.class}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class TransformRegistryRefreshTest +{ + @SpyBean + private TransformRegistry transformRegistry; + @Autowired + private TransformConfigFromFiles transformConfigFromFiles; + @Autowired + private AdditionalTransformConfigResources additionalTransformConfigResources; + + @Test + public void checkRegistryRefreshes() throws InterruptedException + { + verify(transformRegistry, atLeast(1)).retrieveConfig(); + assertEquals(4, transformRegistry.getTransformConfig().getTransformers().size()); + + // As we can't change the content of a classpath resource, lets change what is read. + ReflectionTestUtils.setField(additionalTransformConfigResources, "config", ImmutableMap.of( + "a", "config/addA2B.json", + "foo", "config/addB2C.json")); + transformConfigFromFiles.initFileConfig(); + + Thread.sleep(3000); // to give it a chance to refresh a few (at least 2 more) times + verify(transformRegistry, atLeast(1+2)).retrieveConfig(); + assertEquals(6, transformRegistry.getTransformConfig().getTransformers().size()); + } +} diff --git a/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryTest.java b/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryTest.java index c3370992..4871b8a1 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/registry/TransformRegistryTest.java @@ -70,7 +70,7 @@ public class TransformRegistryTest ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", Collections.emptyList()); ReflectionTestUtils.setField(additionalTransformConfigResources, "config", Collections.emptyMap()); ReflectionTestUtils.setField(additionalTransformConfigResourcesHistoric, "additional", Collections.emptyMap()); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); } private String getTransformerNames(TransformConfig transformConfig) @@ -93,7 +93,7 @@ public class TransformRegistryTest ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", ImmutableList.of( new FakeTransformEngineWithOneCustomTransformer())); transformConfigFromTransformEngines.initTransformEngineConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig())); } @@ -106,7 +106,7 @@ public class TransformRegistryTest new FakeTransformEngineWithOneCustomTransformer(), new FakeTransformEngineWithTwoCustomTransformers())); transformConfigFromTransformEngines.initTransformEngineConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("Pdf2Jpg, Pdf2Png, TxT2Pdf, Txt2JpgViaPdf, Txt2PngViaPdf", getTransformerNames(transformRegistry.getTransformConfig())); @@ -123,7 +123,7 @@ public class TransformRegistryTest transformConfigFromTransformEngines.initTransformEngineConfig(); transformConfigFromFiles.initFileConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig())); } @@ -139,7 +139,7 @@ public class TransformRegistryTest transformConfigFromTransformEngines.initTransformEngineConfig(); transformConfigFromFiles.initFileConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig())); } @@ -156,7 +156,7 @@ public class TransformRegistryTest transformConfigFromTransformEngines.initTransformEngineConfig(); transformConfigFromFiles.initFileConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("A2B, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig())); } @@ -171,7 +171,7 @@ public class TransformRegistryTest transformConfigFromTransformEngines.initTransformEngineConfig(); transformConfigFromFiles.initFileConfig(); - transformRegistry.initRegistry(); + transformRegistry.retrieveConfig(); assertEquals("A2Z", getTransformerNames(transformRegistry.getTransformConfig())); }