mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-08-14 17:58:27 +00:00
Schedule config reads
This commit is contained in:
@@ -28,6 +28,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.retry</groupId>
|
<groupId>org.springframework.retry</groupId>
|
||||||
<artifactId>spring-retry</artifactId>
|
<artifactId>spring-retry</artifactId>
|
||||||
|
@@ -32,9 +32,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
|
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.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||||
import org.springframework.core.task.TaskExecutor;
|
import org.springframework.core.task.TaskExecutor;
|
||||||
@@ -44,10 +42,12 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
//@EnableScheduling
|
@EnableScheduling
|
||||||
//@EnableRetry
|
@EnableRetry
|
||||||
public class Application
|
public class Application
|
||||||
{
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
||||||
|
|
||||||
@Value("${container.name}")
|
@Value("${container.name}")
|
||||||
private String containerName;
|
private String containerName;
|
||||||
|
|
||||||
|
@@ -61,8 +61,7 @@ public class WebApplicationConfig implements WebMvcConfigurer
|
|||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry)
|
public void addInterceptors(InterceptorRegistry registry)
|
||||||
{
|
{
|
||||||
registry
|
registry.addInterceptor(new TransformInterceptor())
|
||||||
.addInterceptor(new TransformInterceptor())
|
|
||||||
.addPathPatterns(ENDPOINT_TRANSFORM, "/live", "/ready");
|
.addPathPatterns(ENDPOINT_TRANSFORM, "/live", "/ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,7 +53,7 @@ import static org.alfresco.transform.config.CoreVersionDecorator.setCoreVersionO
|
|||||||
@Service
|
@Service
|
||||||
public class TransformRegistry extends AbstractTransformRegistry
|
public class TransformRegistry extends AbstractTransformRegistry
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(TransformRegistry.class);
|
private static final Logger logger = LoggerFactory.getLogger(TransformRegistry.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private String coreVersion;
|
private String coreVersion;
|
||||||
@@ -81,7 +81,7 @@ public class TransformRegistry extends AbstractTransformRegistry
|
|||||||
// Ensures that read operations are blocked while config is being updated
|
// Ensures that read operations are blocked while config is being updated
|
||||||
private ReadWriteLock configRefreshLock = new ReentrantReadWriteLock();
|
private ReadWriteLock configRefreshLock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
@EventListener
|
@EventListener(ContextRefreshedEvent.class)
|
||||||
void handleContextRefreshedEvent(final ContextRefreshedEvent event)
|
void handleContextRefreshedEvent(final ContextRefreshedEvent event)
|
||||||
{
|
{
|
||||||
final ApplicationContext context = event.getApplicationContext();
|
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
|
* 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.
|
* to use @PostConstruct to add to {@code transformConfigSources}, before the registry is loaded.
|
||||||
*/
|
*/
|
||||||
// @Async
|
@Async
|
||||||
// @Retryable(include = {IllegalStateException.class},
|
@Retryable(include = {IllegalStateException.class},
|
||||||
// maxAttemptsExpression = "#{${transform.engine.config.retry.attempts}}",
|
maxAttemptsExpression = "#{${transform.engine.config.retry.attempts}}",
|
||||||
// backoff = @Backoff(delayExpression = "#{${transform.engine.config.retry.timeout} * 1000}"))
|
backoff = @Backoff(delayExpression = "#{${transform.engine.config.retry.timeout} * 1000}"))
|
||||||
public void initRegistryOnAppStartup(final ContextRefreshedEvent event)
|
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
|
* Takes the schedule from a spring-boot property
|
||||||
*/
|
*/
|
||||||
// @Scheduled(cron = "${transformer.engine.config.cron}")
|
@Scheduled(cron = "${transform.engine.config.cron}")
|
||||||
public void retrieveEngineConfigs()
|
public void retrieveEngineConfigs()
|
||||||
{
|
{
|
||||||
log.trace("Refresh TransformRegistry");
|
logger.trace("Refresh TransformRegistry");
|
||||||
initRegistry();
|
retrieveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initRegistry()
|
void retrieveConfig()
|
||||||
{
|
{
|
||||||
CombinedTransformConfig combinedTransformConfig = new CombinedTransformConfig();
|
CombinedTransformConfig combinedTransformConfig = new CombinedTransformConfig();
|
||||||
|
|
||||||
@@ -130,16 +140,6 @@ public class TransformRegistry extends AbstractTransformRegistry
|
|||||||
concurrentUpdate(combinedTransformConfig, transformConfigBeforeIncompleteTransformsAreRemoved);
|
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()
|
public TransformConfig getTransformConfig()
|
||||||
{
|
{
|
||||||
return getData().getTransformConfigBeforeIncompleteTransformsAreRemoved();
|
return getData().getTransformConfigBeforeIncompleteTransformsAreRemoved();
|
||||||
@@ -187,12 +187,12 @@ public class TransformRegistry extends AbstractTransformRegistry
|
|||||||
@Override
|
@Override
|
||||||
protected void logError(String msg)
|
protected void logError(String msg)
|
||||||
{
|
{
|
||||||
log.error(msg);
|
logger.error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void logWarn(String msg)
|
protected void logWarn(String msg)
|
||||||
{
|
{
|
||||||
log.warn(msg);
|
logger.warn(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,9 +111,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
@SpringBootTest(classes={org.alfresco.transform.base.Application.class})
|
@SpringBootTest(classes={org.alfresco.transform.base.Application.class})
|
||||||
@ContextConfiguration(classes = {
|
@ContextConfiguration(classes = {
|
||||||
FakeTransformEngineWithTwoCustomTransformers.class,
|
FakeTransformEngineWithTwoCustomTransformers.class,
|
||||||
FakeTransformerTxT2Pdf.class,
|
FakeTransformerTxT2Pdf.class,
|
||||||
FakeTransformerPdf2Png.class})
|
FakeTransformerPdf2Png.class})
|
||||||
public class TransformControllerTest
|
public class TransformControllerTest
|
||||||
{
|
{
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
@@ -70,7 +70,7 @@ public class TransformRegistryTest
|
|||||||
ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", Collections.emptyList());
|
ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", Collections.emptyList());
|
||||||
ReflectionTestUtils.setField(additionalTransformConfigResources, "config", Collections.emptyMap());
|
ReflectionTestUtils.setField(additionalTransformConfigResources, "config", Collections.emptyMap());
|
||||||
ReflectionTestUtils.setField(additionalTransformConfigResourcesHistoric, "additional", Collections.emptyMap());
|
ReflectionTestUtils.setField(additionalTransformConfigResourcesHistoric, "additional", Collections.emptyMap());
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTransformerNames(TransformConfig transformConfig)
|
private String getTransformerNames(TransformConfig transformConfig)
|
||||||
@@ -93,7 +93,7 @@ public class TransformRegistryTest
|
|||||||
ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", ImmutableList.of(
|
ReflectionTestUtils.setField(transformConfigFromTransformEngines, "transformEngines", ImmutableList.of(
|
||||||
new FakeTransformEngineWithOneCustomTransformer()));
|
new FakeTransformEngineWithOneCustomTransformer()));
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
assertEquals("Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ public class TransformRegistryTest
|
|||||||
new FakeTransformEngineWithOneCustomTransformer(),
|
new FakeTransformEngineWithOneCustomTransformer(),
|
||||||
new FakeTransformEngineWithTwoCustomTransformers()));
|
new FakeTransformEngineWithTwoCustomTransformers()));
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("Pdf2Jpg, Pdf2Png, TxT2Pdf, Txt2JpgViaPdf, Txt2PngViaPdf",
|
assertEquals("Pdf2Jpg, Pdf2Png, TxT2Pdf, Txt2JpgViaPdf, Txt2PngViaPdf",
|
||||||
getTransformerNames(transformRegistry.getTransformConfig()));
|
getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
@@ -123,7 +123,7 @@ public class TransformRegistryTest
|
|||||||
|
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformConfigFromFiles.initFileConfig();
|
transformConfigFromFiles.initFileConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ public class TransformRegistryTest
|
|||||||
|
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformConfigFromFiles.initFileConfig();
|
transformConfigFromFiles.initFileConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
assertEquals("A2B, B2C, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ public class TransformRegistryTest
|
|||||||
|
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformConfigFromFiles.initFileConfig();
|
transformConfigFromFiles.initFileConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("A2B, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
assertEquals("A2B, Pdf2Jpg", getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ public class TransformRegistryTest
|
|||||||
|
|
||||||
transformConfigFromTransformEngines.initTransformEngineConfig();
|
transformConfigFromTransformEngines.initTransformEngineConfig();
|
||||||
transformConfigFromFiles.initFileConfig();
|
transformConfigFromFiles.initFileConfig();
|
||||||
transformRegistry.initRegistry();
|
transformRegistry.retrieveConfig();
|
||||||
|
|
||||||
assertEquals("A2Z", getTransformerNames(transformRegistry.getTransformConfig()));
|
assertEquals("A2Z", getTransformerNames(transformRegistry.getTransformConfig()));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user