mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
REPO-4639 Content conversion failed using Tika (#587)
The Tika T-Engine was not being called by the Transform Service or Local transforms, because the sub-transform name was required. Moved common classes (with repo) to alfresco-transform-model so that it can be used by the T-Engines to work out which sub transformer to use. InT also performed a refactor on these classes (alfresco-transform-model 1.0.2.7). Also includes changes to legacy transformers so that they don't pass the sub transformer name any more.
This commit is contained in:
20
.travis.yml
20
.travis.yml
@@ -64,11 +64,11 @@ jobs:
|
|||||||
before_install:
|
before_install:
|
||||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.4 postgres -c 'max_connections=300'
|
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.4 postgres -c 'max_connections=300'
|
||||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
|
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
|
||||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-pdf-renderer:2.1.0-EA4
|
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-pdf-renderer:2.1.0-DEV1
|
||||||
- docker run -d -p 8091:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-imagemagick:2.1.0-EA4
|
- docker run -d -p 8091:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-imagemagick:2.1.0-DEV1
|
||||||
- docker run -d -p 8092:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-libreoffice:2.1.0-EA4
|
- docker run -d -p 8092:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-libreoffice:2.1.0-DEV1
|
||||||
- docker run -d -p 8093:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-tika:2.1.0-EA4
|
- docker run -d -p 8093:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-tika:2.1.0-DEV1
|
||||||
- docker run -d -p 8094:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-misc:2.1.0-EA4
|
- docker run -d -p 8094:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-misc:2.1.0-DEV1
|
||||||
script: travis_wait 20 mvn test -B -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8092/ -Dimg.url=http://localhost:8091/ -Dtika.url=http://localhost:8093/ -Dtransform.misc.url=http://localhost:8094/
|
script: travis_wait 20 mvn test -B -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8092/ -Dimg.url=http://localhost:8091/ -Dtika.url=http://localhost:8093/ -Dtransform.misc.url=http://localhost:8094/
|
||||||
- name: "AppContextExtraTestSuite"
|
- name: "AppContextExtraTestSuite"
|
||||||
before_install:
|
before_install:
|
||||||
@@ -79,11 +79,11 @@ jobs:
|
|||||||
before_install:
|
before_install:
|
||||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.4 postgres -c 'max_connections=300'
|
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:11.4 postgres -c 'max_connections=300'
|
||||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
|
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.15.8
|
||||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-pdf-renderer:2.1.0-EA4
|
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-pdf-renderer:2.1.0-DEV1
|
||||||
- docker run -d -p 8091:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-imagemagick:2.1.0-EA4
|
- docker run -d -p 8091:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-imagemagick:2.1.0-DEV1
|
||||||
- docker run -d -p 8092:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-libreoffice:2.1.0-EA4
|
- docker run -d -p 8092:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-libreoffice:2.1.0-DEV1
|
||||||
- docker run -d -p 8093:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-tika:2.1.0-EA4
|
- docker run -d -p 8093:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-tika:2.1.0-DEV1
|
||||||
- docker run -d -p 8094:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-misc:2.1.0-EA4
|
- docker run -d -p 8094:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-misc:2.1.0-DEV1
|
||||||
script: travis_wait 20 mvn test -B -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8092/ -Dimg.url=http://localhost:8091/ -Dtika.url=http://localhost:8093/ -Dtransform.misc.url=http://localhost:8094/
|
script: travis_wait 20 mvn test -B -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco -Dalfresco-pdf-renderer.url=http://localhost:8090/ -Djodconverter.url=http://localhost:8092/ -Dimg.url=http://localhost:8091/ -Dtika.url=http://localhost:8093/ -Dtransform.misc.url=http://localhost:8094/
|
||||||
- name: "MySQL tests"
|
- name: "MySQL tests"
|
||||||
before_install:
|
before_install:
|
||||||
|
14
pom.xml
14
pom.xml
@@ -40,11 +40,11 @@
|
|||||||
<dependency.alfresco-legacy-lucene.version>6.2</dependency.alfresco-legacy-lucene.version>
|
<dependency.alfresco-legacy-lucene.version>6.2</dependency.alfresco-legacy-lucene.version>
|
||||||
<dependency.alfresco-core.version>7.21</dependency.alfresco-core.version>
|
<dependency.alfresco-core.version>7.21</dependency.alfresco-core.version>
|
||||||
<dependency.alfresco-greenmail.version>6.1</dependency.alfresco-greenmail.version>
|
<dependency.alfresco-greenmail.version>6.1</dependency.alfresco-greenmail.version>
|
||||||
<dependency.alfresco-data-model.version>8.48</dependency.alfresco-data-model.version>
|
<dependency.alfresco-data-model.version>8.49</dependency.alfresco-data-model.version>
|
||||||
<dependency.alfresco-jlan.version>7.1</dependency.alfresco-jlan.version>
|
<dependency.alfresco-jlan.version>7.1</dependency.alfresco-jlan.version>
|
||||||
<dependency.alfresco-pdf-renderer.version>1.1</dependency.alfresco-pdf-renderer.version>
|
<dependency.alfresco-pdf-renderer.version>1.1</dependency.alfresco-pdf-renderer.version>
|
||||||
<dependency.alfresco-hb-data-sender.version>1.0.11</dependency.alfresco-hb-data-sender.version>
|
<dependency.alfresco-hb-data-sender.version>1.0.11</dependency.alfresco-hb-data-sender.version>
|
||||||
|
<dependency.transform.model.version>1.0.2.7</dependency.transform.model.version>
|
||||||
|
|
||||||
<dependency.spring.version>5.1.8.RELEASE</dependency.spring.version>
|
<dependency.spring.version>5.1.8.RELEASE</dependency.spring.version>
|
||||||
<dependency.httpcomponents.version>4.5.9</dependency.httpcomponents.version>
|
<dependency.httpcomponents.version>4.5.9</dependency.httpcomponents.version>
|
||||||
@@ -66,7 +66,6 @@
|
|||||||
<dependency.cxf.version>3.3.2</dependency.cxf.version>
|
<dependency.cxf.version>3.3.2</dependency.cxf.version>
|
||||||
<dependency.jackson.version>2.9.9</dependency.jackson.version>
|
<dependency.jackson.version>2.9.9</dependency.jackson.version>
|
||||||
<dependency.jackson-databind.version>2.9.9.3</dependency.jackson-databind.version>
|
<dependency.jackson-databind.version>2.9.9.3</dependency.jackson-databind.version>
|
||||||
<dependency.transform.model.version>1.0.2.5</dependency.transform.model.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -194,7 +193,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
<version>1.18</version>
|
<version>1.19</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@@ -1052,6 +1051,13 @@
|
|||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transform-model</artifactId>
|
||||||
|
<version>${dependency.transform.model.version}</version>
|
||||||
|
<classifier>tests</classifier>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-core</artifactId>
|
<artifactId>alfresco-core</artifactId>
|
||||||
|
@@ -141,12 +141,6 @@ public class ArchiveContentTransformer extends TikaPoweredContentTransformer
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "Archive";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void transformRemote(RemoteTransformerClient remoteTransformerClient, ContentReader reader,
|
protected void transformRemote(RemoteTransformerClient remoteTransformerClient, ContentReader reader,
|
||||||
ContentWriter writer, TransformationOptions options,
|
ContentWriter writer, TransformationOptions options,
|
||||||
@@ -154,7 +148,6 @@ public class ArchiveContentTransformer extends TikaPoweredContentTransformer
|
|||||||
String sourceExtension, String targetExtension,
|
String sourceExtension, String targetExtension,
|
||||||
String targetEncoding) throws Exception
|
String targetEncoding) throws Exception
|
||||||
{
|
{
|
||||||
String transform = getTransform();
|
|
||||||
long timeoutMs = options.getTimeoutMs();
|
long timeoutMs = options.getTimeoutMs();
|
||||||
boolean recurse = includeContents;
|
boolean recurse = includeContents;
|
||||||
if(options.getIncludeEmbedded() != null)
|
if(options.getIncludeEmbedded() != null)
|
||||||
@@ -162,7 +155,10 @@ public class ArchiveContentTransformer extends TikaPoweredContentTransformer
|
|||||||
recurse = options.getIncludeEmbedded();
|
recurse = options.getIncludeEmbedded();
|
||||||
}
|
}
|
||||||
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
||||||
timeoutMs, logger, "transform", transform, "includeContents", Boolean.toString(recurse),
|
timeoutMs, logger,
|
||||||
"targetMimetype", targetMimetype, "targetEncoding", targetEncoding);
|
"includeContents", Boolean.toString(recurse),
|
||||||
|
"sourceMimetype", sourceMimetype,
|
||||||
|
"targetMimetype", targetMimetype,
|
||||||
|
"targetEncoding", targetEncoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -143,11 +143,11 @@ public class LocalTransformImpl extends AbstractLocalTransform
|
|||||||
String sourceExtension, String targetExtension,
|
String sourceExtension, String targetExtension,
|
||||||
String renditionName, NodeRef sourceNodeRef) throws Exception
|
String renditionName, NodeRef sourceNodeRef) throws Exception
|
||||||
{
|
{
|
||||||
// At some point in the future, we may decide to only pass the sourceEncoding and other dynamic values like
|
// Only pass the sourceEncoding and other dynamic values like it if they were supplied in the rendition
|
||||||
// it if they were supplied in the rendition definition without a value. The sourceEncoding value is also
|
// definition without a value. The sourceEncoding value is also supplied in the RenditionEventProducer in
|
||||||
// supplied in the TransformRequest (message to the T-Router).
|
// the message to the T-Router.
|
||||||
transformOptions = new HashMap<>(transformOptions);
|
transformOptions = new HashMap<>(transformOptions);
|
||||||
if (transformOptions.get(SOURCE_ENCODING) == null)
|
if (transformOptions.containsKey(SOURCE_ENCODING) && transformOptions.get(SOURCE_ENCODING) == null)
|
||||||
{
|
{
|
||||||
String sourceEncoding = reader.getEncoding();
|
String sourceEncoding = reader.getEncoding();
|
||||||
transformOptions.put(SOURCE_ENCODING, sourceEncoding);
|
transformOptions.put(SOURCE_ENCODING, sourceEncoding);
|
||||||
|
@@ -25,20 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.content.transform;
|
package org.alfresco.repo.content.transform;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
|
||||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.transform.client.model.config.CombinedConfig;
|
|
||||||
import org.alfresco.transform.client.model.config.InlineTransformer;
|
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistryImpl;
|
|
||||||
import org.alfresco.transform.client.model.config.TransformStep;
|
|
||||||
import org.alfresco.util.PropertyCheck;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -48,6 +34,21 @@ import java.util.Map;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.transform.client.registry.CombinedConfig;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOption;
|
||||||
|
import org.alfresco.transform.client.registry.TransformServiceRegistryImpl;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformStep;
|
||||||
|
import org.alfresco.transform.client.model.config.Transformer;
|
||||||
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements {@link TransformServiceRegistry} providing a mechanism of validating if a local transformation
|
* Implements {@link TransformServiceRegistry} providing a mechanism of validating if a local transformation
|
||||||
* (based on {@link LocalTransform} request is supported. It also extends this interface to provide a
|
* (based on {@link LocalTransform} request is supported. It also extends this interface to provide a
|
||||||
@@ -156,7 +157,8 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void register(InlineTransformer transformer, String baseUrl, String readFrom)
|
public void register(Transformer transformer, Map<String, Set<TransformOption>> transformOptions,
|
||||||
|
String baseUrl, String readFrom)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -242,7 +244,7 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
localTransforms.put(name, localTransform);
|
localTransforms.put(name, localTransform);
|
||||||
super.register(transformer, baseUrl, readFrom);
|
super.register(transformer, transformOptions, baseUrl, readFrom);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
@@ -394,7 +396,7 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
public long findMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
||||||
{
|
{
|
||||||
// This message is not logged if placed in afterPropertiesSet
|
// This message is not logged if placed in afterPropertiesSet
|
||||||
if (getFirstTime())
|
if (getFirstTime())
|
||||||
@@ -404,7 +406,7 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
return enabled
|
return enabled
|
||||||
? super.getMaxSize(sourceMimetype, targetMimetype, options, renditionName)
|
? super.findMaxSize(sourceMimetype, targetMimetype, options, renditionName)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,7 +424,7 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
|||||||
public LocalTransform getLocalTransform(Map<String, String> actualOptions, String renditionName,
|
public LocalTransform getLocalTransform(Map<String, String> actualOptions, String renditionName,
|
||||||
String sourceMimetype, String targetMimetype, long sourceSizeInBytes)
|
String sourceMimetype, String targetMimetype, long sourceSizeInBytes)
|
||||||
{
|
{
|
||||||
String name = getTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, renditionName);
|
String name = findTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, renditionName);
|
||||||
LocalData data = getData();
|
LocalData data = getData();
|
||||||
Map<String, LocalTransform> localTransforms = data.localTransforms;
|
Map<String, LocalTransform> localTransforms = data.localTransforms;
|
||||||
return localTransforms.get(name);
|
return localTransforms.get(name);
|
||||||
|
@@ -51,10 +51,4 @@ public class MailContentTransformer extends TikaPoweredContentTransformer
|
|||||||
protected Parser getParser() {
|
protected Parser getParser() {
|
||||||
return new OfficeParser();
|
return new OfficeParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "OutlookMsg";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -98,13 +98,6 @@ public class PdfBoxContentTransformer extends TikaPoweredContentTransformer
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "PdfBox";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void transformRemote(RemoteTransformerClient remoteTransformerClient, ContentReader reader,
|
protected void transformRemote(RemoteTransformerClient remoteTransformerClient, ContentReader reader,
|
||||||
ContentWriter writer, TransformationOptions options,
|
ContentWriter writer, TransformationOptions options,
|
||||||
@@ -112,8 +105,6 @@ public class PdfBoxContentTransformer extends TikaPoweredContentTransformer
|
|||||||
String sourceExtension, String targetExtension,
|
String sourceExtension, String targetExtension,
|
||||||
String targetEncoding) throws Exception
|
String targetEncoding) throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
String transform = getTransform();
|
|
||||||
long timeoutMs = options.getTimeoutMs();
|
long timeoutMs = options.getTimeoutMs();
|
||||||
String notExtractBookmarksText = null;
|
String notExtractBookmarksText = null;
|
||||||
|
|
||||||
@@ -124,8 +115,8 @@ public class PdfBoxContentTransformer extends TikaPoweredContentTransformer
|
|||||||
|
|
||||||
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
||||||
timeoutMs, logger,
|
timeoutMs, logger,
|
||||||
"transform", transform,
|
|
||||||
"notExtractBookmarksText", notExtractBookmarksText,
|
"notExtractBookmarksText", notExtractBookmarksText,
|
||||||
|
"sourceMimetype", sourceMimetype,
|
||||||
"targetMimetype", targetMimetype,
|
"targetMimetype", targetMimetype,
|
||||||
"targetEncoding", targetEncoding);
|
"targetEncoding", targetEncoding);
|
||||||
}
|
}
|
||||||
|
@@ -76,10 +76,4 @@ public class PoiContentTransformer extends TikaPoweredContentTransformer
|
|||||||
protected Parser getParser() {
|
protected Parser getParser() {
|
||||||
return new OfficeParser();
|
return new OfficeParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "Office";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -211,10 +211,4 @@ public class PoiHssfContentTransformer extends TikaPoweredContentTransformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "Poi";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -65,10 +65,4 @@ public class PoiOOXMLContentTransformer extends TikaPoweredContentTransformer
|
|||||||
protected Parser getParser() {
|
protected Parser getParser() {
|
||||||
return new OOXMLParser();
|
return new OOXMLParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "OOXML";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -51,10 +51,4 @@ public class TextMiningContentTransformer extends TikaPoweredContentTransformer
|
|||||||
protected Parser getParser() {
|
protected Parser getParser() {
|
||||||
return new OfficeParser();
|
return new OfficeParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "TextMining";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -131,10 +131,4 @@ public class TikaAutoContentTransformer extends TikaPoweredContentTransformer
|
|||||||
{
|
{
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "TikaAuto";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -292,18 +292,15 @@ public abstract class TikaPoweredContentTransformer extends AbstractRemoteConten
|
|||||||
String sourceExtension, String targetExtension,
|
String sourceExtension, String targetExtension,
|
||||||
String targetEncoding) throws Exception
|
String targetEncoding) throws Exception
|
||||||
{
|
{
|
||||||
String transform = getTransform();
|
|
||||||
long timeoutMs = options.getTimeoutMs();
|
long timeoutMs = options.getTimeoutMs();
|
||||||
|
|
||||||
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
||||||
timeoutMs, logger,
|
timeoutMs, logger,
|
||||||
"transform", transform,
|
"sourceMimetype", sourceMimetype,
|
||||||
"targetMimetype", targetMimetype,
|
"targetMimetype", targetMimetype,
|
||||||
"targetEncoding", targetEncoding);
|
"targetEncoding", targetEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getTransform();
|
|
||||||
|
|
||||||
private String calculateMemoryAndTimeUsage(ContentReader reader, long startTime)
|
private String calculateMemoryAndTimeUsage(ContentReader reader, long startTime)
|
||||||
{
|
{
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
|
@@ -107,10 +107,4 @@ public class TikaSpringConfiguredContentTransformer extends TikaPoweredContentTr
|
|||||||
throw new AlfrescoRuntimeException("Unable to create specified Parser", e);
|
throw new AlfrescoRuntimeException("Unable to create specified Parser", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransform()
|
|
||||||
{
|
|
||||||
return "tikaspring"; // This transformer is no longer created by Spring, so is not supported by the Tika transformer image
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -25,10 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rendition2;
|
package org.alfresco.repo.rendition2;
|
||||||
|
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains common code used in TransformServiceRegistries.
|
* Contains common code used in TransformServiceRegistries.
|
||||||
*
|
*
|
||||||
@@ -37,9 +37,8 @@ import java.util.Map;
|
|||||||
public abstract class AbstractTransformServiceRegistry implements TransformServiceRegistry
|
public abstract class AbstractTransformServiceRegistry implements TransformServiceRegistry
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(String sourceMimetype, long size, String targetMimetype, Map<String, String> options, String renditionName)
|
public String findTransformerName(String sourceMimetype, long sourceSizeInBytes, String targetMimetype, Map<String, String> actualOptions, String renditionName)
|
||||||
{
|
{
|
||||||
long maxSize = getMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
throw new UnsupportedOperationException("AbstractTransformServiceRegistry.findTransformerName(...) is not supported. Only supported in ");
|
||||||
return maxSize != 0 && (maxSize == -1L || maxSize >= size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ package org.alfresco.repo.rendition2;
|
|||||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ public class LegacyTransformServiceRegistry extends AbstractTransformServiceRegi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
public long findMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
||||||
{
|
{
|
||||||
// This message is not logged if placed in afterPropertiesSet
|
// This message is not logged if placed in afterPropertiesSet
|
||||||
if (firstTime)
|
if (firstTime)
|
||||||
|
@@ -27,7 +27,7 @@ package org.alfresco.repo.rendition2;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
import org.alfresco.util.ConfigFileFinder;
|
import org.alfresco.util.ConfigFileFinder;
|
||||||
import org.alfresco.util.ConfigScheduler;
|
import org.alfresco.util.ConfigScheduler;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
@@ -343,7 +343,7 @@ public class RenditionDefinitionRegistry2Impl implements RenditionDefinitionRegi
|
|||||||
String targetMimetype = renditionDefinition2.getTargetMimetype();
|
String targetMimetype = renditionDefinition2.getTargetMimetype();
|
||||||
String renditionName = renditionDefinition2.getRenditionName();
|
String renditionName = renditionDefinition2.getRenditionName();
|
||||||
Map<String, String> options = renditionDefinition2.getTransformOptions();
|
Map<String, String> options = renditionDefinition2.getTransformOptions();
|
||||||
Long maxSize = transformServiceRegistry.getMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
Long maxSize = transformServiceRegistry.findMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
||||||
if (maxSize != null)
|
if (maxSize != null)
|
||||||
{
|
{
|
||||||
String renditionNameMaxSizePair = entry.getKey();
|
String renditionNameMaxSizePair = entry.getKey();
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rendition2;
|
package org.alfresco.repo.rendition2;
|
||||||
|
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -46,17 +46,17 @@ public class SwitchingTransformServiceRegistry extends AbstractTransformServiceR
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
public long findMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
||||||
{
|
{
|
||||||
long maxSize;
|
long maxSize;
|
||||||
long primaryMaxSize = primary.getMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
long primaryMaxSize = primary.findMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
||||||
if (primaryMaxSize == -1L)
|
if (primaryMaxSize == -1L)
|
||||||
{
|
{
|
||||||
maxSize = -1L;
|
maxSize = -1L;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
long secondaryMaxSize = secondary.getMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
long secondaryMaxSize = secondary.findMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
||||||
maxSize = primaryMaxSize == 0
|
maxSize = primaryMaxSize == 0
|
||||||
? secondaryMaxSize
|
? secondaryMaxSize
|
||||||
: secondaryMaxSize == 0
|
: secondaryMaxSize == 0
|
||||||
|
@@ -45,7 +45,7 @@ import org.alfresco.service.cmr.thumbnail.ThumbnailException;
|
|||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
@@ -457,7 +457,7 @@ public class ThumbnailRegistry implements ApplicationContextAware, ApplicationLi
|
|||||||
{
|
{
|
||||||
Map<String, String> options = renditionDefinition.getTransformOptions();
|
Map<String, String> options = renditionDefinition.getTransformOptions();
|
||||||
String renditionName = renditionDefinition.getRenditionName();
|
String renditionName = renditionDefinition.getRenditionName();
|
||||||
maxSize = transformServiceRegistry.getMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
maxSize = transformServiceRegistry.findMaxSize(sourceMimetype, targetMimetype, options, renditionName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a single transformer in a pipeline of multiple transformers. A transformer's options may be optional or
|
|
||||||
* required in the containing transformer. Historically in ACS only options for the final transformer were provided.
|
|
||||||
*/
|
|
||||||
public class ChildTransformer
|
|
||||||
{
|
|
||||||
private boolean required;
|
|
||||||
private InlineTransformer transformer;
|
|
||||||
|
|
||||||
public ChildTransformer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChildTransformer(boolean required, InlineTransformer transformer)
|
|
||||||
{
|
|
||||||
this.required = required;
|
|
||||||
this.transformer = transformer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRequired()
|
|
||||||
{
|
|
||||||
return required;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequired(boolean required)
|
|
||||||
{
|
|
||||||
this.required = required;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InlineTransformer getTransformer()
|
|
||||||
{
|
|
||||||
return transformer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransformer(InlineTransformer transformer)
|
|
||||||
{
|
|
||||||
this.transformer = transformer;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,440 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2019 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
|
||||||
import org.alfresco.util.ConfigFileFinder;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.StatusLine;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class recreates the json format used in ACS 6.1 where we just had an array of transformers and each
|
|
||||||
* transformer has a list of node options. The idea of this code is that it replaces the references with the
|
|
||||||
* actual node options that have been separated out into their own section.<p>
|
|
||||||
*
|
|
||||||
* The T-Router and T-Engines return the format with the node option separated into their own section. Pipeline
|
|
||||||
* definitions used by the LocalTransformServiceRegistry may use node reference options defined in the json
|
|
||||||
* returned by T-Engines. with the actual definitions from the node options
|
|
||||||
* reference section. It also combines multiple json sources into a single jsonNode structure that can be parsed as
|
|
||||||
* before.
|
|
||||||
*/
|
|
||||||
public class CombinedConfig
|
|
||||||
{
|
|
||||||
private static final String TRANSFORMER_NAME = "transformerName";
|
|
||||||
private static final String TRANSFORM_CONFIG = "/transform/config";
|
|
||||||
private static final String TRANSFORM_OPTIONS = "transformOptions";
|
|
||||||
private static final String GROUP = "group";
|
|
||||||
private static final String TRANSFORMERS = "transformers";
|
|
||||||
|
|
||||||
private final Log log;
|
|
||||||
private Map<String, ArrayNode> allTransformOptions = new HashMap<>();
|
|
||||||
private List<TransformNodeAndItsOrigin> allTransforms = new ArrayList<>();
|
|
||||||
private ObjectMapper jsonObjectMapper = new ObjectMapper();
|
|
||||||
private ConfigFileFinder configFileFinder;
|
|
||||||
private int tEngineCount;
|
|
||||||
|
|
||||||
static class TransformNodeAndItsOrigin
|
|
||||||
{
|
|
||||||
final ObjectNode node;
|
|
||||||
final String baseUrl;
|
|
||||||
final String readFrom;
|
|
||||||
|
|
||||||
TransformNodeAndItsOrigin(ObjectNode node, String baseUrl, String readFrom)
|
|
||||||
{
|
|
||||||
this.node = node;
|
|
||||||
this.baseUrl = baseUrl;
|
|
||||||
this.readFrom = readFrom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class TransformAndItsOrigin
|
|
||||||
{
|
|
||||||
final InlineTransformer transform;
|
|
||||||
final String baseUrl;
|
|
||||||
final String readFrom;
|
|
||||||
|
|
||||||
TransformAndItsOrigin(InlineTransformer transform, String baseUrl, String readFrom)
|
|
||||||
{
|
|
||||||
this.transform = transform;
|
|
||||||
this.baseUrl = baseUrl;
|
|
||||||
this.readFrom = readFrom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CombinedConfig(Log log)
|
|
||||||
{
|
|
||||||
this.log = log;
|
|
||||||
|
|
||||||
configFileFinder = new ConfigFileFinder(jsonObjectMapper)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void readJson(JsonNode jsonNode, String readFromMessage, String baseUrl) throws IOException
|
|
||||||
{
|
|
||||||
JsonNode transformOptions = jsonNode.get(TRANSFORM_OPTIONS);
|
|
||||||
if (transformOptions != null && transformOptions.isObject())
|
|
||||||
{
|
|
||||||
Iterator<Map.Entry<String, JsonNode>> iterator = transformOptions.fields();
|
|
||||||
while (iterator.hasNext())
|
|
||||||
{
|
|
||||||
Map.Entry<String, JsonNode> entry = iterator.next();
|
|
||||||
|
|
||||||
JsonNode options = entry.getValue();
|
|
||||||
if (options.isArray())
|
|
||||||
{
|
|
||||||
String optionsName = entry.getKey();
|
|
||||||
allTransformOptions.put(optionsName, (ArrayNode)options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode transformers = jsonNode.get(TRANSFORMERS);
|
|
||||||
if (transformers != null && transformers.isArray())
|
|
||||||
{
|
|
||||||
for (JsonNode transformer : transformers)
|
|
||||||
{
|
|
||||||
if (transformer.isObject())
|
|
||||||
{
|
|
||||||
allTransforms.add(new TransformNodeAndItsOrigin((ObjectNode)transformer, baseUrl, readFromMessage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addRemoteConfig(List<String> urls, String remoteType)
|
|
||||||
{
|
|
||||||
boolean successReadingConfig = true;
|
|
||||||
for (String url : urls)
|
|
||||||
{
|
|
||||||
if (addRemoteConfig(url, remoteType))
|
|
||||||
{
|
|
||||||
tEngineCount++ ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
successReadingConfig = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return successReadingConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean addRemoteConfig(String baseUrl, String remoteType)
|
|
||||||
{
|
|
||||||
String url = baseUrl + TRANSFORM_CONFIG;
|
|
||||||
HttpGet httpGet = new HttpGet(url);
|
|
||||||
boolean successReadingConfig = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
try (CloseableHttpClient httpclient = HttpClients.createDefault())
|
|
||||||
{
|
|
||||||
try (CloseableHttpResponse response = execute(httpclient, httpGet))
|
|
||||||
{
|
|
||||||
StatusLine statusLine = response.getStatusLine();
|
|
||||||
if (statusLine == null)
|
|
||||||
{
|
|
||||||
throw new AlfrescoRuntimeException(remoteType+" on " + url+" returned no status ");
|
|
||||||
}
|
|
||||||
HttpEntity resEntity = response.getEntity();
|
|
||||||
if (resEntity != null)
|
|
||||||
{
|
|
||||||
int statusCode = statusLine.getStatusCode();
|
|
||||||
if (statusCode == 200)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
String content = getContent(resEntity);
|
|
||||||
|
|
||||||
try (StringReader reader = new StringReader(content))
|
|
||||||
{
|
|
||||||
int transformCount = allTransforms.size();
|
|
||||||
configFileFinder.readFile(reader, remoteType+" on "+baseUrl, "json", baseUrl, log);
|
|
||||||
if (transformCount == allTransforms.size())
|
|
||||||
{
|
|
||||||
successReadingConfig = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityUtils.consume(resEntity);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new AlfrescoRuntimeException("Failed to read the returned content from "+
|
|
||||||
remoteType+" on " + url, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String message = getErrorMessage(resEntity);
|
|
||||||
throw new AlfrescoRuntimeException(remoteType+" on " + url+" returned a " + statusCode +
|
|
||||||
" status " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new AlfrescoRuntimeException(remoteType+" on " + url+" did not return an entity " + url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new AlfrescoRuntimeException("Failed to connect or to read the response from "+remoteType+
|
|
||||||
" on " + url, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new AlfrescoRuntimeException(remoteType+" on " + url+" failed to create an HttpClient", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (AlfrescoRuntimeException e)
|
|
||||||
{
|
|
||||||
log.error(e.getMessage());
|
|
||||||
successReadingConfig = false;
|
|
||||||
}
|
|
||||||
return successReadingConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests mock the return values
|
|
||||||
CloseableHttpResponse execute(CloseableHttpClient httpclient, HttpGet httpGet) throws IOException
|
|
||||||
{
|
|
||||||
return httpclient.execute(httpGet);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests mock the return values
|
|
||||||
String getContent(HttpEntity resEntity) throws IOException
|
|
||||||
{
|
|
||||||
return EntityUtils.toString(resEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strip out just the error message in the response
|
|
||||||
private String getErrorMessage(HttpEntity resEntity) throws IOException
|
|
||||||
{
|
|
||||||
String message = "";
|
|
||||||
String content = getContent(resEntity);
|
|
||||||
int i = content.indexOf("\"message\":\"");
|
|
||||||
if (i != -1)
|
|
||||||
{
|
|
||||||
int j = content.indexOf("\",\"path\":", i);
|
|
||||||
if (j != -1)
|
|
||||||
{
|
|
||||||
message = content.substring(i+11, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addLocalConfig(String path) throws IOException
|
|
||||||
{
|
|
||||||
return configFileFinder.readFiles(path, log);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(TransformServiceRegistryImpl registry) throws IOException
|
|
||||||
{
|
|
||||||
TransformServiceRegistryImpl.Data data = registry.getData();
|
|
||||||
data.setTEngineCount(tEngineCount);
|
|
||||||
data.setFileCount(configFileFinder.getFileCount());
|
|
||||||
List<TransformAndItsOrigin> transformers = getTransforms();
|
|
||||||
transformers.forEach(t->registry.register(t.transform, t.baseUrl, t.readFrom));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TransformAndItsOrigin> getTransforms() throws IOException
|
|
||||||
{
|
|
||||||
List<TransformAndItsOrigin> transforms = new ArrayList<>();
|
|
||||||
|
|
||||||
// After all json input has been loaded build the output with the options in place.
|
|
||||||
ArrayNode transformersNode = jsonObjectMapper.createArrayNode();
|
|
||||||
for (TransformNodeAndItsOrigin entity : allTransforms)
|
|
||||||
{
|
|
||||||
transformersNode.add(entity.node);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ArrayNode transformOptions = (ArrayNode) entity.node.get(TRANSFORM_OPTIONS);
|
|
||||||
if (transformOptions != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
ArrayNode options;
|
|
||||||
int size = transformOptions.size();
|
|
||||||
if (size == 1)
|
|
||||||
{
|
|
||||||
// If there is a single node option reference, we can just use it.
|
|
||||||
int i = 0;
|
|
||||||
options = getTransformOptions(transformOptions, i, entity.node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If there are many node option references (typically in a pipeline), then each element
|
|
||||||
// has a group for each set of node options.
|
|
||||||
options = jsonObjectMapper.createArrayNode();
|
|
||||||
for (int i = size - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
JsonNode referencedTransformOptions = getTransformOptions(transformOptions, i, entity.node);
|
|
||||||
if (referencedTransformOptions != null)
|
|
||||||
{
|
|
||||||
ObjectNode element = jsonObjectMapper.createObjectNode();
|
|
||||||
options.add(element);
|
|
||||||
|
|
||||||
ObjectNode group = jsonObjectMapper.createObjectNode();
|
|
||||||
group.set(TRANSFORM_OPTIONS, referencedTransformOptions);
|
|
||||||
element.set(GROUP, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (options == null || options.size() == 0)
|
|
||||||
{
|
|
||||||
entity.node.remove(TRANSFORM_OPTIONS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entity.node.set(TRANSFORM_OPTIONS, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InlineTransformer transform = jsonObjectMapper.convertValue(entity.node, InlineTransformer.class);
|
|
||||||
transforms.add(new TransformAndItsOrigin(transform, entity.baseUrl, entity.readFrom));
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
log.error("Invalid transformer "+getTransformName(entity.node)+" "+e.getMessage()+" baseUrl="+entity.baseUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
String transformString = jsonObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entity.node);
|
|
||||||
log.error(e.getMessage());
|
|
||||||
log.debug(transformString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (log.isTraceEnabled())
|
|
||||||
{
|
|
||||||
log.trace("Combined config:\n"+jsonObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(transformersNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
transforms = sortTransformers(transforms);
|
|
||||||
return transforms;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort transformers so there are no forward references, if that is possible.
|
|
||||||
private List<TransformAndItsOrigin> sortTransformers(List<TransformAndItsOrigin> original)
|
|
||||||
{
|
|
||||||
List<TransformAndItsOrigin> transformers = new ArrayList<>(original.size());
|
|
||||||
List<TransformAndItsOrigin> todo = new ArrayList<>(original.size());
|
|
||||||
Set<String> transformerNames = new HashSet<>();
|
|
||||||
boolean added;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
added = false;
|
|
||||||
for (TransformAndItsOrigin entry : original)
|
|
||||||
{
|
|
||||||
String name = entry.transform.getTransformerName();
|
|
||||||
List<TransformStep> pipeline = entry.transform.getTransformerPipeline();
|
|
||||||
boolean addEntry = true;
|
|
||||||
if (pipeline != null && !pipeline.isEmpty())
|
|
||||||
{
|
|
||||||
for (TransformStep step : pipeline)
|
|
||||||
{
|
|
||||||
String stepName = step.getTransformerName();
|
|
||||||
if (!transformerNames.contains(stepName))
|
|
||||||
{
|
|
||||||
todo.add(entry);
|
|
||||||
addEntry = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (addEntry)
|
|
||||||
{
|
|
||||||
transformers.add(entry);
|
|
||||||
added = true;
|
|
||||||
if (name != null)
|
|
||||||
{
|
|
||||||
transformerNames.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
original.clear();
|
|
||||||
original.addAll(todo);
|
|
||||||
todo.clear();
|
|
||||||
}
|
|
||||||
while (added && !original.isEmpty());
|
|
||||||
|
|
||||||
transformers.addAll(todo);
|
|
||||||
|
|
||||||
return transformers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayNode getTransformOptions(ArrayNode transformOptions, int i, ObjectNode transform)
|
|
||||||
{
|
|
||||||
ArrayNode options = null;
|
|
||||||
JsonNode optionName = transformOptions.get(i);
|
|
||||||
if (optionName.isTextual())
|
|
||||||
{
|
|
||||||
String name = optionName.asText();
|
|
||||||
options = allTransformOptions.get(name);
|
|
||||||
if (options == null)
|
|
||||||
{
|
|
||||||
String message = "Reference to \"transformOptions\": \"" + name + "\" not found. Transformer " +
|
|
||||||
getTransformName(transform) + " ignored.";
|
|
||||||
throw new IllegalArgumentException(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTransformName(ObjectNode transform)
|
|
||||||
{
|
|
||||||
String name = "Unknown";
|
|
||||||
JsonNode nameNode = transform.get(TRANSFORMER_NAME);
|
|
||||||
if (nameNode != null && nameNode.isTextual())
|
|
||||||
{
|
|
||||||
name = '"'+nameNode.asText()+'"';
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
import org.quartz.CronExpression;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by clients work out if a transformation is supported by a Transform Service.
|
|
||||||
*/
|
|
||||||
public interface TransformServiceRegistry
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Works out if the Transform Server should be able to transform content of a given source mimetype and size into a
|
|
||||||
* target mimetype given a list of actual transform option names and values (Strings) plus the data contained in the
|
|
||||||
* {@Transform} objects registered with this class.
|
|
||||||
* @param sourceMimetype the mimetype of the source content
|
|
||||||
* @param sourceSizeInBytes the size in bytes of the source content. Ignored if negative.
|
|
||||||
* @param targetMimetype the mimetype of the target
|
|
||||||
* @param actualOptions the actual name value pairs available that could be passed to the Transform Service.
|
|
||||||
* @param transformName (optional) name for the set of options and target mimetype. If supplied is used to cache
|
|
||||||
* results to avoid having to work out if a given transformation is supported a second time.
|
|
||||||
* The sourceMimetype and sourceSizeInBytes may still change. In the case of ACS this is the
|
|
||||||
* rendition name.
|
|
||||||
*/
|
|
||||||
boolean isSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String transformName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the maximun size (in bytes) of the source content that can be transformed.
|
|
||||||
* @param sourceMimetype the mimetype of the source content
|
|
||||||
* @param targetMimetype the mimetype of the target
|
|
||||||
* @param actualOptions the actual name value pairs available that could be passed to the Transform Service.
|
|
||||||
* @param transformName (optional) name for the set of options and target mimetype. If supplied is used to cache
|
|
||||||
* results to avoid having to work out if a given transformation is supported a second time.
|
|
||||||
* The sourceMimetype and sourceSizeInBytes may still change. In the case of ACS this is the
|
|
||||||
* rendition name.
|
|
||||||
* @return the maximum size (in bytes) of the source content that can be transformed. If {@code -1} there is no
|
|
||||||
* limit, but if {@code 0} the transform is not supported.
|
|
||||||
*/
|
|
||||||
long getMaxSize(String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String transformName);
|
|
||||||
}
|
|
@@ -1,459 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.alfresco.util.ConfigScheduler;
|
|
||||||
import org.alfresco.util.PropertyCheck;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.quartz.CronExpression;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by clients to work out if a transformation is supported by the Transform Service.
|
|
||||||
*/
|
|
||||||
public abstract class TransformServiceRegistryImpl implements TransformServiceRegistry, InitializingBean
|
|
||||||
{
|
|
||||||
public static class Data
|
|
||||||
{
|
|
||||||
ConcurrentMap<String, ConcurrentMap<String, List<SupportedTransform>>> transformers = new ConcurrentHashMap<>();
|
|
||||||
ConcurrentMap<String, ConcurrentMap<String, List<SupportedTransform>>> cachedSupportedTransformList = new ConcurrentHashMap<>();
|
|
||||||
private int transformerCount = 0;
|
|
||||||
private int transformCount = 0;
|
|
||||||
private int tEngineCount = 0;
|
|
||||||
private int fileCount;
|
|
||||||
boolean firstTime = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return transformerCount == 0 && transformCount == 0 && tEngineCount == 0 && fileCount == 0
|
|
||||||
? ""
|
|
||||||
: "(transformers: "+transformerCount+" transforms: "+transformCount+" t-engines: "+tEngineCount+" files: "+fileCount+")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTEngineCount(int tEngineCount)
|
|
||||||
{
|
|
||||||
this.tEngineCount = tEngineCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileCount(int fileCount)
|
|
||||||
{
|
|
||||||
this.fileCount = fileCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class SupportedTransform
|
|
||||||
{
|
|
||||||
TransformOptionGroup transformOptions;
|
|
||||||
long maxSourceSizeBytes;
|
|
||||||
private String name;
|
|
||||||
private int priority;
|
|
||||||
|
|
||||||
public SupportedTransform(Data data, String name, Set<TransformOption> transformOptions, long maxSourceSizeBytes, int priority)
|
|
||||||
{
|
|
||||||
// Logically the top level TransformOptionGroup is required, so that child options are optional or required
|
|
||||||
// based on their own setting.
|
|
||||||
this.transformOptions = new TransformOptionGroup(true, transformOptions);
|
|
||||||
this.maxSourceSizeBytes = maxSourceSizeBytes;
|
|
||||||
this.name = name;
|
|
||||||
this.priority = priority;
|
|
||||||
data.transformCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean enabled = true;
|
|
||||||
private ObjectMapper jsonObjectMapper;
|
|
||||||
private CronExpression cronExpression;
|
|
||||||
private CronExpression initialAndOnErrorCronExpression;
|
|
||||||
|
|
||||||
private ConfigScheduler<Data> configScheduler = new ConfigScheduler(this)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean readConfig() throws IOException
|
|
||||||
{
|
|
||||||
return TransformServiceRegistryImpl.this.readConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object createData()
|
|
||||||
{
|
|
||||||
return TransformServiceRegistryImpl.this.createData();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void setJsonObjectMapper(ObjectMapper jsonObjectMapper)
|
|
||||||
{
|
|
||||||
this.jsonObjectMapper = jsonObjectMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CronExpression getCronExpression()
|
|
||||||
{
|
|
||||||
return cronExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCronExpression(CronExpression cronExpression)
|
|
||||||
{
|
|
||||||
this.cronExpression = cronExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CronExpression getInitialAndOnErrorCronExpression()
|
|
||||||
{
|
|
||||||
return initialAndOnErrorCronExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialAndOnErrorCronExpression(CronExpression initialAndOnErrorCronExpression)
|
|
||||||
{
|
|
||||||
this.initialAndOnErrorCronExpression = initialAndOnErrorCronExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet() throws Exception
|
|
||||||
{
|
|
||||||
PropertyCheck.mandatory(this, "jsonObjectMapper", jsonObjectMapper);
|
|
||||||
// If we have a cronExpression it indicates that we will schedule reading.
|
|
||||||
if (cronExpression != null)
|
|
||||||
{
|
|
||||||
PropertyCheck.mandatory(this, "initialAndOnErrorCronExpression", initialAndOnErrorCronExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log log = getLog();
|
|
||||||
configScheduler.run(enabled, log, cronExpression, initialAndOnErrorCronExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Data createData()
|
|
||||||
{
|
|
||||||
return new Data();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Data getData()
|
|
||||||
{
|
|
||||||
return configScheduler.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean readConfig() throws IOException;
|
|
||||||
|
|
||||||
public boolean isEnabled()
|
|
||||||
{
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(boolean enabled)
|
|
||||||
{
|
|
||||||
this.enabled = enabled;
|
|
||||||
setFirstTime(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setFirstTime(boolean firstTime)
|
|
||||||
{
|
|
||||||
getData().firstTime = firstTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean getFirstTime()
|
|
||||||
{
|
|
||||||
return getData().firstTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Log getLog();
|
|
||||||
|
|
||||||
public void register(Reader reader, String readFrom) throws IOException
|
|
||||||
{
|
|
||||||
List<InlineTransformer> transformers = jsonObjectMapper.readValue(reader, new TypeReference<List<InlineTransformer>>(){});
|
|
||||||
transformers.forEach(t -> register(t, null, readFrom));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void register(InlineTransformer transformer, String baseUrl, String readFrom)
|
|
||||||
{
|
|
||||||
Data data = getData();
|
|
||||||
data.transformerCount++;
|
|
||||||
transformer.getSupportedSourceAndTargetList().forEach(
|
|
||||||
e -> data.transformers.computeIfAbsent(e.getSourceMediaType(),
|
|
||||||
k -> new ConcurrentHashMap<>()).computeIfAbsent(e.getTargetMediaType(),
|
|
||||||
k -> new ArrayList<>()).add(
|
|
||||||
new SupportedTransform(data, transformer.getTransformerName(),
|
|
||||||
transformer.getTransformOptions(), e.getMaxSourceSizeBytes(), e.getPriority())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String renditionName)
|
|
||||||
{
|
|
||||||
long maxSize = getMaxSize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
|
||||||
return maxSize != 0 && (maxSize == -1L || maxSize >= sourceSizeInBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Works out the name of the transformer (might not map to an actual transformer) that will be used to transform
|
|
||||||
* content of a given source mimetype and size into a target mimetype given a list of actual transform option names
|
|
||||||
* and values (Strings) plus the data contained in the {@Transform} objects registered with this class.
|
|
||||||
* @param sourceMimetype the mimetype of the source content
|
|
||||||
* @param sourceSizeInBytes the size in bytes of the source content. Ignored if negative.
|
|
||||||
* @param targetMimetype the mimetype of the target
|
|
||||||
* @param actualOptions the actual name value pairs available that could be passed to the Transform Service.
|
|
||||||
* @param renditionName (optional) name for the set of options and target mimetype. If supplied is used to cache
|
|
||||||
* results to avoid having to work out if a given transformation is supported a second time.
|
|
||||||
* The sourceMimetype and sourceSizeInBytes may still change. In the case of ACS this is the
|
|
||||||
* rendition name.
|
|
||||||
*/
|
|
||||||
protected String getTransformerName(String sourceMimetype, long sourceSizeInBytes, String targetMimetype, Map<String, String> actualOptions, String renditionName)
|
|
||||||
{
|
|
||||||
List<SupportedTransform> supportedTransforms = getTransformListBySize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
|
||||||
for (SupportedTransform supportedTransform : supportedTransforms)
|
|
||||||
{
|
|
||||||
if (supportedTransform.maxSourceSizeBytes == -1 || supportedTransform.maxSourceSizeBytes >= sourceSizeInBytes)
|
|
||||||
{
|
|
||||||
return supportedTransform.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getMaxSize(String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String renditionName)
|
|
||||||
{
|
|
||||||
List<SupportedTransform> supportedTransforms = getTransformListBySize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
|
||||||
return supportedTransforms.isEmpty() ? 0 : supportedTransforms.get(supportedTransforms.size()-1).maxSourceSizeBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns transformers in increasing supported size order, where lower priority transformers for the same size have
|
|
||||||
// been discarded.
|
|
||||||
private List<SupportedTransform> getTransformListBySize(String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String renditionName)
|
|
||||||
{
|
|
||||||
if (actualOptions == null)
|
|
||||||
{
|
|
||||||
actualOptions = Collections.EMPTY_MAP;
|
|
||||||
}
|
|
||||||
if (renditionName != null && renditionName.trim().isEmpty())
|
|
||||||
{
|
|
||||||
renditionName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data data = getData();
|
|
||||||
List<SupportedTransform> transformListBySize = renditionName == null ? null
|
|
||||||
: data.cachedSupportedTransformList.computeIfAbsent(renditionName, k -> new ConcurrentHashMap<>()).get(sourceMimetype);
|
|
||||||
if (transformListBySize != null)
|
|
||||||
{
|
|
||||||
return transformListBySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the "timeout" property from the actualOptions as it is not used to select a transformer.
|
|
||||||
if (actualOptions.containsKey(TIMEOUT))
|
|
||||||
{
|
|
||||||
actualOptions = new HashMap(actualOptions);
|
|
||||||
actualOptions.remove(TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
transformListBySize = new ArrayList<>();
|
|
||||||
ConcurrentMap<String, List<SupportedTransform>> targetMap = data.transformers.get(sourceMimetype);
|
|
||||||
if (targetMap != null)
|
|
||||||
{
|
|
||||||
List<SupportedTransform> supportedTransformList = targetMap.get(targetMimetype);
|
|
||||||
if (supportedTransformList != null)
|
|
||||||
{
|
|
||||||
for (SupportedTransform supportedTransform : supportedTransformList)
|
|
||||||
{
|
|
||||||
TransformOptionGroup transformOptions = supportedTransform.transformOptions;
|
|
||||||
Map<String, Boolean> possibleTransformOptions = new HashMap<>();
|
|
||||||
addToPossibleTransformOptions(possibleTransformOptions, transformOptions, true, actualOptions);
|
|
||||||
if (isSupported(possibleTransformOptions, actualOptions))
|
|
||||||
{
|
|
||||||
addToSupportedTransformList(transformListBySize, supportedTransform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renditionName != null)
|
|
||||||
{
|
|
||||||
data.cachedSupportedTransformList.get(renditionName).put(sourceMimetype, transformListBySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return transformListBySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add newTransform to the transformListBySize in increasing size order and discards lower priority (numerically
|
|
||||||
// higher) transforms with a smaller or equal size.
|
|
||||||
private void addToSupportedTransformList(List<SupportedTransform> transformListBySize, SupportedTransform newTransform)
|
|
||||||
{
|
|
||||||
for (int i=0; i < transformListBySize.size(); i++)
|
|
||||||
{
|
|
||||||
SupportedTransform existingTransform = transformListBySize.get(i);
|
|
||||||
int added = -1;
|
|
||||||
int compare = compare(newTransform.maxSourceSizeBytes, existingTransform.maxSourceSizeBytes);
|
|
||||||
if (compare < 0)
|
|
||||||
{
|
|
||||||
transformListBySize.add(i, newTransform);
|
|
||||||
added = i;
|
|
||||||
}
|
|
||||||
else if (compare == 0)
|
|
||||||
{
|
|
||||||
if (newTransform.priority < existingTransform.priority)
|
|
||||||
{
|
|
||||||
transformListBySize.set(i, newTransform);
|
|
||||||
added = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (added == i)
|
|
||||||
{
|
|
||||||
for (i--; i >= 0; i--)
|
|
||||||
{
|
|
||||||
existingTransform = transformListBySize.get(i);
|
|
||||||
if (newTransform.priority <= existingTransform.priority)
|
|
||||||
{
|
|
||||||
transformListBySize.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transformListBySize.add(newTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare where -1 is unlimited.
|
|
||||||
private int compare(long a, long b)
|
|
||||||
{
|
|
||||||
return a == -1
|
|
||||||
? b == -1 ? 0 : 1
|
|
||||||
: b == -1 ? -1
|
|
||||||
: a == b ? 0
|
|
||||||
: a > b ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flatten out the transform options by adding them to the supplied possibleTransformOptions.</p>
|
|
||||||
*
|
|
||||||
* If possible discards options in the supplied transformOptionGroup if the group is optional and the actualOptions
|
|
||||||
* don't provide any of the options in the group. Or to put it another way:<p/>
|
|
||||||
*
|
|
||||||
* It adds individual transform options from the transformOptionGroup to possibleTransformOptions if the group is
|
|
||||||
* required or if the actualOptions include individual options from the group. As a result it is possible that none
|
|
||||||
* of the group are added if it is optional. It is also possible to add individual transform options that are
|
|
||||||
* themselves required but not in the actualOptions. In this the isSupported method will return false.
|
|
||||||
* @return true if any options were added. Used by nested call parents to determine if an option was added from a
|
|
||||||
* nested sub group.
|
|
||||||
*/
|
|
||||||
boolean addToPossibleTransformOptions(Map<String, Boolean> possibleTransformOptions,
|
|
||||||
TransformOptionGroup transformOptionGroup,
|
|
||||||
Boolean parentGroupRequired, Map<String, String> actualOptions)
|
|
||||||
{
|
|
||||||
boolean added = false;
|
|
||||||
boolean required = false;
|
|
||||||
|
|
||||||
Set<TransformOption> optionList = transformOptionGroup.getTransformOptions();
|
|
||||||
if (optionList != null && !optionList.isEmpty())
|
|
||||||
{
|
|
||||||
// We need to avoid adding options from a group that is required but its parents are not.
|
|
||||||
boolean transformOptionGroupRequired = transformOptionGroup.isRequired() && parentGroupRequired;
|
|
||||||
|
|
||||||
// Check if the group contains options in actualOptions. This will add any options from sub groups.
|
|
||||||
for (TransformOption transformOption : optionList)
|
|
||||||
{
|
|
||||||
if (transformOption instanceof TransformOptionGroup)
|
|
||||||
{
|
|
||||||
added = addToPossibleTransformOptions(possibleTransformOptions, (TransformOptionGroup) transformOption,
|
|
||||||
transformOptionGroupRequired, actualOptions);
|
|
||||||
required |= added;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String name = ((TransformOptionValue) transformOption).getName();
|
|
||||||
if (actualOptions.containsKey(name))
|
|
||||||
{
|
|
||||||
required = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (required || transformOptionGroupRequired)
|
|
||||||
{
|
|
||||||
for (TransformOption transformOption : optionList)
|
|
||||||
{
|
|
||||||
if (transformOption instanceof TransformOptionValue)
|
|
||||||
{
|
|
||||||
added = true;
|
|
||||||
TransformOptionValue transformOptionValue = (TransformOptionValue) transformOption;
|
|
||||||
String name = transformOptionValue.getName();
|
|
||||||
boolean optionValueRequired = transformOptionValue.isRequired();
|
|
||||||
possibleTransformOptions.put(name, optionValueRequired);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return added;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isSupported(Map<String, Boolean> transformOptions, Map<String, String> actualOptions)
|
|
||||||
{
|
|
||||||
boolean supported = true;
|
|
||||||
|
|
||||||
// Check all required transformOptions are supplied
|
|
||||||
for (Map.Entry<String, Boolean> transformOption : transformOptions.entrySet())
|
|
||||||
{
|
|
||||||
Boolean required = transformOption.getValue();
|
|
||||||
if (required)
|
|
||||||
{
|
|
||||||
String name = transformOption.getKey();
|
|
||||||
if (!actualOptions.containsKey(name))
|
|
||||||
{
|
|
||||||
supported = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (supported)
|
|
||||||
{
|
|
||||||
// Check there are no extra unused actualOptions
|
|
||||||
for (String actualOption : actualOptions.keySet())
|
|
||||||
{
|
|
||||||
if (!transformOptions.containsKey(actualOption))
|
|
||||||
{
|
|
||||||
supported = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return supported;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2019 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco 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.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.client.registry;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformConfig;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOption;
|
||||||
|
import org.alfresco.transform.client.model.config.Transformer;
|
||||||
|
import org.alfresco.util.ConfigFileFinder;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class reads multiple T-Engine config and local files and registers them all with a registry as if they were all
|
||||||
|
* in one file. Transform options are shared between all sources.<p>
|
||||||
|
*
|
||||||
|
* The caller should make calls to {@link #addRemoteConfig(List, String)} and {@link #addLocalConfig(String)} followed
|
||||||
|
* by a call to {@link #register(TransformServiceRegistryImpl)}.
|
||||||
|
*
|
||||||
|
* @author adavis
|
||||||
|
*/
|
||||||
|
public class CombinedConfig
|
||||||
|
{
|
||||||
|
private static final String TRANSFORM_CONFIG = "/transform/config";
|
||||||
|
|
||||||
|
private final Log log;
|
||||||
|
|
||||||
|
static class TransformAndItsOrigin
|
||||||
|
{
|
||||||
|
final Transformer transformer;
|
||||||
|
final String baseUrl;
|
||||||
|
final String readFrom;
|
||||||
|
|
||||||
|
TransformAndItsOrigin(Transformer transformer, String baseUrl, String readFrom)
|
||||||
|
{
|
||||||
|
this.transformer = transformer;
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
this.readFrom = readFrom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Set<TransformOption>> combinedTransformOptions = new HashMap<>();
|
||||||
|
List<TransformAndItsOrigin> combinedTransformers = new ArrayList<>();
|
||||||
|
|
||||||
|
private ObjectMapper jsonObjectMapper = new ObjectMapper();
|
||||||
|
private ConfigFileFinder configFileFinder;
|
||||||
|
private int tEngineCount;
|
||||||
|
|
||||||
|
public CombinedConfig(Log log)
|
||||||
|
{
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
configFileFinder = new ConfigFileFinder(jsonObjectMapper)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void readJson(JsonNode jsonNode, String readFrom, String baseUrl)
|
||||||
|
{
|
||||||
|
TransformConfig transformConfig = jsonObjectMapper.convertValue(jsonNode, TransformConfig.class);
|
||||||
|
transformConfig.getTransformOptions().forEach((key, map) -> combinedTransformOptions.put(key, map));
|
||||||
|
transformConfig.getTransformers().forEach(transformer -> combinedTransformers.add(
|
||||||
|
new TransformAndItsOrigin(transformer, baseUrl, readFrom)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addLocalConfig(String path)
|
||||||
|
{
|
||||||
|
return configFileFinder.readFiles(path, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addRemoteConfig(List<String> urls, String remoteType)
|
||||||
|
{
|
||||||
|
boolean successReadingConfig = true;
|
||||||
|
for (String url : urls)
|
||||||
|
{
|
||||||
|
if (addRemoteConfig(url, remoteType))
|
||||||
|
{
|
||||||
|
tEngineCount++ ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
successReadingConfig = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return successReadingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean addRemoteConfig(String baseUrl, String remoteType)
|
||||||
|
{
|
||||||
|
String url = baseUrl + TRANSFORM_CONFIG;
|
||||||
|
HttpGet httpGet = new HttpGet(url);
|
||||||
|
boolean successReadingConfig = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
try (CloseableHttpClient httpclient = HttpClients.createDefault())
|
||||||
|
{
|
||||||
|
try (CloseableHttpResponse response = execute(httpclient, httpGet))
|
||||||
|
{
|
||||||
|
StatusLine statusLine = response.getStatusLine();
|
||||||
|
if (statusLine == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException(remoteType+" on " + url+" returned no status ");
|
||||||
|
}
|
||||||
|
HttpEntity resEntity = response.getEntity();
|
||||||
|
if (resEntity != null)
|
||||||
|
{
|
||||||
|
int statusCode = statusLine.getStatusCode();
|
||||||
|
if (statusCode == 200)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String content = getContent(resEntity);
|
||||||
|
|
||||||
|
try (StringReader reader = new StringReader(content))
|
||||||
|
{
|
||||||
|
int transformCount = combinedTransformers.size();
|
||||||
|
configFileFinder.readFile(reader, remoteType+" on "+baseUrl, "json", baseUrl, log);
|
||||||
|
if (transformCount == combinedTransformers.size())
|
||||||
|
{
|
||||||
|
successReadingConfig = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityUtils.consume(resEntity);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to read the returned content from "+
|
||||||
|
remoteType+" on " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String message = getErrorMessage(resEntity);
|
||||||
|
throw new AlfrescoRuntimeException(remoteType+" on " + url+" returned a " + statusCode +
|
||||||
|
" status " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException(remoteType+" on " + url+" did not return an entity " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to connect or to read the response from "+remoteType+
|
||||||
|
" on " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException(remoteType+" on " + url+" failed to create an HttpClient", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (AlfrescoRuntimeException e)
|
||||||
|
{
|
||||||
|
log.error(e.getMessage());
|
||||||
|
successReadingConfig = false;
|
||||||
|
}
|
||||||
|
return successReadingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests mock the return values
|
||||||
|
CloseableHttpResponse execute(CloseableHttpClient httpclient, HttpGet httpGet) throws IOException
|
||||||
|
{
|
||||||
|
return httpclient.execute(httpGet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests mock the return values
|
||||||
|
String getContent(HttpEntity resEntity) throws IOException
|
||||||
|
{
|
||||||
|
return EntityUtils.toString(resEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip out just the error message in the response
|
||||||
|
private String getErrorMessage(HttpEntity resEntity) throws IOException
|
||||||
|
{
|
||||||
|
String message = "";
|
||||||
|
String content = getContent(resEntity);
|
||||||
|
int i = content.indexOf("\"message\":\"");
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
int j = content.indexOf("\",\"path\":", i);
|
||||||
|
if (j != -1)
|
||||||
|
{
|
||||||
|
message = content.substring(i+11, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(TransformServiceRegistryImpl registry)
|
||||||
|
{
|
||||||
|
TransformServiceRegistryImpl.Data data = registry.getData();
|
||||||
|
data.setTEngineCount(tEngineCount);
|
||||||
|
data.setFileCount(configFileFinder.getFileCount());
|
||||||
|
|
||||||
|
combinedTransformers.forEach(transformer ->
|
||||||
|
registry.register(transformer.transformer, combinedTransformOptions,
|
||||||
|
transformer.baseUrl, transformer.readFrom));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco 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.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.client.registry;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.alfresco.transform.client.registry.AbstractTransformRegistry;
|
||||||
|
import org.alfresco.transform.client.registry.TransformCache;
|
||||||
|
import org.alfresco.util.ConfigScheduler;
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.quartz.CronExpression;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by clients to work out if a transformation is supported by the Transform Service.
|
||||||
|
*/
|
||||||
|
public abstract class TransformServiceRegistryImpl extends AbstractTransformRegistry implements InitializingBean
|
||||||
|
{
|
||||||
|
public static class Data extends TransformCache
|
||||||
|
{
|
||||||
|
private int tEngineCount = 0;
|
||||||
|
private int fileCount;
|
||||||
|
boolean firstTime = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return transformerCount == 0 && transformCount == 0 && tEngineCount == 0 && fileCount == 0
|
||||||
|
? ""
|
||||||
|
: "(transformers: "+transformerCount+" transforms: "+transformCount+" t-engines: "+tEngineCount+" files: "+fileCount+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTEngineCount(int tEngineCount)
|
||||||
|
{
|
||||||
|
this.tEngineCount = tEngineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileCount(int fileCount)
|
||||||
|
{
|
||||||
|
this.fileCount = fileCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean enabled = true;
|
||||||
|
private ObjectMapper jsonObjectMapper;
|
||||||
|
private CronExpression cronExpression;
|
||||||
|
private CronExpression initialAndOnErrorCronExpression;
|
||||||
|
|
||||||
|
private ConfigScheduler<Data> configScheduler = new ConfigScheduler<>(this)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean readConfig() throws IOException
|
||||||
|
{
|
||||||
|
return TransformServiceRegistryImpl.this.readConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data createData()
|
||||||
|
{
|
||||||
|
return TransformServiceRegistryImpl.this.createData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void setJsonObjectMapper(ObjectMapper jsonObjectMapper)
|
||||||
|
{
|
||||||
|
this.jsonObjectMapper = jsonObjectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CronExpression getCronExpression()
|
||||||
|
{
|
||||||
|
return cronExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCronExpression(CronExpression cronExpression)
|
||||||
|
{
|
||||||
|
this.cronExpression = cronExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CronExpression getInitialAndOnErrorCronExpression()
|
||||||
|
{
|
||||||
|
return initialAndOnErrorCronExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInitialAndOnErrorCronExpression(CronExpression initialAndOnErrorCronExpression)
|
||||||
|
{
|
||||||
|
this.initialAndOnErrorCronExpression = initialAndOnErrorCronExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
PropertyCheck.mandatory(this, "jsonObjectMapper", jsonObjectMapper);
|
||||||
|
// If we have a cronExpression it indicates that we will schedule reading.
|
||||||
|
if (cronExpression != null)
|
||||||
|
{
|
||||||
|
PropertyCheck.mandatory(this, "initialAndOnErrorCronExpression", initialAndOnErrorCronExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log log = getLog();
|
||||||
|
configScheduler.run(enabled, log, cronExpression, initialAndOnErrorCronExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data createData()
|
||||||
|
{
|
||||||
|
return new Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data getData()
|
||||||
|
{
|
||||||
|
return configScheduler.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean readConfig() throws IOException;
|
||||||
|
|
||||||
|
public boolean isEnabled()
|
||||||
|
{
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled)
|
||||||
|
{
|
||||||
|
this.enabled = enabled;
|
||||||
|
setFirstTime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setFirstTime(boolean firstTime)
|
||||||
|
{
|
||||||
|
getData().firstTime = firstTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean getFirstTime()
|
||||||
|
{
|
||||||
|
return getData().firstTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Log getLog();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void logError(String msg)
|
||||||
|
{
|
||||||
|
getLog().error(msg);
|
||||||
|
}
|
||||||
|
}
|
@@ -201,7 +201,7 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.util.resource.HierarchicalResourceLoaderTest.class,
|
org.alfresco.util.resource.HierarchicalResourceLoaderTest.class,
|
||||||
org.alfresco.repo.events.ClientUtilTest.class,
|
org.alfresco.repo.events.ClientUtilTest.class,
|
||||||
org.alfresco.repo.rendition2.RenditionService2Test.class,
|
org.alfresco.repo.rendition2.RenditionService2Test.class,
|
||||||
org.alfresco.transform.client.model.config.TransformServiceRegistryConfigTest.class
|
org.alfresco.transform.client.registry.TransformServiceRegistryConfigTest.class
|
||||||
})
|
})
|
||||||
public class AllUnitTestsSuite
|
public class AllUnitTestsSuite
|
||||||
{
|
{
|
||||||
|
@@ -49,7 +49,7 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.repo.rawevents.TransactionAwareEventProducerTest.class,
|
org.alfresco.repo.rawevents.TransactionAwareEventProducerTest.class,
|
||||||
|
|
||||||
// Requires running transformers
|
// Requires running transformers
|
||||||
org.alfresco.transform.client.model.config.LocalTransformServiceRegistryConfigTest.class,
|
org.alfresco.transform.client.registry.LocalTransformServiceRegistryConfigTest.class,
|
||||||
org.alfresco.repo.rendition2.RenditionService2IntegrationTest.class,
|
org.alfresco.repo.rendition2.RenditionService2IntegrationTest.class,
|
||||||
org.alfresco.repo.rendition2.LocalTransformServiceRegistryIntegrationTest.class,
|
org.alfresco.repo.rendition2.LocalTransformServiceRegistryIntegrationTest.class,
|
||||||
org.alfresco.repo.rendition2.LocalTransformClientIntegrationTest.class,
|
org.alfresco.repo.rendition2.LocalTransformClientIntegrationTest.class,
|
||||||
|
@@ -45,7 +45,7 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
import org.alfresco.util.BaseSpringTest;
|
import org.alfresco.util.BaseSpringTest;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.PropertyMap;
|
import org.alfresco.util.PropertyMap;
|
||||||
|
@@ -59,6 +59,6 @@ public class LocalRenditionTest extends AbstractRenditionTest
|
|||||||
@Test
|
@Test
|
||||||
public void testAllSourceExtensions() throws Exception
|
public void testAllSourceExtensions() throws Exception
|
||||||
{
|
{
|
||||||
internalTestAllSourceExtensions(57, 0);
|
internalTestAllSourceExtensions(81, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
package org.alfresco.repo.rendition2;
|
package org.alfresco.repo.rendition2;
|
||||||
|
|
||||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
import org.alfresco.transform.client.registry.TransformServiceRegistry;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistryImpl;
|
import org.alfresco.transform.client.registry.TransformServiceRegistryImpl;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@@ -39,7 +39,7 @@ import org.alfresco.service.cmr.repository.NodeService;
|
|||||||
import org.alfresco.service.cmr.rule.RuleService;
|
import org.alfresco.service.cmr.rule.RuleService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.transform.client.model.config.TransformServiceRegistryImpl;
|
import org.alfresco.transform.client.registry.TransformServiceRegistryImpl;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class that builds a {@link InlineTransformer} given the source and target types and a pipeline of Transformers
|
|
||||||
* for creating intermediary content.
|
|
||||||
*/
|
|
||||||
public class TransformBuilder
|
|
||||||
{
|
|
||||||
public InlineTransformer buildPipeLine(String name, Set<SupportedSourceAndTarget> sourceAndTargetList,
|
|
||||||
List<ChildTransformer> transformerList)
|
|
||||||
{
|
|
||||||
Set<TransformOption> options = new HashSet<>(transformerList.size());
|
|
||||||
transformerList.forEach(t ->
|
|
||||||
{
|
|
||||||
// Avoid creating an enpty TransformOptionGroup if the transformer has no options.
|
|
||||||
// Works with an empty TransformOptionGroup but adds to the complexity.
|
|
||||||
if (t.getTransformer().getTransformOptions() != null)
|
|
||||||
{
|
|
||||||
options.add(new TransformOptionGroup(t.isRequired(), t.getTransformer().getTransformOptions()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return new InlineTransformer(name, options, sourceAndTargetList);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,896 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco 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.
|
|
||||||
*
|
|
||||||
* Alfresco 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.client.model.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.apache.log4j.Level;
|
|
||||||
import org.apache.log4j.LogManager;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.quartz.CronExpression;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the config received from the Transform Service about what it supports.
|
|
||||||
*/
|
|
||||||
public class TransformServiceRegistryConfigTest
|
|
||||||
{
|
|
||||||
private static Log log = LogFactory.getLog(TransformServiceRegistryConfigTest.class);
|
|
||||||
|
|
||||||
public static final String GIF = "image/gif";
|
|
||||||
public static final String JPEG = "image/jpeg";
|
|
||||||
public static final String PNG = "image/png";
|
|
||||||
public static final String TIFF = "image/tiff";
|
|
||||||
public static final String PDF = "application/pdf";
|
|
||||||
public static final String DOC = "application/msword";
|
|
||||||
public static final String XLS = "application/vnd.ms-excel";
|
|
||||||
public static final String PPT = "application/vnd.ms-powerpoint";
|
|
||||||
public static final String MSG = "application/vnd.ms-outlook";
|
|
||||||
public static final String TXT = "text/plain";
|
|
||||||
|
|
||||||
private static final String TRANSFORM_SERVICE_CONFIG = "alfresco/transform-service-config-test.json";
|
|
||||||
private static final String TRANSFORM_SERVICE_CONFIG_PIPELINE = "alfresco/transform-service-config-pipeline-test.json";
|
|
||||||
|
|
||||||
public static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper();
|
|
||||||
|
|
||||||
private TransformServiceRegistryImpl registry;
|
|
||||||
protected TransformBuilder builder;
|
|
||||||
protected InlineTransformer transformer;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception
|
|
||||||
{
|
|
||||||
registry = buildTransformServiceRegistryImpl();
|
|
||||||
builder = new TransformBuilder();
|
|
||||||
LogManager.getLogger(TransformServiceRegistryConfigTest.class).setLevel(Level.DEBUG);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TransformServiceRegistryImpl buildTransformServiceRegistryImpl() throws Exception
|
|
||||||
{
|
|
||||||
TransformServiceRegistryImpl registry = new TransformServiceRegistryImpl()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean readConfig() throws IOException
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Log getLog()
|
|
||||||
{
|
|
||||||
return log;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
registry.setJsonObjectMapper(JSON_OBJECT_MAPPER);
|
|
||||||
registry.setCronExpression(null); // just read once
|
|
||||||
registry.afterPropertiesSet();
|
|
||||||
return registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown()
|
|
||||||
{
|
|
||||||
// shut down
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getTransformServiceConfig()
|
|
||||||
{
|
|
||||||
return TRANSFORM_SERVICE_CONFIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getTransformServiceConfigPipeline()
|
|
||||||
{
|
|
||||||
return TRANSFORM_SERVICE_CONFIG_PIPELINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertAddToPossibleOptions(TransformOptionGroup transformOptionGroup, String actualOptionNames, String expectedNames, String expectedRequired)
|
|
||||||
{
|
|
||||||
Map<String, String> actualOptions = buildActualOptions(actualOptionNames);
|
|
||||||
Set<String> expectedNameSet = expectedNames == null || expectedNames.isEmpty() ? Collections.EMPTY_SET : new HashSet(Arrays.asList(expectedNames.split(", ")));
|
|
||||||
Set<String> expectedRequiredSet = expectedRequired == null || expectedRequired.isEmpty() ? Collections.EMPTY_SET : new HashSet(Arrays.asList(expectedRequired.split(", ")));
|
|
||||||
|
|
||||||
Map<String, Boolean> possibleTransformOptions = new HashMap<>();
|
|
||||||
|
|
||||||
registry.addToPossibleTransformOptions(possibleTransformOptions, transformOptionGroup, true, actualOptions);
|
|
||||||
|
|
||||||
assertEquals("The expected options don't match", expectedNameSet, possibleTransformOptions.keySet());
|
|
||||||
for (String name: possibleTransformOptions.keySet())
|
|
||||||
{
|
|
||||||
Boolean required = possibleTransformOptions.get(name);
|
|
||||||
if (required)
|
|
||||||
{
|
|
||||||
assertTrue(name+" should be REQUIRED", expectedRequiredSet.contains(name));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assertFalse(name+" should be OPTIONAL", expectedRequiredSet.contains(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transformOptionNames are upper case if required.
|
|
||||||
private void assertIsSupported(String actualOptionNames, String transformOptionNames, String unsupportedMsg)
|
|
||||||
{
|
|
||||||
Map<String, String> actualOptions = buildActualOptions(actualOptionNames);
|
|
||||||
|
|
||||||
Map<String, Boolean> transformOptions = new HashMap<>();
|
|
||||||
Set<String> transformOptionNameSet = transformOptionNames == null || transformOptionNames.isEmpty() ? Collections.EMPTY_SET : new HashSet(Arrays.asList(transformOptionNames.split(", ")));
|
|
||||||
for (String name : transformOptionNameSet)
|
|
||||||
{
|
|
||||||
Boolean required = name.toUpperCase().equals(name);
|
|
||||||
transformOptions.put(name, required);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean supported = registry.isSupported(transformOptions, actualOptions);
|
|
||||||
if (unsupportedMsg == null || unsupportedMsg.isEmpty())
|
|
||||||
{
|
|
||||||
assertTrue("Expected these options to be SUPPORTED", supported);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assertFalse("Expected these options NOT to be supported, because "+unsupportedMsg, supported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTransformOptions(Set<TransformOption> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
transformer = new InlineTransformer("name",
|
|
||||||
transformOptions,
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, TXT, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, TXT, 1024000)));
|
|
||||||
|
|
||||||
registry = buildTransformServiceRegistryImpl();
|
|
||||||
registry.register(transformer, getBaseUrl(transformer), getClass().getName());
|
|
||||||
|
|
||||||
assertTrue(registry.isSupported(XLS, 1024, TXT, Collections.emptyMap(), null));
|
|
||||||
assertTrue(registry.isSupported(XLS, 1024000, TXT, null, null));
|
|
||||||
assertFalse(registry.isSupported(XLS, 1024001, TXT, Collections.emptyMap(), null));
|
|
||||||
assertTrue(registry.isSupported(DOC, 1024001, TXT, null, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getBaseUrl(InlineTransformer transformer)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTransformerName(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String expectedTransformerName,
|
|
||||||
InlineTransformer... transformers) throws Exception
|
|
||||||
{
|
|
||||||
buildAndPopulateRegistry(transformers);
|
|
||||||
String transformerName = registry.getTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, null);
|
|
||||||
assertEquals(sourceMimetype+" to "+targetMimetype+" should have returned "+expectedTransformerName, expectedTransformerName, transformerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String unsupportedMsg) throws Exception
|
|
||||||
{
|
|
||||||
assertSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, unsupportedMsg, transformer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String unsupportedMsg,
|
|
||||||
InlineTransformer... transformers) throws Exception
|
|
||||||
{
|
|
||||||
buildAndPopulateRegistry(transformers);
|
|
||||||
assertSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, null, unsupportedMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildAndPopulateRegistry(InlineTransformer[] transformers) throws Exception
|
|
||||||
{
|
|
||||||
registry = buildTransformServiceRegistryImpl();
|
|
||||||
for (InlineTransformer transformer : transformers)
|
|
||||||
{
|
|
||||||
registry.register(transformer, getBaseUrl(transformer), getClass().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
|
||||||
Map<String, String> actualOptions, String renditionName,
|
|
||||||
String unsupportedMsg)
|
|
||||||
{
|
|
||||||
boolean supported = registry.isSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, renditionName);
|
|
||||||
if (unsupportedMsg == null || unsupportedMsg.isEmpty())
|
|
||||||
{
|
|
||||||
assertTrue(sourceMimetype+" to "+targetMimetype+" should be SUPPORTED", supported);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assertFalse(sourceMimetype+" to "+targetMimetype+" should NOT be supported", supported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> buildActualOptions(String actualOptionNames)
|
|
||||||
{
|
|
||||||
Map<String, String> actualOptions = new HashMap<>();
|
|
||||||
Set<String> actualOptionNamesSet = actualOptionNames == null || actualOptionNames.isEmpty() ? Collections.EMPTY_SET : new HashSet(Arrays.asList(actualOptionNames.split(", ")));
|
|
||||||
for (String name : actualOptionNamesSet)
|
|
||||||
{
|
|
||||||
actualOptions.put(name, "value for " + name);
|
|
||||||
}
|
|
||||||
return actualOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void register(String path) throws IOException
|
|
||||||
{
|
|
||||||
CombinedConfig combinedConfig = new CombinedConfig(log);
|
|
||||||
combinedConfig.addLocalConfig(path);
|
|
||||||
combinedConfig.register(registry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadWriteJson() throws IOException
|
|
||||||
{
|
|
||||||
InlineTransformer libreoffice = new InlineTransformer("libreoffice",
|
|
||||||
null, // there are no options
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, PDF, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, PDF, 1024000),
|
|
||||||
new SupportedSourceAndTarget(PPT, PDF, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, PDF, -1)));
|
|
||||||
|
|
||||||
InlineTransformer pdfrenderer = new InlineTransformer("pdfrenderer",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "page"),
|
|
||||||
new TransformOptionValue(false, "width"),
|
|
||||||
new TransformOptionValue(false, "height"),
|
|
||||||
new TransformOptionValue(false, "allowPdfEnlargement"),
|
|
||||||
new TransformOptionValue(false, "maintainPdfAspectRatio")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(PDF, PNG, -1)));
|
|
||||||
|
|
||||||
InlineTransformer tika = new InlineTransformer("tika",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "transform"),
|
|
||||||
new TransformOptionValue(false, "includeContents"),
|
|
||||||
new TransformOptionValue(false, "notExtractBookmarksText"),
|
|
||||||
new TransformOptionValue(false, "targetMimetype"),
|
|
||||||
new TransformOptionValue(false, "targetEncoding")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(PDF, TXT, -1),
|
|
||||||
new SupportedSourceAndTarget(DOC, TXT, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, TXT, 1024000),
|
|
||||||
new SupportedSourceAndTarget(PPT, TXT, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, TXT, -1)));
|
|
||||||
|
|
||||||
InlineTransformer imagemagick = new InlineTransformer("imagemagick",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "alphaRemove"),
|
|
||||||
new TransformOptionValue(false, "autoOrient"),
|
|
||||||
new TransformOptionGroup(false, Set.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, Set.of(
|
|
||||||
new TransformOptionValue(false, "thumbnail"),
|
|
||||||
new TransformOptionValue(false, "resizeHeight"),
|
|
||||||
new TransformOptionValue(false, "resizeWidth"),
|
|
||||||
new TransformOptionValue(false, "resizePercentage"),
|
|
||||||
new TransformOptionValue(false, "maintainAspectRatio")))),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(GIF, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(GIF, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(GIF, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(GIF, TIFF, -1),
|
|
||||||
|
|
||||||
new SupportedSourceAndTarget(JPEG, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(JPEG, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(JPEG, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(JPEG, TIFF, -1),
|
|
||||||
|
|
||||||
new SupportedSourceAndTarget(PNG, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(PNG, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(PNG, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(PNG, TIFF, -1),
|
|
||||||
|
|
||||||
new SupportedSourceAndTarget(TIFF, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(TIFF, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(TIFF, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(TIFF, TIFF, -1)));
|
|
||||||
|
|
||||||
InlineTransformer officeToImage = builder.buildPipeLine("transformer1",
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(DOC, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(DOC, TIFF, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(XLS, TIFF, -1),
|
|
||||||
new SupportedSourceAndTarget(PPT, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(PPT, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(PPT, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(PPT, TIFF, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, PNG, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, TIFF, -1)),
|
|
||||||
Arrays.asList(
|
|
||||||
new ChildTransformer(false, libreoffice), // to pdf
|
|
||||||
new ChildTransformer(false, pdfrenderer), // to png
|
|
||||||
new ChildTransformer(true, imagemagick))); // to other image formats
|
|
||||||
|
|
||||||
List<InlineTransformer> transformers1 = Arrays.asList(libreoffice, tika, pdfrenderer, imagemagick, officeToImage);
|
|
||||||
|
|
||||||
File tempFile = File.createTempFile("test", ".json");
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
objectMapper.writerWithDefaultPrettyPrinter().writeValue(new FileWriter(tempFile), transformers1);
|
|
||||||
|
|
||||||
try (Reader reader = new BufferedReader(new FileReader(tempFile)))
|
|
||||||
{
|
|
||||||
registry.register(reader, getClass().getName());
|
|
||||||
// Check the count of transforms supported
|
|
||||||
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
|
||||||
42, countSupportedTransforms(true));
|
|
||||||
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
|
||||||
"There may be multiple transformers for the same combination. Config change?",
|
|
||||||
42, countSupportedTransforms(false));
|
|
||||||
|
|
||||||
// Check a supported transform for each transformer.
|
|
||||||
assertSupported(DOC, 1234, PDF, null, null, ""); // libreoffice
|
|
||||||
assertSupported(DOC, 1234, PDF, null, null, ""); // libreoffice
|
|
||||||
assertSupported(PDF, 1234, PNG, null, null, ""); // pdfrenderer
|
|
||||||
assertSupported(JPEG,1234, GIF, null, null, ""); // imagemagick
|
|
||||||
assertSupported(MSG, 1234, TXT, null, null, ""); // tika
|
|
||||||
assertSupported(MSG, 1234, GIF, null, null, ""); // transformer1 (officeToImageViaPdf)
|
|
||||||
assertSupported(DOC, 1234, PNG, null, null, ""); // transformer1 (officeToImageViaPdf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJsonConfig() throws IOException
|
|
||||||
{
|
|
||||||
register(getTransformServiceConfig());
|
|
||||||
|
|
||||||
// Check the count of transforms supported
|
|
||||||
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
|
||||||
60, countSupportedTransforms(true));
|
|
||||||
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
|
||||||
"There may be multiple transformers for the same combination. Config change?",
|
|
||||||
60, countSupportedTransforms(false));
|
|
||||||
|
|
||||||
// Check a supported transform for each transformer.
|
|
||||||
assertSupported(DOC, 1234, PDF, null, null, ""); // libreoffice
|
|
||||||
assertSupported(DOC, 1234, PDF, null, null, ""); // libreoffice
|
|
||||||
assertSupported(PDF, 1234, PNG, null, null, ""); // pdfrenderer
|
|
||||||
assertSupported(JPEG,1234, GIF, null, null, ""); // imagemagick
|
|
||||||
assertSupported(MSG, 1234, TXT, null, null, ""); // tika
|
|
||||||
assertSupported(MSG, 1234, GIF, null, null, ""); // officeToImageViaPdf
|
|
||||||
|
|
||||||
Map<String, String> invalidPdfOptions = new HashMap<>();
|
|
||||||
invalidPdfOptions.put("allowEnlargement", "false");
|
|
||||||
assertSupported(DOC, 1234, PDF, invalidPdfOptions, null, "Invalid as there is a extra option");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJsonPipeline() throws IOException
|
|
||||||
{
|
|
||||||
register(getTransformServiceConfigPipeline());
|
|
||||||
|
|
||||||
// Check the count of transforms supported
|
|
||||||
int expectedTransforms = getExpectedTransformsForTestJsonPipeline();
|
|
||||||
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
|
||||||
expectedTransforms, countSupportedTransforms(true));
|
|
||||||
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
|
||||||
"There may be multiple transformers for the same combination. Config change?",
|
|
||||||
expectedTransforms, countSupportedTransforms(false));
|
|
||||||
|
|
||||||
ConcurrentMap<String, List<TransformServiceRegistryImpl.SupportedTransform>> transformer =
|
|
||||||
registry.getData().transformers.get("officeToImageViaPdf");
|
|
||||||
|
|
||||||
// Check required and optional default correctly
|
|
||||||
ConcurrentMap<String, List<TransformServiceRegistryImpl.SupportedTransform>> transformsToWord =
|
|
||||||
registry.getData().transformers.get(DOC);
|
|
||||||
List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms = transformsToWord.get(GIF);
|
|
||||||
TransformServiceRegistryImpl.SupportedTransform supportedTransform = supportedTransforms.get(0);
|
|
||||||
|
|
||||||
Set<TransformOption> transformOptionsSet = supportedTransform.transformOptions.getTransformOptions();
|
|
||||||
System.out.println("Nothing");
|
|
||||||
|
|
||||||
Iterator<TransformOption> iterator = transformOptionsSet.iterator();
|
|
||||||
assertTrue("Expected transform values", iterator.hasNext());
|
|
||||||
// Because Set is unordered we don't know which TransformOptionGroup we retrieve
|
|
||||||
TransformOptionGroup transformOptions1 = (TransformOptionGroup)iterator.next();
|
|
||||||
|
|
||||||
assertTrue("Expected transform values", iterator.hasNext());
|
|
||||||
TransformOptionGroup transformOptions2 = (TransformOptionGroup)iterator.next();
|
|
||||||
|
|
||||||
TransformOptionGroup imagemagick;
|
|
||||||
TransformOptionGroup pdf;
|
|
||||||
|
|
||||||
if(containsTransformOptionValueName(transformOptions1, "alphaRemove"))
|
|
||||||
{
|
|
||||||
imagemagick = transformOptions1;
|
|
||||||
pdf = transformOptions2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
imagemagick = transformOptions2;
|
|
||||||
pdf = transformOptions1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransformOptionValue alphaRemove = (TransformOptionValue)retrieveTransformOptionByPropertyName(imagemagick, "alphaRemove", "TransformOptionValue");
|
|
||||||
TransformOptionGroup crop = (TransformOptionGroup)retrieveTransformOptionByPropertyName(imagemagick, "crop", "TransformOptionGroup");
|
|
||||||
TransformOptionValue cropGravity = (TransformOptionValue)retrieveTransformOptionByPropertyName(crop, "cropGravity", "TransformOptionValue");
|
|
||||||
TransformOptionValue cropWidth = (TransformOptionValue)retrieveTransformOptionByPropertyName(crop, "cropWidth", "TransformOptionValue");
|
|
||||||
|
|
||||||
assertTrue("The holding group should be required", supportedTransform.transformOptions.isRequired());
|
|
||||||
assertFalse("imagemagick should be optional as it is not set", imagemagick.isRequired());
|
|
||||||
assertFalse("pdf should be optional as required is not set", pdf.isRequired());
|
|
||||||
assertEquals("alphaRemove", alphaRemove.getName());
|
|
||||||
assertEquals("cropGravity", cropGravity.getName());
|
|
||||||
assertEquals("cropWidth", cropWidth.getName());
|
|
||||||
assertFalse("alphaRemove should be optional as required is not set", alphaRemove.isRequired());
|
|
||||||
assertFalse("crop should be optional as required is not set", crop.isRequired());
|
|
||||||
assertTrue("cropGravity should be required as it is set", cropGravity.isRequired());
|
|
||||||
assertFalse("cropWidth should be optional as required is not set", cropWidth.isRequired());
|
|
||||||
|
|
||||||
// Check a supported transform for each transformer.
|
|
||||||
assertSupported(DOC,1234, GIF, null, null, "");
|
|
||||||
assertSupported(DOC,1234, PNG, null, null, "");
|
|
||||||
assertSupported(DOC,1234, JPEG, null, null, "");
|
|
||||||
assertSupported(DOC,1234, TIFF, null, null, "");
|
|
||||||
|
|
||||||
Map<String, String> actualOptions = new HashMap<>();
|
|
||||||
actualOptions.put("thumbnail", "true");
|
|
||||||
actualOptions.put("resizeWidth", "100");
|
|
||||||
actualOptions.put("resizeHeight", "100");
|
|
||||||
actualOptions.put("allowEnlargement", "false");
|
|
||||||
actualOptions.put("maintainAspectRatio", "true");
|
|
||||||
assertSupported(DOC,1234, PNG, actualOptions, null, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransformOption retrieveTransformOptionByPropertyName (TransformOptionGroup transformOptionGroup, String propertyName, String propertyType)
|
|
||||||
{
|
|
||||||
Iterator<TransformOption> iterator = transformOptionGroup.getTransformOptions().iterator();
|
|
||||||
|
|
||||||
List<TransformOption> transformOptionsList = new ArrayList<>();
|
|
||||||
while(iterator.hasNext())
|
|
||||||
{
|
|
||||||
transformOptionsList.add(iterator.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TransformOption t : transformOptionsList)
|
|
||||||
{
|
|
||||||
if (t instanceof TransformOptionValue)
|
|
||||||
{
|
|
||||||
TransformOptionValue value = (TransformOptionValue) t;
|
|
||||||
if (propertyType.equalsIgnoreCase("TransformOptionValue"))
|
|
||||||
{
|
|
||||||
if (value.getName().equalsIgnoreCase(propertyName))
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (value.getName().contains(propertyName))
|
|
||||||
return transformOptionGroup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TransformOption result = retrieveTransformOptionByPropertyName((TransformOptionGroup)t, propertyName, propertyType);
|
|
||||||
if (result != null)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containsTransformOptionValueName (TransformOptionGroup transformOptionGroup, String propertyName)
|
|
||||||
{
|
|
||||||
if (retrieveTransformOptionByPropertyName(transformOptionGroup, propertyName, "TransformOptionValue") != null)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containsTransformOptionGroupeName (TransformOptionGroup transformOptionGroup, String propertyName)
|
|
||||||
{
|
|
||||||
if (retrieveTransformOptionByPropertyName(transformOptionGroup, propertyName, "TransformOptionGroup") != null)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getExpectedTransformsForTestJsonPipeline()
|
|
||||||
{
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int countSupportedTransforms(boolean unique)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
int uniqueCount = 0;
|
|
||||||
for (ConcurrentMap<String, List<TransformServiceRegistryImpl.SupportedTransform>> targetMap : registry.getData().transformers.values())
|
|
||||||
{
|
|
||||||
for (List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms : targetMap.values())
|
|
||||||
{
|
|
||||||
uniqueCount++;
|
|
||||||
count += supportedTransforms.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return unique ? uniqueCount : count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOptionalGroups()
|
|
||||||
{
|
|
||||||
TransformOptionGroup transformOptionGroup =
|
|
||||||
new TransformOptionGroup(true, Set.of(
|
|
||||||
new TransformOptionValue(false, "1"),
|
|
||||||
new TransformOptionValue(true, "2"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "3.1"),
|
|
||||||
new TransformOptionValue(false, "3.2"),
|
|
||||||
new TransformOptionValue(false, "3.3"))),
|
|
||||||
new TransformOptionGroup(false, Set.of( // OPTIONAL
|
|
||||||
new TransformOptionValue(false, "4.1"),
|
|
||||||
new TransformOptionValue(true, "4.2"),
|
|
||||||
new TransformOptionValue(false, "4.3")))));
|
|
||||||
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "", "1, 2", "2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1", "1, 2", "2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2", "1, 2", "2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 3.2", "1, 2, 3.1, 3.2, 3.3", "2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 4.1", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 4.2", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRequiredGroup()
|
|
||||||
{
|
|
||||||
TransformOptionGroup transformOptionGroup =
|
|
||||||
new TransformOptionGroup(true, Set.of(
|
|
||||||
new TransformOptionValue(false, "1"),
|
|
||||||
new TransformOptionValue(true, "2"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "3.1"),
|
|
||||||
new TransformOptionValue(false, "3.2"),
|
|
||||||
new TransformOptionValue(false, "3.3"))),
|
|
||||||
new TransformOptionGroup(true, Set.of( // REQUIRED
|
|
||||||
new TransformOptionValue(false, "4.1"),
|
|
||||||
new TransformOptionValue(true, "4.2"),
|
|
||||||
new TransformOptionValue(false, "4.3")))));
|
|
||||||
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 3.2", "1, 2, 3.1, 3.2, 3.3, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 4.1", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 4.2", "1, 2, 4.1, 4.2, 4.3", "2, 4.2");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNesstedGrpups()
|
|
||||||
{
|
|
||||||
TransformOptionGroup transformOptionGroup =
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "1"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "1.2"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "1.2.3"))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "2"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "2.2"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "2.2.1.2"))))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(true, "3"), // REQUIRED
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "3.1.1.2"))))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "4"),
|
|
||||||
new TransformOptionGroup(true, Set.of( // REQUIRED
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "4.1.1.2"))))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "5"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(true, Set.of( // REQUIRED
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "5.1.1.2"))))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "6"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(true, Set.of( // REQUIRED
|
|
||||||
new TransformOptionValue(false, "6.1.1.2"))))))))),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(false, "7"),
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionGroup(false, Set.of(
|
|
||||||
new TransformOptionValue(true, "7.1.1.2"))))))))) // REQUIRED
|
|
||||||
));
|
|
||||||
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "", "", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1", "1", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 7", "1, 7", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 7.1.1.2", "1, 7, 7.1.1.2", "7.1.1.2");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 6", "1, 6", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 6.1.1.2", "1, 6, 6.1.1.2", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 5", "1, 5", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 5.1.1.2", "1, 5, 5.1.1.2", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 4", "1, 4", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 4.1.1.2", "1, 4, 4.1.1.2", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 3", "1, 3", "3");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "1, 3.1.1.2", "1, 3, 3.1.1.2", "3");
|
|
||||||
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2", "2", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "2, 2.2", "2, 2.2", "");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "3", "3", "3");
|
|
||||||
assertAddToPossibleOptions(transformOptionGroup, "3.1.1.2", "3, 3.1.1.2", "3");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSupportedOptions()
|
|
||||||
{
|
|
||||||
assertIsSupported("a", "a, B, c", "required option B is missing");
|
|
||||||
assertIsSupported("", "a, B, c", "required option B is missing");
|
|
||||||
assertIsSupported("B", "a, B, c", null);
|
|
||||||
assertIsSupported("B, c", "a, B, c", null);
|
|
||||||
assertIsSupported("B, a, c", "a, B, c", null);
|
|
||||||
|
|
||||||
assertIsSupported("B, d", "a, B, c", "there is an extra option d");
|
|
||||||
assertIsSupported("B, c, d", "a, B, c", "there is an extra option d");
|
|
||||||
assertIsSupported("d", "a, B, c", "required option B is missing and there is an extra option d");
|
|
||||||
|
|
||||||
assertIsSupported("a", "a, b, c", null);
|
|
||||||
assertIsSupported("", "a, b, c", null);
|
|
||||||
assertIsSupported("a, b, c", "a, b, c", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoActualOptions() throws Exception
|
|
||||||
{
|
|
||||||
assertTransformOptions(Set.of(
|
|
||||||
new TransformOptionValue(false, "option1"),
|
|
||||||
new TransformOptionValue(false, "option2")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoTrasformOptions() throws Exception
|
|
||||||
{
|
|
||||||
assertTransformOptions(Collections.emptySet());
|
|
||||||
assertTransformOptions(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSupported() throws Exception
|
|
||||||
{
|
|
||||||
transformer = new InlineTransformer("name",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "page"),
|
|
||||||
new TransformOptionValue(false, "width"),
|
|
||||||
new TransformOptionValue(false, "height")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, 102400),
|
|
||||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, GIF, -1)));
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, null, null);
|
|
||||||
assertSupported(DOC, 102400, GIF, null, null);
|
|
||||||
assertSupported(DOC, 102401, GIF, null, "source is too large");
|
|
||||||
assertSupported(DOC, 1024, JPEG, null, null);
|
|
||||||
assertSupported(GIF, 1024, DOC, null, GIF+" is not a source of this transformer");
|
|
||||||
assertSupported(MSG, 1024, GIF, null, null);
|
|
||||||
assertSupported(MSG, 1024, JPEG, null, MSG+" to "+JPEG+" is not supported by this transformer");
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width"), null);
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width, startPage"), "startPage is not an option");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCache()
|
|
||||||
{
|
|
||||||
// Note: transformNames are an alias for a set of actualOptions and the target mimetpe. The source mimetype may change.
|
|
||||||
transformer = new InlineTransformer("name",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "page"),
|
|
||||||
new TransformOptionValue(false, "width"),
|
|
||||||
new TransformOptionValue(false, "height")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, 102400),
|
|
||||||
new SupportedSourceAndTarget(MSG, GIF, -1)));
|
|
||||||
|
|
||||||
registry.register(transformer, getBaseUrl(transformer), getClass().getName());
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, null, "doclib", "");
|
|
||||||
assertSupported(MSG, 1024, GIF, null, "doclib", "");
|
|
||||||
|
|
||||||
assertEquals(102400L, registry.getMaxSize(DOC, GIF, null, "doclib"));
|
|
||||||
assertEquals(-1L, registry.getMaxSize(MSG, GIF, null, "doclib"));
|
|
||||||
|
|
||||||
// Change the cached value and try and check we are now using the cached value.
|
|
||||||
List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms = registry.getData().cachedSupportedTransformList.get("doclib").get(DOC);
|
|
||||||
supportedTransforms.get(0).maxSourceSizeBytes = 1234L;
|
|
||||||
assertEquals(1234L, registry.getMaxSize(DOC, GIF, null, "doclib"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetTransformerName() throws Exception
|
|
||||||
{
|
|
||||||
InlineTransformer t1 = new InlineTransformer("transformer1", null,
|
|
||||||
Set.of(new SupportedSourceAndTarget(MSG, GIF, 100, 50)));
|
|
||||||
InlineTransformer t2 = new InlineTransformer("transformer2", null,
|
|
||||||
Set.of(new SupportedSourceAndTarget(MSG, GIF, 200, 60)));
|
|
||||||
InlineTransformer t3 = new InlineTransformer("transformer3", null,
|
|
||||||
Set.of(new SupportedSourceAndTarget(MSG, GIF, 200, 40)));
|
|
||||||
InlineTransformer t4 = new InlineTransformer("transformer4", null,
|
|
||||||
Set.of(new SupportedSourceAndTarget(MSG, GIF, -1, 100)));
|
|
||||||
InlineTransformer t5 = new InlineTransformer("transformer5", null,
|
|
||||||
Set.of(new SupportedSourceAndTarget(MSG, GIF, -1, 80)));
|
|
||||||
|
|
||||||
Map<String, String> actualOptions = null;
|
|
||||||
|
|
||||||
// Select on size - priority is ignored
|
|
||||||
assertTransformerName(MSG, 100, GIF, actualOptions, "transformer1", t1, t2);
|
|
||||||
assertTransformerName(MSG, 150, GIF, actualOptions, "transformer2", t1, t2);
|
|
||||||
assertTransformerName(MSG, 250, GIF, actualOptions, null, t1, t2);
|
|
||||||
// Select on priority - t1, t2 and t4 are discarded.
|
|
||||||
// t3 is a higher priority and has a larger size than t1 and t2.
|
|
||||||
// Similar story fo t4 with t5.
|
|
||||||
assertTransformerName(MSG, 100, GIF, actualOptions, "transformer3", t1, t2, t3, t4, t5);
|
|
||||||
assertTransformerName(MSG, 200, GIF, actualOptions, "transformer3", t1, t2, t3, t4, t5);
|
|
||||||
// Select on size and priority, t1 and t2 discarded
|
|
||||||
assertTransformerName(MSG, 200, GIF, actualOptions, "transformer3", t1, t2, t3, t4);
|
|
||||||
assertTransformerName(MSG, 300, GIF, actualOptions, "transformer4", t1, t2, t3, t4);
|
|
||||||
assertTransformerName(MSG, 300, GIF, actualOptions, "transformer5", t1, t2, t3, t4, t5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultipleTransformers() throws Exception
|
|
||||||
{
|
|
||||||
InlineTransformer transformer1 = new InlineTransformer("transformer1",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "page"),
|
|
||||||
new TransformOptionValue(false, "width"),
|
|
||||||
new TransformOptionValue(false, "height")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, 102400),
|
|
||||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, GIF, -1)));
|
|
||||||
|
|
||||||
InlineTransformer transformer2 = new InlineTransformer("transformer2",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "opt1"),
|
|
||||||
new TransformOptionValue(false, "opt2")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(PDF, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(PPT, JPEG, -1)));
|
|
||||||
|
|
||||||
InlineTransformer transformer3 = new InlineTransformer("transformer3",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "opt1")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, -1)));
|
|
||||||
|
|
||||||
Map<String, String> actualOptions = null;
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, actualOptions, null, transformer1);
|
|
||||||
assertSupported(DOC, 1024, GIF, actualOptions, null, transformer1, transformer2);
|
|
||||||
assertSupported(DOC, 1024, GIF, actualOptions, null, transformer1, transformer2, transformer3);
|
|
||||||
|
|
||||||
assertSupported(DOC, 102401, GIF, null, "source is too large", transformer1);
|
|
||||||
assertSupported(DOC, 102401, GIF, null, null, transformer1, transformer3);
|
|
||||||
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, "Only transformer2 supports these mimetypes", transformer1);
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, null, transformer1, transformer2);
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, null, transformer1, transformer2, transformer3);
|
|
||||||
|
|
||||||
actualOptions = buildActualOptions("opt1");
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, "Only transformer2/4 supports these options", transformer1);
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, null, transformer1, transformer2);
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, null, transformer1, transformer2, transformer3);
|
|
||||||
assertSupported(PDF, 1024, GIF, actualOptions, "transformer4 supports opt1 but not the source mimetype ", transformer1, transformer3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPipeline() throws Exception
|
|
||||||
{
|
|
||||||
InlineTransformer transformer1 = new InlineTransformer("transformer1",
|
|
||||||
null, // there are no options
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, PDF, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, PDF, -1)));
|
|
||||||
|
|
||||||
InlineTransformer transformer2 = new InlineTransformer("transformer2",
|
|
||||||
Set.of(
|
|
||||||
new TransformOptionValue(false, "page"),
|
|
||||||
new TransformOptionValue(false, "width"),
|
|
||||||
new TransformOptionValue(false, "height")),
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(PDF, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(PDF, JPEG, -1)));
|
|
||||||
|
|
||||||
buildPipelineTransformer(transformer1, transformer2);
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, null, null);
|
|
||||||
assertSupported(DOC, 1024, JPEG, null, null);
|
|
||||||
assertSupported(GIF, 1024, DOC, null, GIF+" is not a source of this transformer");
|
|
||||||
assertSupported(MSG, 1024, GIF, null, null);
|
|
||||||
assertSupported(MSG, 1024, JPEG, null, MSG+" to "+JPEG+" is not supported by this transformer");
|
|
||||||
|
|
||||||
// Now try the options
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width"), null);
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width, startPage"), "startPage is not an option");
|
|
||||||
|
|
||||||
// Add options to the first transformer
|
|
||||||
transformer1.setTransformOptions(Set.of(
|
|
||||||
new TransformOptionValue(false, "startPage"),
|
|
||||||
new TransformOptionValue(false, "endPage")));
|
|
||||||
buildPipelineTransformer(transformer1, transformer2);
|
|
||||||
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width"), null);
|
|
||||||
assertSupported(DOC, 1024, GIF, buildActualOptions("page, width, startPage"), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildPipelineTransformer(InlineTransformer transformer1, InlineTransformer transformer2)
|
|
||||||
{
|
|
||||||
transformer = builder.buildPipeLine("transformer1",
|
|
||||||
Set.of(
|
|
||||||
new SupportedSourceAndTarget(DOC, GIF, -1),
|
|
||||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
|
||||||
new SupportedSourceAndTarget(MSG, GIF, -1)),
|
|
||||||
Arrays.asList(
|
|
||||||
new ChildTransformer(false, transformer1),
|
|
||||||
new ChildTransformer(true, transformer2)));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -23,12 +23,15 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.client.model.config;
|
package org.alfresco.transform.client.registry;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||||
|
import org.alfresco.transform.client.model.config.SupportedSourceAndTarget;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOption;
|
||||||
|
import org.alfresco.transform.client.model.config.Transformer;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -43,12 +46,12 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends the {@link TransformServiceRegistryConfigTest} (used to test the config received from the Transform Service)
|
* Extends the {@link TransformServiceRegistryConfigTest} (used to test the config received from the Transform Service)
|
||||||
@@ -115,12 +118,7 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TestLocalTransformServiceRegistry registry;
|
private static Log log = LogFactory.getLog(LocalTransformServiceRegistry.class);
|
||||||
|
|
||||||
private Properties properties = new Properties();
|
|
||||||
|
|
||||||
@Mock private TransformerDebug transformerDebug;
|
|
||||||
@Mock private MimetypeMap mimetypeMap;
|
|
||||||
|
|
||||||
private static final String LOCAL_TRANSFORM_SERVICE_CONFIG = "alfresco/local-transform-service-config-test.json";
|
private static final String LOCAL_TRANSFORM_SERVICE_CONFIG = "alfresco/local-transform-service-config-test.json";
|
||||||
private static final String LOCAL_TRANSFORM_SERVICE_CONFIG_PIPELINE = "alfresco/local-transform-service-config-pipeline-test.json";
|
private static final String LOCAL_TRANSFORM_SERVICE_CONFIG_PIPELINE = "alfresco/local-transform-service-config-pipeline-test.json";
|
||||||
@@ -129,7 +127,15 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
private static final String LOCAL_TRANSFORM = "localTransform.";
|
private static final String LOCAL_TRANSFORM = "localTransform.";
|
||||||
private static final String URL = ".url";
|
private static final String URL = ".url";
|
||||||
|
|
||||||
private static Log log = LogFactory.getLog(LocalTransformServiceRegistry.class);
|
private Map<String, Set<TransformOption>> mapOfTransformOptions;
|
||||||
|
private List<CombinedConfig.TransformAndItsOrigin> transformerList;
|
||||||
|
|
||||||
|
protected TestLocalTransformServiceRegistry registry;
|
||||||
|
|
||||||
|
private Properties properties = new Properties();
|
||||||
|
|
||||||
|
@Mock private TransformerDebug transformerDebug;
|
||||||
|
@Mock private MimetypeMap mimetypeMap;
|
||||||
|
|
||||||
private Map<String, List<String>> imagemagickSupportedTransformation;
|
private Map<String, List<String>> imagemagickSupportedTransformation;
|
||||||
private Map<String, List<String>> tikaSupportedTransformation;
|
private Map<String, List<String>> tikaSupportedTransformation;
|
||||||
@@ -187,20 +193,14 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads and loads localTransforms from LOCAL_TRANSFORM_SERVICE_CONFIG config file.
|
* Loads localTransforms from the LOCAL_TRANSFORM_SERVICE_CONFIG config file.
|
||||||
* @return List<Transformer> list of local transformers.
|
|
||||||
*/
|
*/
|
||||||
private List<CombinedConfig.TransformAndItsOrigin> retrieveLocalTransformList()
|
private void retrieveLocalTransformList()
|
||||||
{
|
{
|
||||||
try {
|
CombinedConfig combinedConfig = new CombinedConfig(log);
|
||||||
CombinedConfig combinedConfig = new CombinedConfig(log);
|
combinedConfig.addLocalConfig(LOCAL_TRANSFORM_SERVICE_CONFIG);
|
||||||
combinedConfig.addLocalConfig(LOCAL_TRANSFORM_SERVICE_CONFIG);
|
mapOfTransformOptions = combinedConfig.combinedTransformOptions;
|
||||||
return combinedConfig.getTransforms();
|
transformerList = combinedConfig.combinedTransformers;
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Could not read LocalTransform config file");
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -280,11 +280,24 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
officeToImageViaPdfSupportedTransformation.put("application/vnd.ms-outlook", targetMimetype);
|
officeToImageViaPdfSupportedTransformation.put("application/vnd.ms-outlook", targetMimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getBaseUrl(InlineTransformer transformer)
|
@Override
|
||||||
|
protected String getBaseUrl(Transformer transformer)
|
||||||
{
|
{
|
||||||
return LOCAL_TRANSFORM+transformer.getTransformerName()+".url";
|
return LOCAL_TRANSFORM+transformer.getTransformerName()+".url";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int countTopLevelOptions(Set<String> transformOptionNames)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (String name: transformOptionNames)
|
||||||
|
{
|
||||||
|
Set<TransformOption> transformOptions = mapOfTransformOptions.get(name);
|
||||||
|
i += transformOptions.size();
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadWriteJson() throws IOException
|
public void testReadWriteJson() throws IOException
|
||||||
{
|
{
|
||||||
@@ -294,7 +307,8 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
@Test
|
@Test
|
||||||
public void testReadJsonConfig()
|
public void testReadJsonConfig()
|
||||||
{
|
{
|
||||||
List<CombinedConfig.TransformAndItsOrigin> transformerList = retrieveLocalTransformList();
|
retrieveLocalTransformList();
|
||||||
|
|
||||||
// Assert expected size of the transformers.
|
// Assert expected size of the transformers.
|
||||||
assertNotNull("Transformer list is null.", transformerList);
|
assertNotNull("Transformer list is null.", transformerList);
|
||||||
assertEquals("Unexpected number of transformers retrieved", 5, transformerList.size());
|
assertEquals("Unexpected number of transformers retrieved", 5, transformerList.size());
|
||||||
@@ -309,18 +323,20 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
|
|
||||||
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
||||||
{
|
{
|
||||||
assertTrue(t.transform.getTransformerName() + " should be an expected local transformer.", listOfExpectedTransformersName.contains(t.transform.getTransformerName()));
|
assertTrue(t.transformer.getTransformerName() + " should be an expected local transformer.", listOfExpectedTransformersName.contains(t.transformer.getTransformerName()));
|
||||||
listOfExpectedTransformersName.remove(t.transform.getTransformerName());
|
listOfExpectedTransformersName.remove(t.transformer.getTransformerName());
|
||||||
|
|
||||||
switch (t.transform.getTransformerName())
|
switch (t.transformer.getTransformerName())
|
||||||
{
|
{
|
||||||
case "imagemagick":
|
case "imagemagick":
|
||||||
assertEquals(t.transform.getTransformerName() + " incorrect number of supported transform", 14, t.transform.getSupportedSourceAndTargetList().size());
|
assertEquals(t.transformer.getTransformerName() + " incorrect number of supported transform", 14, t.transformer.getSupportedSourceAndTargetList().size());
|
||||||
assertEquals( t.transform.getTransformerName() + "incorrect number of transform options", 6, t.transform.getTransformOptions().size());
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform option names", 1, t.transformer.getTransformOptions().size());
|
||||||
assertEquals(t.transform.getTransformerName() + " expected to not be a transformer pipeline", t.transform.getTransformerPipeline().size(), 0);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform options", 6, countTopLevelOptions(t.transformer.getTransformOptions()));
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a transformer pipeline", t.transformer.getTransformerPipeline().size(), 0);
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a failover pipeline", t.transformer.getTransformerFailover().size(), 0);
|
||||||
|
|
||||||
//Test supportedSourceAndTargetList
|
//Test supportedSourceAndTargetList
|
||||||
for ( SupportedSourceAndTarget ssat: t.transform.getSupportedSourceAndTargetList())
|
for ( SupportedSourceAndTarget ssat: t.transformer.getSupportedSourceAndTargetList())
|
||||||
{
|
{
|
||||||
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", imagemagickSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", imagemagickSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
||||||
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), imagemagickSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), imagemagickSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
||||||
@@ -328,12 +344,14 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "tika":
|
case "tika":
|
||||||
assertEquals(t.transform.getTransformerName() + " incorrect number of supported transform", 8, t.transform.getSupportedSourceAndTargetList().size());
|
assertEquals(t.transformer.getTransformerName() + " incorrect number of supported transform", 8, t.transformer.getSupportedSourceAndTargetList().size());
|
||||||
assertEquals( t.transform.getTransformerName() + "incorrect number of transform options", 5, t.transform.getTransformOptions().size());
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform option names", 1, t.transformer.getTransformOptions().size());
|
||||||
assertEquals(t.transform.getTransformerName() + " expected to not be a transformer pipeline", t.transform.getTransformerPipeline().size(), 0);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform options", 5, countTopLevelOptions(t.transformer.getTransformOptions()));
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a transformer pipeline", t.transformer.getTransformerPipeline().size(), 0);
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a failover pipeline", t.transformer.getTransformerFailover().size(), 0);
|
||||||
|
|
||||||
//Test supportedSourceAndTargetList
|
//Test supportedSourceAndTargetList
|
||||||
for ( SupportedSourceAndTarget ssat: t.transform.getSupportedSourceAndTargetList())
|
for ( SupportedSourceAndTarget ssat: t.transformer.getSupportedSourceAndTargetList())
|
||||||
{
|
{
|
||||||
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", tikaSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", tikaSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
||||||
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), tikaSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), tikaSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
||||||
@@ -341,12 +359,14 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "pdfrenderer":
|
case "pdfrenderer":
|
||||||
assertEquals(t.transform.getTransformerName() + " incorrect number of supported transform", 1, t.transform.getSupportedSourceAndTargetList().size());
|
assertEquals(t.transformer.getTransformerName() + " incorrect number of supported transform", 1, t.transformer.getSupportedSourceAndTargetList().size());
|
||||||
assertEquals( t.transform.getTransformerName() + "incorrect number of transform options", 5, t.transform.getTransformOptions().size());
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform option names", 1, t.transformer.getTransformOptions().size());
|
||||||
assertEquals(t.transform.getTransformerName() + " expected to not be a transformer pipeline", t.transform.getTransformerPipeline().size(), 0);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform options", 5, countTopLevelOptions(t.transformer.getTransformOptions()));
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a transformer pipeline", t.transformer.getTransformerPipeline().size(), 0);
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a failover pipeline", t.transformer.getTransformerFailover().size(), 0);
|
||||||
|
|
||||||
//Test supportedSourceAndTargetList
|
//Test supportedSourceAndTargetList
|
||||||
for ( SupportedSourceAndTarget ssat: t.transform.getSupportedSourceAndTargetList())
|
for ( SupportedSourceAndTarget ssat: t.transformer.getSupportedSourceAndTargetList())
|
||||||
{
|
{
|
||||||
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", pdfRendererSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", pdfRendererSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
||||||
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), pdfRendererSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), pdfRendererSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
||||||
@@ -354,12 +374,14 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "libreoffice":
|
case "libreoffice":
|
||||||
assertEquals(t.transform.getTransformerName() + " incorrect number of supported transform", 9, t.transform.getSupportedSourceAndTargetList().size());
|
assertEquals(t.transformer.getTransformerName() + " incorrect number of supported transform", 9, t.transformer.getSupportedSourceAndTargetList().size());
|
||||||
assertEquals( t.transform.getTransformerName() + "incorrect number of transform options", t.transform.getTransformOptions().size(), 0);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform option names", 0, t.transformer.getTransformOptions().size());
|
||||||
assertEquals(t.transform.getTransformerName() + " expected to not be a transformer pipeline", t.transform.getTransformerPipeline().size(), 0);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform options", 0, countTopLevelOptions(t.transformer.getTransformOptions()));
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a transformer pipeline", t.transformer.getTransformerPipeline().size(), 0);
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to not be a failover pipeline", t.transformer.getTransformerFailover().size(), 0);
|
||||||
|
|
||||||
//Test supportedSourceAndTargetList
|
//Test supportedSourceAndTargetList
|
||||||
for ( SupportedSourceAndTarget ssat: t.transform.getSupportedSourceAndTargetList())
|
for ( SupportedSourceAndTarget ssat: t.transformer.getSupportedSourceAndTargetList())
|
||||||
{
|
{
|
||||||
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", libreofficeSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", libreofficeSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
||||||
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), libreofficeSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), libreofficeSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
||||||
@@ -367,12 +389,13 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "officeToImageViaPdf":
|
case "officeToImageViaPdf":
|
||||||
assertEquals(t.transform.getTransformerName() + " incorrect number of supported transform", 28, t.transform.getSupportedSourceAndTargetList().size());
|
assertEquals(t.transformer.getTransformerName() + " incorrect number of supported transform", 28, t.transformer.getSupportedSourceAndTargetList().size());
|
||||||
assertEquals( t.transform.getTransformerName() + "incorrect number of transform options", 2, t.transform.getTransformOptions().size());
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform option names", 2, t.transformer.getTransformOptions().size());
|
||||||
assertEquals(t.transform.getTransformerName() + " expected to be a transformer pipeline", t.transform.getTransformerPipeline().size(), 3);
|
assertEquals( t.transformer.getTransformerName() + "incorrect number of transform options", 11, countTopLevelOptions(t.transformer.getTransformOptions()));
|
||||||
|
assertEquals(t.transformer.getTransformerName() + " expected to be a transformer pipeline", t.transformer.getTransformerPipeline().size(), 3);
|
||||||
|
|
||||||
//Test supportedSourceAndTargetList
|
//Test supportedSourceAndTargetList
|
||||||
for ( SupportedSourceAndTarget ssat: t.transform.getSupportedSourceAndTargetList())
|
for ( SupportedSourceAndTarget ssat: t.transformer.getSupportedSourceAndTargetList())
|
||||||
{
|
{
|
||||||
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", officeToImageViaPdfSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
assertTrue(ssat.getSourceMediaType() + " not expected to be a supported transform source.", officeToImageViaPdfSupportedTransformation.containsKey(ssat.getSourceMediaType()));
|
||||||
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), officeToImageViaPdfSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
assertTrue(ssat.getTargetMediaType() + " not expected to be a supported transform target for " + ssat.getSourceMediaType(), officeToImageViaPdfSupportedTransformation.get(ssat.getSourceMediaType()).contains(ssat.getTargetMediaType()));
|
||||||
@@ -386,13 +409,14 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
@Test
|
@Test
|
||||||
public void testReadTransformProperties()
|
public void testReadTransformProperties()
|
||||||
{
|
{
|
||||||
List<CombinedConfig.TransformAndItsOrigin> transformerList = retrieveLocalTransformList();
|
retrieveLocalTransformList();
|
||||||
|
|
||||||
assertNotNull("Transformer list is null.", transformerList);
|
assertNotNull("Transformer list is null.", transformerList);
|
||||||
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
||||||
{
|
{
|
||||||
if(t.transform.getTransformerPipeline() == null)
|
if(t.transformer.getTransformerPipeline() == null)
|
||||||
{
|
{
|
||||||
assertNotNull(t.transform.getTransformerName()+ " JVM property not set.", System.getProperty(LOCAL_TRANSFORM + t.transform.getTransformerName() + URL));
|
assertNotNull(t.transformer.getTransformerName()+ " JVM property not set.", System.getProperty(LOCAL_TRANSFORM + t.transformer.getTransformerName() + URL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals("Unexpected pdfrenderer JVM property value", "http://localhost:8090/", System.getProperty(LOCAL_TRANSFORM + "pdfrenderer" + URL));
|
assertEquals("Unexpected pdfrenderer JVM property value", "http://localhost:8090/", System.getProperty(LOCAL_TRANSFORM + "pdfrenderer" + URL));
|
||||||
@@ -402,9 +426,9 @@ public class LocalTransformServiceRegistryConfigTest extends TransformServiceReg
|
|||||||
|
|
||||||
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
for (CombinedConfig.TransformAndItsOrigin t : transformerList)
|
||||||
{
|
{
|
||||||
if(t.transform.getTransformerPipeline() == null)
|
if(t.transformer.getTransformerPipeline() == null)
|
||||||
{
|
{
|
||||||
assertNotNull(t.transform.getTransformerName()+ " alfresco-global property not set.", properties.getProperty(LOCAL_TRANSFORM + t.transform.getTransformerName() + URL));
|
assertNotNull(t.transformer.getTransformerName()+ " alfresco-global property not set.", properties.getProperty(LOCAL_TRANSFORM + t.transformer.getTransformerName() + URL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals("Unexpected pdfrenderer alfresco-global property value", "http://localhost:8090/", properties.getProperty(LOCAL_TRANSFORM + "pdfrenderer" + URL));
|
assertEquals("Unexpected pdfrenderer alfresco-global property value", "http://localhost:8090/", properties.getProperty(LOCAL_TRANSFORM + "pdfrenderer" + URL));
|
@@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco 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.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.client.registry;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOption;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOptionGroup;
|
||||||
|
import org.alfresco.transform.client.model.config.TransformOptionValue;
|
||||||
|
import org.alfresco.transform.client.registry.SupportedTransform;
|
||||||
|
import org.alfresco.transform.client.registry.TransformRegistryTest;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.LogManager;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the config received from the Transform Service about what it supports.
|
||||||
|
*
|
||||||
|
* @author adavis
|
||||||
|
*/
|
||||||
|
public class TransformServiceRegistryConfigTest extends TransformRegistryTest
|
||||||
|
{
|
||||||
|
private static Log log = LogFactory.getLog(TransformServiceRegistryConfigTest.class);
|
||||||
|
|
||||||
|
public static final String PNG = "image/png";
|
||||||
|
public static final String TIFF = "image/tiff";
|
||||||
|
|
||||||
|
private static final String TRANSFORM_SERVICE_CONFIG = "alfresco/transform-service-config-test.json";
|
||||||
|
private static final String TRANSFORM_SERVICE_CONFIG_PIPELINE = "alfresco/transform-service-config-pipeline-test.json";
|
||||||
|
|
||||||
|
public static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
super.setUp();
|
||||||
|
LogManager.getLogger(TransformServiceRegistryConfigTest.class).setLevel(Level.DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TransformServiceRegistryImpl buildTransformServiceRegistryImpl() throws Exception
|
||||||
|
{
|
||||||
|
TransformServiceRegistryImpl registry = new TransformServiceRegistryImpl()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean readConfig() throws IOException
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Log getLog()
|
||||||
|
{
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
registry.setJsonObjectMapper(JSON_OBJECT_MAPPER);
|
||||||
|
registry.setCronExpression(null); // just read once
|
||||||
|
registry.afterPropertiesSet();
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown()
|
||||||
|
{
|
||||||
|
// shut down
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getTransformServiceConfig()
|
||||||
|
{
|
||||||
|
return TRANSFORM_SERVICE_CONFIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getTransformServiceConfigPipeline()
|
||||||
|
{
|
||||||
|
return TRANSFORM_SERVICE_CONFIG_PIPELINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void register(String path) throws IOException
|
||||||
|
{
|
||||||
|
CombinedConfig combinedConfig = new CombinedConfig(log);
|
||||||
|
combinedConfig.addLocalConfig(path);
|
||||||
|
combinedConfig.register((TransformServiceRegistryImpl)registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJsonConfig() throws IOException
|
||||||
|
{
|
||||||
|
register(getTransformServiceConfig());
|
||||||
|
|
||||||
|
// Check the count of transforms supported
|
||||||
|
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
||||||
|
60, countSupportedTransforms(true));
|
||||||
|
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
||||||
|
"There may be multiple transformers for the same combination. Config change?",
|
||||||
|
60, countSupportedTransforms(false));
|
||||||
|
|
||||||
|
// Check a supported transform for each transformer.
|
||||||
|
assertSupported(DOC, 1234, PDF, emptyMap(), null, ""); // libreoffice
|
||||||
|
assertSupported(DOC, 1234, PDF, emptyMap(), null, ""); // libreoffice
|
||||||
|
assertSupported(PDF, 1234, PNG, emptyMap(), null, ""); // pdfrenderer
|
||||||
|
assertSupported(JPEG,1234, GIF, emptyMap(), null, ""); // imagemagick
|
||||||
|
assertSupported(MSG, 1234, TXT, emptyMap(), null, ""); // tika
|
||||||
|
assertSupported(MSG, 1234, GIF, emptyMap(), null, ""); // officeToImageViaPdf
|
||||||
|
|
||||||
|
Map<String, String> invalidPdfOptions = new HashMap<>();
|
||||||
|
invalidPdfOptions.put("allowEnlargement", "false");
|
||||||
|
assertSupported(DOC, 1234, PDF, invalidPdfOptions, null, "Invalid as there is a extra option");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJsonPipeline() throws IOException
|
||||||
|
{
|
||||||
|
register(getTransformServiceConfigPipeline());
|
||||||
|
|
||||||
|
// Check the count of transforms supported
|
||||||
|
int expectedTransforms = getExpectedTransformsForTestJsonPipeline();
|
||||||
|
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
||||||
|
expectedTransforms, countSupportedTransforms(true));
|
||||||
|
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
||||||
|
"There may be multiple transformers for the same combination. Config change?",
|
||||||
|
expectedTransforms, countSupportedTransforms(false));
|
||||||
|
|
||||||
|
// Check required and optional default correctly
|
||||||
|
Map<String, List<SupportedTransform>> transformsToWord =
|
||||||
|
registry.getData().getTransforms().get(DOC);
|
||||||
|
List<SupportedTransform> supportedTransforms = transformsToWord.get(GIF);
|
||||||
|
SupportedTransform supportedTransform = supportedTransforms.get(0);
|
||||||
|
|
||||||
|
Set<TransformOption> transformOptionsSet = supportedTransform.getTransformOptions().getTransformOptions();
|
||||||
|
System.out.println("Nothing");
|
||||||
|
|
||||||
|
Iterator<TransformOption> iterator = transformOptionsSet.iterator();
|
||||||
|
assertTrue("Expected transform values", iterator.hasNext());
|
||||||
|
// Because Set is unordered we don't know which TransformOptionGroup we retrieve
|
||||||
|
TransformOptionGroup transformOptions1 = (TransformOptionGroup)iterator.next();
|
||||||
|
|
||||||
|
assertTrue("Expected transform values", iterator.hasNext());
|
||||||
|
TransformOptionGroup transformOptions2 = (TransformOptionGroup)iterator.next();
|
||||||
|
|
||||||
|
TransformOptionGroup imagemagick;
|
||||||
|
TransformOptionGroup pdf;
|
||||||
|
|
||||||
|
if(containsTransformOptionValueName(transformOptions1, "alphaRemove"))
|
||||||
|
{
|
||||||
|
imagemagick = transformOptions1;
|
||||||
|
pdf = transformOptions2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imagemagick = transformOptions2;
|
||||||
|
pdf = transformOptions1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformOptionValue alphaRemove = (TransformOptionValue)retrieveTransformOptionByPropertyName(imagemagick, "alphaRemove", "TransformOptionValue");
|
||||||
|
TransformOptionGroup crop = (TransformOptionGroup)retrieveTransformOptionByPropertyName(imagemagick, "crop", "TransformOptionGroup");
|
||||||
|
TransformOptionValue cropGravity = (TransformOptionValue)retrieveTransformOptionByPropertyName(crop, "cropGravity", "TransformOptionValue");
|
||||||
|
TransformOptionValue cropWidth = (TransformOptionValue)retrieveTransformOptionByPropertyName(crop, "cropWidth", "TransformOptionValue");
|
||||||
|
|
||||||
|
assertTrue("The holding group should be required", supportedTransform.getTransformOptions().isRequired());
|
||||||
|
assertFalse("imagemagick should be optional as it is not set", imagemagick.isRequired());
|
||||||
|
assertFalse("pdf should be optional as required is not set", pdf.isRequired());
|
||||||
|
assertEquals("alphaRemove", alphaRemove.getName());
|
||||||
|
assertEquals("cropGravity", cropGravity.getName());
|
||||||
|
assertEquals("cropWidth", cropWidth.getName());
|
||||||
|
assertFalse("alphaRemove should be optional as required is not set", alphaRemove.isRequired());
|
||||||
|
assertFalse("crop should be optional as required is not set", crop.isRequired());
|
||||||
|
assertTrue("cropGravity should be required as it is set", cropGravity.isRequired());
|
||||||
|
assertFalse("cropWidth should be optional as required is not set", cropWidth.isRequired());
|
||||||
|
|
||||||
|
// Check a supported transform for each transformer.
|
||||||
|
assertSupported(DOC,1234, GIF, emptyMap(), null, "");
|
||||||
|
assertSupported(DOC,1234, PNG, emptyMap(), null, "");
|
||||||
|
assertSupported(DOC,1234, JPEG, emptyMap(), null, "");
|
||||||
|
assertSupported(DOC,1234, TIFF, emptyMap(), null, "");
|
||||||
|
|
||||||
|
Map<String, String> actualOptions = new HashMap<>();
|
||||||
|
actualOptions.put("thumbnail", "true");
|
||||||
|
actualOptions.put("resizeWidth", "100");
|
||||||
|
actualOptions.put("resizeHeight", "100");
|
||||||
|
actualOptions.put("allowEnlargement", "false");
|
||||||
|
actualOptions.put("maintainAspectRatio", "true");
|
||||||
|
assertSupported(DOC,1234, PNG, actualOptions, null, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransformOption retrieveTransformOptionByPropertyName (TransformOptionGroup transformOptionGroup, String propertyName, String propertyType)
|
||||||
|
{
|
||||||
|
Iterator<TransformOption> iterator = transformOptionGroup.getTransformOptions().iterator();
|
||||||
|
|
||||||
|
List<TransformOption> transformOptionsList = new ArrayList<>();
|
||||||
|
while(iterator.hasNext())
|
||||||
|
{
|
||||||
|
transformOptionsList.add(iterator.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TransformOption t : transformOptionsList)
|
||||||
|
{
|
||||||
|
if (t instanceof TransformOptionValue)
|
||||||
|
{
|
||||||
|
TransformOptionValue value = (TransformOptionValue) t;
|
||||||
|
if (propertyType.equalsIgnoreCase("TransformOptionValue"))
|
||||||
|
{
|
||||||
|
if (value.getName().equalsIgnoreCase(propertyName))
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value.getName().contains(propertyName))
|
||||||
|
return transformOptionGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TransformOption result = retrieveTransformOptionByPropertyName((TransformOptionGroup)t, propertyName, propertyType);
|
||||||
|
if (result != null)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsTransformOptionValueName (TransformOptionGroup transformOptionGroup, String propertyName)
|
||||||
|
{
|
||||||
|
return retrieveTransformOptionByPropertyName(transformOptionGroup, propertyName, "TransformOptionValue") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getExpectedTransformsForTestJsonPipeline()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countSupportedTransforms(boolean unique)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int uniqueCount = 0;
|
||||||
|
for (Map<String, List<SupportedTransform>> targetMap : registry.getData().getTransforms().values())
|
||||||
|
{
|
||||||
|
for (List<SupportedTransform> supportedTransforms : targetMap.values())
|
||||||
|
{
|
||||||
|
uniqueCount++;
|
||||||
|
count += supportedTransforms.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unique ? uniqueCount : count;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user