.
+ * #L%
+ */
+package org.alfresco.transform.config.reader;
+
+import java.io.IOException;
+
+import org.alfresco.transform.config.TransformConfig;
+import org.springframework.core.io.Resource;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+public class TransformConfigReaderYaml implements TransformConfigReader
+{
+ private static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory());
+
+ private final Resource resource;
+
+ TransformConfigReaderYaml(final Resource resource)
+ {
+ this.resource = resource;
+ }
+
+ @Override
+ public TransformConfig load() throws IOException
+ {
+ return MAPPER.readValue(resource.getInputStream(), TransformConfig.class);
+ }
+}
diff --git a/model/src/main/java/org/alfresco/transform/common/TransformConfigResourceReader.java b/model/src/main/java/org/alfresco/transform/config/reader/TransformConfigResourceReader.java
similarity index 72%
rename from model/src/main/java/org/alfresco/transform/common/TransformConfigResourceReader.java
rename to model/src/main/java/org/alfresco/transform/config/reader/TransformConfigResourceReader.java
index 8c95b167..02fd5c06 100644
--- a/model/src/main/java/org/alfresco/transform/common/TransformConfigResourceReader.java
+++ b/model/src/main/java/org/alfresco/transform/config/reader/TransformConfigResourceReader.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Transform Core
* %%
- * Copyright (C) 2005 - 2022 Alfresco Software Limited
+ * Copyright (C) 2022 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
@@ -24,9 +24,9 @@
* along with Alfresco. If not, see .
* #L%
*/
-package org.alfresco.transform.common;
+package org.alfresco.transform.config.reader;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import org.alfresco.transform.common.TransformException;
import org.alfresco.transform.config.TransformConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
@@ -41,7 +41,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
/**
- * Reads {@link TransformConfig} from a {@json} file. Typically used by {@code TransformEngine.getTransformConfig()}.
+ * Reads {@link TransformConfig} from json or yaml files. Typically used by {@code TransformEngine.getTransformConfig()}.
*
* transformConfigResourceReader.read("classpath:pdfrenderer_engine_config.json");
*
@@ -51,20 +51,16 @@ public class TransformConfigResourceReader
{
@Autowired ResourceLoader resourceLoader;
- private ObjectMapper jsonObjectMapper = new ObjectMapper();
-
- public TransformConfig read(String engineConfigLocation)
+ public TransformConfig read(String resourcePath)
{
- Resource engineConfig = resourceLoader.getResource(engineConfigLocation);
- return read(engineConfig);
+ return read(resourceLoader.getResource(resourcePath));
}
public TransformConfig read(Resource resource)
{
- try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8))
+ try
{
- TransformConfig transformConfig = jsonObjectMapper.readValue(reader, TransformConfig.class);
- return transformConfig;
+ return TransformConfigReaderFactory.create(resource).load();
}
catch (IOException e)
{
diff --git a/model/src/main/java/org/alfresco/transform/registry/CombinedTransformConfig.java b/model/src/main/java/org/alfresco/transform/registry/CombinedTransformConfig.java
index f11421de..51f93071 100644
--- a/model/src/main/java/org/alfresco/transform/registry/CombinedTransformConfig.java
+++ b/model/src/main/java/org/alfresco/transform/registry/CombinedTransformConfig.java
@@ -32,6 +32,7 @@ import org.alfresco.transform.config.TransformStep;
import org.alfresco.transform.config.Transformer;
import org.alfresco.transform.config.TransformerAndTypes;
import org.alfresco.transform.config.Types;
+import org.apache.commons.lang3.tuple.Triple;
import java.util.ArrayList;
import java.util.HashMap;
@@ -827,4 +828,9 @@ public class CombinedTransformConfig
{
return combinedTransformers.size();
}
+
+ public Map> getTransformerByNameMap()
+ {
+ return combinedTransformers.stream().collect(Collectors.toMap(origin -> origin.get().getTransformerName(), origin -> origin));
+ }
}
diff --git a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java
index 3cff2c71..e5ee4e0d 100644
--- a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java
+++ b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java
@@ -39,6 +39,7 @@ import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.Map.Entry;
import static java.util.stream.Collectors.toMap;
+import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
class TransformRegistryHelper
@@ -95,17 +96,36 @@ class TransformRegistryHelper
return cachedTransformList;
}
- final List builtTransformList = buildTransformList(data,
- sourceMimetype,
- targetMimetype,
- filterTimeout(actualOptions));
-
- if (renditionName != null)
+ // The transformOptions always contains sourceEncoding and possibly timeout when sent to a T-Engine, even though
+ // they should not be used to select a transformer. Would like to change this, but cannot as we need to support
+ // older ACS repo versions.
+ String sourceEncoding = actualOptions.remove(SOURCE_ENCODING);
+ String timeout = actualOptions.remove(TIMEOUT);
+ try
{
- data.cache(renditionName, sourceMimetype, builtTransformList);
- }
+ final List builtTransformList = buildTransformList(data,
+ sourceMimetype,
+ targetMimetype,
+ actualOptions);
- return builtTransformList;
+ if (renditionName != null)
+ {
+ data.cache(renditionName, sourceMimetype, builtTransformList);
+ }
+
+ return builtTransformList;
+ }
+ finally
+ {
+ if (sourceEncoding != null)
+ {
+ actualOptions.put(SOURCE_ENCODING, sourceEncoding);
+ }
+ if (timeout != null)
+ {
+ actualOptions.put(TIMEOUT, timeout);
+ }
+ }
}
private static List buildTransformList(
@@ -349,18 +369,4 @@ class TransformRegistryHelper
.stream()
.allMatch(transformOptions::containsKey);
}
-
- private static Map filterTimeout(final Map options)
- {
- // Remove the "timeout" property from the actualOptions as it is not used to select a transformer.
- if (!options.containsKey(TIMEOUT))
- {
- return options;
- }
- return options
- .entrySet()
- .stream()
- .filter(e -> !TIMEOUT.equals(e.getKey()))
- .collect(toMap(Entry::getKey, Entry::getValue));
- }
}
diff --git a/model/src/test/java/org/alfresco/transform/common/TransformerDebugTest.java b/model/src/test/java/org/alfresco/transform/common/TransformerDebugTest.java
index ee7e9480..48f15056 100644
--- a/model/src/test/java/org/alfresco/transform/common/TransformerDebugTest.java
+++ b/model/src/test/java/org/alfresco/transform/common/TransformerDebugTest.java
@@ -63,10 +63,10 @@ class TransformerDebugTest
.replaceAll(" [\\d,]+ ms", " -- ms");
}
- private void twoStepTransform(boolean isTEngine, boolean fail, Level logLevel, String renditionName,
+ private void twoStepTransform(boolean isTRouter, boolean fail, Level logLevel, String renditionName,
long sourceSize)
{
- transformerDebug.setIsTEngine(isTEngine);
+ transformerDebug.setIsTRouter(isTRouter);
monitorLogs(logLevel);
TransformRequest request = TransformRequest.builder()
@@ -144,7 +144,7 @@ class TransformerDebugTest
@Test
void testRouterTwoStepTransform()
{
- twoStepTransform(false, false, Level.DEBUG, "", 1234L);
+ twoStepTransform(true, false, Level.DEBUG, "", 1234L);
Assertions.assertEquals("" +
"1 txt pdf 1.2 KB wrapper\n" +
@@ -159,7 +159,7 @@ class TransformerDebugTest
@Test
void testRouterTwoStepTransformWithTrace()
{
- twoStepTransform(false, false, Level.TRACE, "", 1234L);
+ twoStepTransform(true, false, Level.TRACE, "", 1234L);
// With trace there are "Finished" lines for nested transforms, like a T-Engine's debug but still without
// the size and rendition name
@@ -178,7 +178,7 @@ class TransformerDebugTest
@Test
void testEngineTwoStepTransform()
{
- twoStepTransform(true, false, Level.DEBUG, "", 1234L);
+ twoStepTransform(false, false, Level.DEBUG, "", 1234L);
// Note the first and last lines would only ever be logged on the router, but the expected data includes
// the extra "Finished" lines, sizes and renditions (if set in client data).
@@ -197,7 +197,7 @@ class TransformerDebugTest
@Test
void testRouterTwoStepTransformWithFailure()
{
- twoStepTransform(false, true, Level.DEBUG, "", 1234L);
+ twoStepTransform(true, true, Level.DEBUG, "", 1234L);
Assertions.assertEquals("" +
"1 txt pdf 1.2 KB wrapper\n" +
@@ -212,7 +212,7 @@ class TransformerDebugTest
@Test
void testRenditionName()
{
- twoStepTransform(false, false, Level.DEBUG, "renditionName", 1234L);
+ twoStepTransform(true, false, Level.DEBUG, "renditionName", 1234L);
Assertions.assertEquals("" +
"1 txt pdf 1.2 KB -- renditionName -- wrapper\n" +
@@ -227,7 +227,7 @@ class TransformerDebugTest
@Test
void testMetadataExtract()
{
- twoStepTransform(false, false, Level.DEBUG, "transform:alfresco-metadata-extract", 1234L);
+ twoStepTransform(true, false, Level.DEBUG, "transform:alfresco-metadata-extract", 1234L);
Assertions.assertEquals("" +
"1 txt pdf 1.2 KB -- metadataExtract -- wrapper\n" +
@@ -242,7 +242,7 @@ class TransformerDebugTest
@Test
void testMetadataEmbed()
{
- twoStepTransform(false, false, Level.DEBUG, "transform:alfresco-metadata-embed", 1234L);
+ twoStepTransform(true, false, Level.DEBUG, "transform:alfresco-metadata-embed", 1234L);
Assertions.assertEquals("" +
"1 txt pdf 1.2 KB -- metadataEmbed -- wrapper\n" +
@@ -257,7 +257,7 @@ class TransformerDebugTest
@Test
void testSourceSize1Byte()
{
- twoStepTransform(false, false, Level.DEBUG, "", 1);
+ twoStepTransform(true, false, Level.DEBUG, "", 1);
Assertions.assertEquals("" +
"1 txt pdf 1 byte wrapper\n" +
@@ -272,7 +272,7 @@ class TransformerDebugTest
@Test
void testSourceSize23TB()
{
- twoStepTransform(false, false, Level.DEBUG, "", 23L*1024*1024*1024*1024);
+ twoStepTransform(true, false, Level.DEBUG, "", 23L*1024*1024*1024*1024);
Assertions.assertEquals("" +
"1 txt pdf 23 TB wrapper\n" +
@@ -285,7 +285,7 @@ class TransformerDebugTest
}
@Test
- void testLogFailure()
+ void testLogFailureOnTEngine()
{
monitorLogs(Level.TRACE);
@@ -296,11 +296,33 @@ class TransformerDebugTest
.withClientData(origClientData)
.build();
+ transformerDebug.setIsTRouter(false);
transformerDebug.logFailure(reply);
String expectedDebug = " T-Request was null - a major error";
Assertions.assertEquals(expectedDebug, getTransformerDebugOutput());
- assertEquals(origClientData+DEBUG_SEPARATOR+expectedDebug, reply.getClientData());
+ assertEquals(origClientData, reply.getClientData());
+ }
+
+ @Test
+ void testLogFailureOnTRouter()
+ {
+ monitorLogs(Level.TRACE);
+
+ String origClientData = clientDataWithDebugRequest("");
+ TransformReply reply = TransformReply.builder()
+ .withInternalContext(InternalContext.initialise(null))
+ .withErrorDetails("T-Request was null - a major error")
+ .withClientData(origClientData)
+ .build();
+
+ transformerDebug.setIsTRouter(true);
+ transformerDebug.logFailure(reply);
+
+ String expectedDebug = " T-Request was null - a major error";
+ String expectedClientData = origClientData+DEBUG_SEPARATOR+expectedDebug;
+ Assertions.assertEquals(expectedDebug, getTransformerDebugOutput());
+ assertEquals(expectedClientData, reply.getClientData());
}
@Test
diff --git a/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderJsonTest.java b/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderJsonTest.java
new file mode 100644
index 00000000..1c824946
--- /dev/null
+++ b/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderJsonTest.java
@@ -0,0 +1,300 @@
+/*
+ * #%L
+ * Alfresco Transform Model
+ * %%
+ * Copyright (C) 2015 - 2022 Alfresco Software Limited
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+package org.alfresco.transform.config.reader;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableMap;
+import org.alfresco.transform.config.TransformConfig;
+import org.alfresco.transform.config.TransformOption;
+import org.alfresco.transform.config.TransformOptionGroup;
+import org.alfresco.transform.config.TransformOptionValue;
+import org.alfresco.transform.config.Transformer;
+import org.alfresco.transform.config.SupportedSourceAndTarget;
+import org.alfresco.transform.config.TransformStep;
+import org.junit.jupiter.api.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class TransformConfigReaderJsonTest
+{
+ @Test
+ public void testEmptyRoutesFile() throws Exception
+ {
+ final Resource resource = new ClassPathResource("config/sample1.json");
+ final TransformConfigReader loader = TransformConfigReaderFactory.create(resource);
+ TransformConfig transformConfig = loader.load();
+ final List transformers = transformConfig.getTransformers();
+
+ assertNotNull(transformers);
+ assertEquals(Collections.emptyList(), transformers);
+ }
+
+ @Test
+ public void testMixedRoutesFile() throws Exception
+ {
+ final List expected = prepareSample2();
+
+ final Resource resource = new ClassPathResource("config/sample2.json");
+ final TransformConfigReader loader = TransformConfigReaderFactory.create(resource);
+
+ TransformConfig transformConfig = loader.load();
+ final List transformers = transformConfig.getTransformers();
+
+ assertNotNull(transformers);
+ assertEquals(expected.size(), transformers.size());
+ assertTrue(expected.containsAll(transformers));
+ }
+
+ private List prepareSample2()
+ {
+ return List.of(
+ Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("image/gif")
+ .withTargetMediaType("image/gif")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("imageMagickOptions"))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("IMAGEMAGICK")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("image/gif")
+ .withTargetMediaType("image/gif")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("imageMagickOptions"))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/msword")
+ .withTargetMediaType("application/pdf")
+ .withMaxSourceSizeBytes(18874368L)
+ .build()
+ ))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("PDF_RENDERER")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/vnd.ms-powerpoint")
+ .withTargetMediaType("application/pdf")
+ .withPriority(55)
+ .withMaxSourceSizeBytes(50331648L)
+ .build()
+ ))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/mediawiki")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/css")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/html")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/x-javascript")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/dita+xml")
+ .withTargetMediaType("text/plain")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("stringOptions"))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("officeToImageViaPdf")
+ .withTransformerPipeline(ImmutableList.of(
+ new TransformStep("libreoffice", "application/pdf"),
+ new TransformStep("pdfToImageViaPng", null)
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .build(),
+ Transformer.builder()
+ .withTransformerName("textToImageViaPdf")
+ .withTransformerPipeline(ImmutableList.of(
+ new TransformStep("libreoffice", "application/pdf"),
+ new TransformStep("pdfToImageViaPng", null)
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/png")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/png")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/png")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .build()
+ );
+ }
+
+ @Test
+ public void testRouteFileWithTransformOptions() throws Exception
+ {
+ final List expected = prepareSample5Transformers();
+ Map> expectedOptions = prepareSample5Options();
+
+ final Resource resource = new ClassPathResource("config/sample5.json");
+ final TransformConfigReader loader = TransformConfigReaderFactory.create(resource);
+
+ TransformConfig transformConfig = loader.load();
+ final List transformers = transformConfig.getTransformers();
+ Map> transformOptions = transformConfig.getTransformOptions();
+
+ assertNotNull(transformers);
+ assertEquals(expected.size(), transformers.size());
+ assertTrue(expected.containsAll(transformers));
+ assertEquals(expectedOptions, transformOptions);
+ }
+
+ private List prepareSample5Transformers()
+ {
+ return List.of(
+ Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("image/gif")
+ .withTargetMediaType("image/gif")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("imageMagickOptions"))
+ .build()
+ );
+ }
+
+ public static Map> prepareSample5Options()
+ {
+ return ImmutableMap.of(
+ "imageMagickOptions", ImmutableSet.of(
+ new TransformOptionValue(false, "alphaRemove"),
+ new TransformOptionValue(false, "autoOrient"),
+ new TransformOptionValue(false, "startPage"),
+ new TransformOptionValue(false, "endPage"),
+ new TransformOptionGroup(false, ImmutableSet.of(
+ new TransformOptionValue(false, "cropGravity"),
+ new TransformOptionValue(false, "cropWidth"),
+ new TransformOptionValue(false, "cropHeight"),
+ new TransformOptionValue(false, "cropPercentage"),
+ new TransformOptionValue(false, "cropXOffset"),
+ new TransformOptionValue(false, "cropYOffset")
+ )),
+ new TransformOptionGroup(false, ImmutableSet.of(
+ new TransformOptionValue(false, "thumbnail"),
+ new TransformOptionValue(false, "resizeHeight"),
+ new TransformOptionValue(false, "resizeWidth"),
+ new TransformOptionValue(false, "resizePercentage"),
+ new TransformOptionValue(false, "allowEnlargement"),
+ new TransformOptionValue(false, "maintainAspectRatio")
+ )))
+ );
+ }
+}
\ No newline at end of file
diff --git a/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderYamlTest.java b/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderYamlTest.java
new file mode 100644
index 00000000..1449d139
--- /dev/null
+++ b/model/src/test/java/org/alfresco/transform/config/reader/TransformConfigReaderYamlTest.java
@@ -0,0 +1,245 @@
+/*
+ * #%L
+ * Alfresco Transform Model
+ * %%
+ * Copyright (C) 2015 - 2022 Alfresco Software Limited
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+package org.alfresco.transform.config.reader;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.alfresco.transform.config.TransformConfig;
+import org.alfresco.transform.config.TransformOption;
+import org.alfresco.transform.config.Transformer;
+import org.alfresco.transform.config.SupportedSourceAndTarget;
+import org.alfresco.transform.config.TransformStep;
+import org.junit.jupiter.api.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class TransformConfigReaderYamlTest
+{
+ @Test
+ public void testEmptyRoutesFile() throws Exception
+ {
+ final Resource resource = new ClassPathResource("config/sample3.yaml");
+ final TransformConfigReader loader = TransformConfigReaderFactory.create(resource);
+ TransformConfig transformConfig = loader.load();
+ final List transformers = transformConfig.getTransformers();
+ assertNotNull(transformers);
+ assertEquals(Collections.emptyList(), transformers);
+ }
+
+ @Test
+ public void testMixedRoutesFile() throws Exception
+ {
+ final List expected = prepareSample4();
+ Map> expectedOptions = TransformConfigReaderJsonTest.prepareSample5Options();
+
+ final Resource resource = new ClassPathResource("config/sample4.yaml");
+ final TransformConfigReader loader = TransformConfigReaderFactory.create(resource);
+
+ TransformConfig transformConfig = loader.load();
+ final List transformers = transformConfig.getTransformers();
+ Map> transformOptions = transformConfig.getTransformOptions();
+
+ assertNotNull(transformers);
+ assertEquals(expected.size(), transformers.size());
+ assertTrue(expected.containsAll(transformers));
+ assertEquals(expectedOptions, transformOptions);
+ }
+
+ private List prepareSample4()
+ {
+ var result = new ArrayList();
+ result.add(Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("image/gif")
+ .withTargetMediaType("image/gif")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("imageMagickOptions"))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("IMAGEMAGICK")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("image/gif")
+ .withTargetMediaType("image/gif")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("imageMagickOptions"))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/msword")
+ .withTargetMediaType("application/pdf")
+ .withMaxSourceSizeBytes(18874368L)
+ .build()
+ ))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("PDF_RENDERER")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/vnd.ms-powerpoint")
+ .withTargetMediaType("application/pdf")
+ .withPriority(55)
+ .withMaxSourceSizeBytes(50331648L)
+ .build()
+ ))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("CORE_AIO")
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/mediawiki")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/css")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/html")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/x-javascript")
+ .withTargetMediaType("text/plain")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("application/dita+xml")
+ .withTargetMediaType("text/plain")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of("stringOptions"))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("officeToImageViaPdf")
+ .withTransformerPipeline(ImmutableList.of(
+ new TransformStep("libreoffice", "application/pdf"),
+ new TransformStep("pdfToImageViaPng", null)
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .build());
+
+ result.add(Transformer.builder()
+ .withTransformerName("textToImageViaPdf")
+ .withTransformerPipeline(ImmutableList.of(
+ new TransformStep("libreoffice", "application/pdf"),
+ new TransformStep("pdfToImageViaPng", null)
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .withSupportedSourceAndTargetList(ImmutableSet.of(
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/plain")
+ .withTargetMediaType("image/png")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/csv")
+ .withTargetMediaType("image/png")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/gif")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/jpeg")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/tiff")
+ .build(),
+ SupportedSourceAndTarget.builder()
+ .withSourceMediaType("text/xml")
+ .withTargetMediaType("image/png")
+ .build()
+ ))
+ .withTransformOptions(ImmutableSet.of(
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ))
+ .build());
+
+ return result;
+ }
+}
diff --git a/model/src/test/java/org/alfresco/transform/registry/TransformRegistryHelperTest.java b/model/src/test/java/org/alfresco/transform/registry/TransformRegistryHelperTest.java
index 83895f11..cc05f9cf 100644
--- a/model/src/test/java/org/alfresco/transform/registry/TransformRegistryHelperTest.java
+++ b/model/src/test/java/org/alfresco/transform/registry/TransformRegistryHelperTest.java
@@ -30,11 +30,13 @@ import com.google.common.collect.ImmutableMap;
import org.alfresco.transform.common.TransformException;
import org.junit.jupiter.api.Test;
+import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
+import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING;
import static org.alfresco.transform.common.RequestParamMap.TIMEOUT;
import static org.alfresco.transform.registry.TransformRegistryHelper.retrieveTransformListBySize;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -192,7 +194,21 @@ public class TransformRegistryHelperTest
assertThrows(TransformException.class, () ->
{
- retrieveTransformListBySize(data, "text/plain", null, ImmutableMap.of(TIMEOUT, "1234"), null);
+ retrieveTransformListBySize(data, "text/plain", null,
+ new HashMap<>(ImmutableMap.of(TIMEOUT, "1234")), null);
+ });
+ }
+
+ @Test
+ public void filterSourceEncodingTest()
+ {
+ // Almost identical to buildTransformListTargetMimeTypeNullErrorTest
+ TransformCache data = new TransformCache();
+
+ assertThrows(TransformException.class, () ->
+ {
+ retrieveTransformListBySize(data, "text/plain", null,
+ new HashMap<>(ImmutableMap.of(SOURCE_ENCODING, "UTF-8")), null);
});
}
}
diff --git a/model/src/test/resources/config/sample1.json b/model/src/test/resources/config/sample1.json
new file mode 100644
index 00000000..d3cd00be
--- /dev/null
+++ b/model/src/test/resources/config/sample1.json
@@ -0,0 +1,3 @@
+{
+ "transformers":[]
+}
\ No newline at end of file
diff --git a/model/src/test/resources/config/sample2.json b/model/src/test/resources/config/sample2.json
new file mode 100644
index 00000000..7f3126c9
--- /dev/null
+++ b/model/src/test/resources/config/sample2.json
@@ -0,0 +1,92 @@
+{
+ "transformers": [
+ {
+ "transformerName": "CORE_AIO",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "image/gif", "targetMediaType": "image/gif" }
+ ],
+ "transformOptions": [
+ "imageMagickOptions"
+ ]
+ },
+ {
+ "transformerName": "IMAGEMAGICK",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "image/gif", "targetMediaType": "image/gif" }
+ ],
+ "transformOptions": [
+ "imageMagickOptions"
+ ]
+ },
+ {
+ "transformerName": "CORE_AIO",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "application/msword", "maxSourceSizeBytes": 18874368, "targetMediaType": "application/pdf" }
+ ]
+ },
+ {
+ "transformerName": "PDF_RENDERER",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "application/vnd.ms-powerpoint", "maxSourceSizeBytes": 50331648, "priority": 55, "targetMediaType": "application/pdf" }
+ ],
+ "transformOptions": [
+ ]
+ },
+ {
+ "transformerName": "CORE_AIO",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "text/plain", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "text/mediawiki", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "text/css", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "text/csv", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "text/xml", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "text/html", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "application/x-javascript", "targetMediaType": "text/plain" },
+ {"sourceMediaType": "application/dita+xml", "targetMediaType": "text/plain" }
+ ],
+ "transformOptions": [
+ "stringOptions"
+ ]
+ },
+ {
+ "transformerName": "officeToImageViaPdf",
+ "transformerPipeline" : [
+ {"transformerName": "libreoffice", "targetMediaType": "application/pdf"},
+ {"transformerName": "pdfToImageViaPng"}
+ ],
+ "supportedSourceAndTargetList": [
+ ],
+ "transformOptions": [
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ]
+ },
+ {
+ "transformerName": "textToImageViaPdf",
+ "transformerPipeline" : [
+ {"transformerName": "libreoffice", "targetMediaType": "application/pdf"},
+ {"transformerName": "pdfToImageViaPng"}
+ ],
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "text/plain", "targetMediaType": "image/gif" },
+ {"sourceMediaType": "text/plain", "targetMediaType": "image/jpeg"},
+ {"sourceMediaType": "text/plain", "targetMediaType": "image/tiff"},
+ {"sourceMediaType": "text/plain", "targetMediaType": "image/png" },
+
+ {"sourceMediaType": "text/csv", "targetMediaType": "image/gif" },
+ {"sourceMediaType": "text/csv", "targetMediaType": "image/jpeg"},
+ {"sourceMediaType": "text/csv", "targetMediaType": "image/tiff"},
+ {"sourceMediaType": "text/csv", "targetMediaType": "image/png" },
+
+ {"sourceMediaType": "text/xml", "targetMediaType": "image/gif" },
+ {"sourceMediaType": "text/xml", "targetMediaType": "image/jpeg"},
+ {"sourceMediaType": "text/xml", "targetMediaType": "image/tiff"},
+ {"sourceMediaType": "text/xml", "targetMediaType": "image/png" }
+ ],
+ "transformOptions": [
+ "pdfRendererOptions",
+ "imageMagickOptions"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/model/src/test/resources/config/sample3.yaml b/model/src/test/resources/config/sample3.yaml
new file mode 100644
index 00000000..0f0be92e
--- /dev/null
+++ b/model/src/test/resources/config/sample3.yaml
@@ -0,0 +1,2 @@
+---
+transformers:
\ No newline at end of file
diff --git a/model/src/test/resources/config/sample4.yaml b/model/src/test/resources/config/sample4.yaml
new file mode 100644
index 00000000..22d051f0
--- /dev/null
+++ b/model/src/test/resources/config/sample4.yaml
@@ -0,0 +1,130 @@
+---
+transformOptions:
+ imageMagickOptions:
+ - value:
+ name: alphaRemove
+ - value:
+ name: autoOrient
+ - value:
+ name: startPage
+ - value:
+ name: endPage
+ - group:
+ transformOptions:
+ - value:
+ name: cropGravity
+ - value:
+ name: cropWidth
+ - value:
+ name: cropHeight
+ - value:
+ name: cropPercentage
+ - value:
+ name: cropXOffset
+ - value:
+ name: cropYOffset
+ - group:
+ transformOptions:
+ - value:
+ name: thumbnail
+ - value:
+ name: resizeHeight
+ - value:
+ name: resizeWidth
+ - value:
+ name: resizePercentage
+ - value:
+ name: allowEnlargement
+ - value:
+ name: maintainAspectRatio
+transformers:
+ - transformerName: CORE_AIO
+ supportedSourceAndTargetList:
+ - sourceMediaType: image/gif
+ targetMediaType: image/gif
+ transformOptions:
+ - imageMagickOptions
+
+
+ - transformerName: IMAGEMAGICK
+ supportedSourceAndTargetList:
+ - sourceMediaType: image/gif
+ targetMediaType: image/gif
+ transformOptions:
+ - imageMagickOptions
+
+ - transformerName: PDF_RENDERER
+ supportedSourceAndTargetList:
+ - sourceMediaType: application/vnd.ms-powerpoint
+ targetMediaType: application/pdf
+ priority: 55
+ maxSourceSizeBytes: 50331648
+ transformOptions: []
+ - transformerName: CORE_AIO
+ supportedSourceAndTargetList:
+ - sourceMediaType: application/msword
+ targetMediaType: application/pdf
+ maxSourceSizeBytes: 18874368
+
+ - transformerName: CORE_AIO
+ supportedSourceAndTargetList:
+ - sourceMediaType: text/plain
+ targetMediaType: text/plain
+ - sourceMediaType: text/mediawiki
+ targetMediaType: text/plain
+ - sourceMediaType: text/css
+ targetMediaType: text/plain
+ - sourceMediaType: text/csv
+ targetMediaType: text/plain
+ - sourceMediaType: text/xml
+ targetMediaType: text/plain
+ - sourceMediaType: text/html
+ targetMediaType: text/plain
+ - sourceMediaType: application/x-javascript
+ targetMediaType: text/plain
+ - sourceMediaType: application/dita+xml
+ targetMediaType: text/plain
+ transformOptions:
+ - stringOptions
+
+ - transformerName: officeToImageViaPdf
+ transformerPipeline:
+ - transformerName: libreoffice
+ targetMediaType: application/pdf
+ - transformerName: pdfToImageViaPng
+ transformOptions:
+ - pdfRendererOptions
+ - imageMagickOptions
+ - transformerName: textToImageViaPdf
+ transformerPipeline:
+ - transformerName: libreoffice
+ targetMediaType: application/pdf
+ - transformerName: pdfToImageViaPng
+ supportedSourceAndTargetList:
+ - sourceMediaType: text/plain
+ targetMediaType: image/gif
+ - sourceMediaType: text/plain
+ targetMediaType: image/jpeg
+ - sourceMediaType: text/plain
+ targetMediaType: image/tiff
+ - sourceMediaType: text/plain
+ targetMediaType: image/png
+ - sourceMediaType: text/csv
+ targetMediaType: image/gif
+ - sourceMediaType: text/csv
+ targetMediaType: image/jpeg
+ - sourceMediaType: text/csv
+ targetMediaType: image/tiff
+ - sourceMediaType: text/csv
+ targetMediaType: image/png
+ - sourceMediaType: text/xml
+ targetMediaType: image/gif
+ - sourceMediaType: text/xml
+ targetMediaType: image/jpeg
+ - sourceMediaType: text/xml
+ targetMediaType: image/tiff
+ - sourceMediaType: text/xml
+ targetMediaType: image/png
+ transformOptions:
+ - pdfRendererOptions
+ - imageMagickOptions
diff --git a/model/src/test/resources/config/sample5.json b/model/src/test/resources/config/sample5.json
new file mode 100644
index 00000000..4536edce
--- /dev/null
+++ b/model/src/test/resources/config/sample5.json
@@ -0,0 +1,37 @@
+{
+ "transformOptions": {
+ "imageMagickOptions": [
+ {"value": {"name": "alphaRemove"}},
+ {"value": {"name": "autoOrient"}},
+ {"value": {"name": "startPage"}},
+ {"value": {"name": "endPage"}},
+ {"group": {"transformOptions": [
+ {"value": {"name": "cropGravity"}},
+ {"value": {"name": "cropWidth"}},
+ {"value": {"name": "cropHeight"}},
+ {"value": {"name": "cropPercentage"}},
+ {"value": {"name": "cropXOffset"}},
+ {"value": {"name": "cropYOffset"}}
+ ]}},
+ {"group": {"transformOptions": [
+ {"value": {"name": "thumbnail"}},
+ {"value": {"name": "resizeHeight"}},
+ {"value": {"name": "resizeWidth"}},
+ {"value": {"name": "resizePercentage"}},
+ {"value": {"name": "allowEnlargement"}},
+ {"value": {"name": "maintainAspectRatio"}}
+ ]}}
+ ]
+ },
+ "transformers": [
+ {
+ "transformerName": "CORE_AIO",
+ "supportedSourceAndTargetList": [
+ {"sourceMediaType": "image/gif", "targetMediaType": "image/gif" }
+ ],
+ "transformOptions": [
+ "imageMagickOptions"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 66a0406d..367fb2f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,6 @@
org.springframework.boot
spring-boot-starter-parent
2.7.2
-