diff --git a/engines/aio/src/main/java/org/alfresco/transform/coreaio/AIOTransformEngine.java b/engines/aio/src/main/java/org/alfresco/transform/coreaio/AIOTransformEngine.java index c67f8379..f5864477 100644 --- a/engines/aio/src/main/java/org/alfresco/transform/coreaio/AIOTransformEngine.java +++ b/engines/aio/src/main/java/org/alfresco/transform/coreaio/AIOTransformEngine.java @@ -78,8 +78,7 @@ public class AIOTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.pdf", "quick.txt", - MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, Collections.emptyMap(), + return new ProbeTransform("quick.pdf", MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, Collections.emptyMap(), 60, 16, 400, 10240, 60 * 30 + 1, 60 * 15 + 20); } } diff --git a/engines/base/README.md b/engines/base/README.md index 2d21c21d..4a358058 100644 --- a/engines/base/README.md +++ b/engines/base/README.md @@ -1,233 +1,147 @@ -# Common code for Transform Engines +# Common base code for T-Engines -This project contains code that is common between all the ACS T-Engine transformers that run as Spring Boot process (optionally within their own -Docker containers). It performs common actions such as logging, throttling requests and handling the streaming of content to and from the container. +This project provides a common base for T-Engines and supersedes the +[original base](https://github.com/Alfresco/alfresco-transform-core/blob/master/deprecated/alfresco-transformer-base). -For more details on build a custom T-Engine, please refer to the current docs in ACS Packaging, including: +This project provides a base Spring Boot application (as a jar) to which transform +specific code may be added. It includes actions such as communication between +components and logging. + +For more details on build a custom T-Engine and T-Config, please refer to the docs in ACS Packaging, including: * [ATS Configuration](https://github.com/Alfresco/acs-packaging/blob/master/docs/custom-transforms-and-renditions.md#ats-configuration) * [Creating a T-Engine](https://github.com/Alfresco/acs-packaging/blob/master/docs/creating-a-t-engine.md) ## Overview -A transformer project is expected to provide the following files: +A T-Engine project which extends this base is expected to provide the following: -~~~ -src/main/resources/templates/test.html -src/main/java/org/alfresco/transformer/Controller.java -src/main/java/org/alfresco/transformer/Application.java -~~~ +* An implementation of the [TransformEngine](https://github.com/Alfresco/alfresco-transform-core/blob/master/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java) + interface to describe the T-Engine. +* Implementations of the [CustomTransformer](engines/base/src/main/java/org/alfresco/transform/base/CustomTransformer.java) + interface with the actual transform code. + +The `TransformEngine` and `CustomTransformer` implementations should have an +`@Component` annotation and be in or below the`org.alfresco.transform` package, so +that they will be discovered by the base T-Engine. -* test.html - A simple test page using [thymeleaf](http://www.thymeleaf.org) that gathers request - parameters, so they may be used to test the transformer. +The `TransformEngine.getTransformConfig()` method typically reads a `json` file. +The names in the config should match the names returned by the `CustomTransformer` +implementations. -~~~ - - -
-

Test Transformation

-
- - - - - - - - - - - -
file *
file *
sourceExtension *
targetExtension *
sourceMimetype *
targetMimetype *
abc:width
abc:height
timeout
-
-
-
- Log -
- - -~~~ -* *TransformerName*Controller.java - A [Spring Boot](https://projects.spring.io/spring-boot/) Controller that - extends TransformController to handel requests. It implements a few methods including *transformImpl* - which is intended to perform the actual transform. Generally the transform is done in a sub class of - *JavaExecutor*, when a Java library is being used or *AbstractCommandExecutor*, when an external process is used. - Both are sub interfaces of *Transformer*. +**Example TransformEngine** -~~~ -... -@Controller -public class TransformerNameController extends TransformController +The `TransformEngineName` is important if the config from multiple T-Engines is being +combined as they are sorted by name. +``` +package org.alfresco.transform.example; + +import com.google.common.collect.ImmutableMap; +import org.alfresco.transform.base.TransformEngine; +import org.alfresco.transform.base.probes.ProbeTransform; +import org.alfresco.transform.common.TransformConfigResourceReader; +import org.alfresco.transform.config.TransformConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class HelloTransformEngine implements TransformEngine { - private static final Logger logger = LoggerFactory.getLogger(TransformerNameController.class); + @Autowired + private TransformConfigResourceReader transformConfigResourceReader; - TransformerNameExecutor executor; - - @PostConstruct - private void init() + @Override + public String getTransformEngineName() { - executor = new TransformerNameExecutor(); + return "0200_hello"; } + @Override + public String getStartupMessage() + { + return "Startup "+getTransformEngineName()+"\nNo 3rd party licenses"; + } + + @Override + public TransformConfig getTransformConfig() + { + return transformConfigResourceReader.read("classpath:hello_engine_config.json"); + } + + @Override + public ProbeTransform getProbeTransform() + { + return new ProbeTransform("jane.txt", "text/plain", "text/plain", + ImmutableMap.of("sourceEncoding", "UTF-8", "language", "English"), + 11, 10, 150, 1024, 1, 60 * 2); + } +} +``` + +**Example CustomTransformer** +``` +package org.alfresco.transform.example; + +import org.alfresco.transform.base.CustomTransformer; +import org.alfresco.transform.base.TransformManager; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +@Component +public class HelloTransformer implements CustomTransformer +{ @Override public String getTransformerName() { - return "Transformer Name"; + return "hello"; } @Override - public String version() + public void transform(String sourceMimetype, InputStream inputStream, String targetMimetype, + OutputStream outputStream, Map transformOptions, TransformManager transformManager) + throws Exception { - return commandExecutor.version(); + String name = new String(inputStream.readAllBytes(), transformOptions.get("sourceEncoding")); + String greeting = String.format(getGreeting(transformOptions.get("language")), name); + byte[] bytes = greeting.getBytes(transformOptions.get("sourceEncoding")); + outputStream.write(bytes, 0, bytes.length); } - @Override - public ProbeTestTransform getProbeTestTransform() + private String getGreeting(String language) { - // See the Javadoc on this method and Probes.md for the choice of these values. - return new ProbeTestTransform(this, "quick.pdf", "quick.png", - 7455, 1024, 150, 10240, 60 * 20 + 1, 60 * 15 - 15) - { - @Override - protected void executeTransformCommand(File sourceFile, File targetFile) - { - transformImpl(null, null, null, Collections.emptyMap(), sourceFile, targetFile); - } - }; + return "Hello %s"; } - - @Override - public void transformImpl(String transformName, String sourceMimetype, String targetMimetype, - Map transformOptions, File sourceFile, File targetFile) - { - executor.transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile); - } -} -~~~ - -* *TransformerName*Executer.java - *JavaExecutor* and *CommandExecutor* sub classes need to extract values from - *transformOptions* and use them in a call to an external process or as parameters to a library call. -~~~ -... -public class TransformerNameExecutor extends AbstractCommandExecutor -{ - ... - @Override - public void transform(String transformName, String sourceMimetype, String targetMimetype, - Map transformOptions, - File sourceFile, File targetFile) throws TransformException - { - final String options = TransformerNameOptionsBuilder - .builder() - .withWidth(transformOptions.get(WIDTH_REQUEST_PARAM)) - .withHeight(transformOptions.get(HEIGHT_REQUEST_PARAM)) - .build(); - - Long timeout = stringToLong(transformOptions.get(TIMEOUT)); - - run(options, sourceFile, targetFile, timeout); - } -} -~~~ - -* Application.java - [Spring Boot](https://projects.spring.io/spring-boot/) expects to find an Application in - a project's source files. The following may be used: - -~~~ -package org.alfresco.transformer; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application -{ - public static void main(String[] args) - { - SpringApplication.run(Application.class, args); - } -} -~~~ - -Transform requests are handled by the *TransformController*, but are either: - * POST requests (a direct http request from a client) where the transform options are passed as parameters, the source is supplied as a multipart file and - the response is a file download. - * POST request (a request via a message queue) where the transform options are supplied as JSON and the response is also JSON. - The source and target content is read from a location accessible to both the client and the transfomer. - -**Example JSON request body** -```javascript -var transformRequest = { - "requestId": "1", - "sourceReference": "2f9ed237-c734-4366-8c8b-6001819169a4", - "sourceMediaType": "application/pdf", - "sourceSize": 123456, - "sourceExtension": "pdf", - "targetMediaType": "text/plain", - "targetExtension": "txt", - "clientType": "ACS", - "clientData": "Yo No Soy Marinero, Soy Capitan, Soy Capitan!", - "schema": 1, - "transformRequestOptions": { - "targetMimetype": "text/plain", - "targetEncoding": "UTF-8", - "abc:width": "120", - "abc:height": "200" - } } ``` -**Example JSON response body** - -```javascript -var transformReply = { - "requestId": "1", - "status": 201, - "errorDetails": null, - "sourceReference": "2f9ed237-c734-4366-8c8b-6001819169a4", - "targetReference": "34d69ff0-7eaa-4741-8a9f-e1915e6995bf", - "clientType": "ACS", - "clientData": "Yo No Soy Marinero, Soy Capitan, Soy Capitan!", - "schema": 1 +**Example T-Config** `resources/hello_engine_config.json` +```json +{ + "transformOptions": { + "helloOptions": [ + {"value": {"name": "language"}}, + {"value": {"name": "sourceEncoding"}} + ] + }, + "transformers": [ + { + "transformerName": "hello", + "supportedSourceAndTargetList": [ + {"sourceMediaType": "text/plain", "targetMediaType": "text/plain" } + ], + "transformOptions": [ + "helloOptions" + ] + } + ] } ``` -## Building and testing - -The project can be built by running the Maven command: - -~~~ -mvn clean install -~~~ - -## Artifacts - -The artifacts can be obtained by: - -* downloading from the [Alfresco repository](https://artifacts.alfresco.com/nexus/content/groups/public/) -* Adding a Maven dependency to your pom file. - -~~~ - - org.alfresco - alfresco-base-t-engine - 1.0 - -~~~ - -and the Alfresco Maven repository: - -~~~ - - alfresco-maven-repo - https://artifacts.alfresco.com/nexus/content/groups/public - -~~~ - -The build plan is available in [TravisCI](https://travis-ci.com/Alfresco/alfresco-transform-core). - -## Contributing guide - -Please use [this guide](https://github.com/Alfresco/alfresco-repository/blob/master/CONTRIBUTING.md) -to make a contribution to the project. - +**Example `ProbeTransform` test file** `jane.txt` +```json +Jane +``` \ No newline at end of file diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java index e9a2cf69..71a01c6c 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java @@ -50,7 +50,9 @@ public interface TransformEngine /** * @return a definition of what the t-engine supports. Normally read from a json Resource on the classpath using a - * {@link TransformConfigResourceReader}. + * {@link TransformConfigResourceReader}. To combine to code from multiple t-engine into a single t-engine + * include all the TransformEngines and CustomTransform implementations, plus a wrapper TransformEngine for the + * others. The wrapper should return {@code null} from this method. */ TransformConfig getTransformConfig(); diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java index 3f4bb15b..e0581b71 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java @@ -74,6 +74,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import static java.util.stream.Collectors.joining; import static org.alfresco.transform.base.fs.FileManager.createTargetFile; @@ -638,7 +639,10 @@ public class TransformHandler sourceSizeInBytes, targetMimetype, transformOptions, null); if (transformerName == null) { - throw new TransformException(BAD_REQUEST, "No transforms were able to handle the request"); + throw new TransformException(BAD_REQUEST, "No transforms were able to handle the request: "+ + sourceMimetype+" -> "+targetMimetype+transformOptions.entrySet().stream() + .map(entry -> entry.getKey()+"="+entry.getValue()) + .collect(Collectors.joining(", ", " with ", ""))); } return transformerName; } diff --git a/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java b/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java index 23ce4532..e8eec15a 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java @@ -51,9 +51,9 @@ import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS; /** * Provides test transformations and the logic used by k8 liveness and readiness probes. * - *

K8s probes: A readiness probe indicates if the pod should accept request. It does not indicate that a pod is - * ready after startup. The liveness probe indicates when to kill the pod. Both probes are called throughout the - * lifetime of the pod and a liveness probes can take place before a readiness probe. The k8s + *

K8s probes: A readiness probe indicates if the pod should accept request. It does not indicate that a + * pod is ready after startup. The liveness probe indicates when to kill the pod. Both probes are called + * throughout the lifetime of the pod and a liveness probes can take place before a readiness probe. The k8s * initialDelaySeconds field is not fully honoured as it is multiplied by a random number, so is * actually a maximum initial delay in seconds, but could be 0.

* @@ -81,7 +81,6 @@ public class ProbeTransform private static final int AVERAGE_OVER_TRANSFORMS = 5; private final String sourceFilename; - private final String targetFilename; private final String sourceMimetype; private final String targetMimetype; private final Map transformOptions; @@ -115,13 +114,11 @@ public class ProbeTransform return maxTime; } - public ProbeTransform(String sourceFilename, String targetFilename, - String sourceMimetype, String targetMimetype, Map transformOptions, + public ProbeTransform(String sourceFilename, String sourceMimetype, String targetMimetype, Map transformOptions, long expectedLength, long plusOrMinus, int livenessPercent, long maxTransforms, long maxTransformSeconds, long livenessTransformPeriodSeconds) { this.sourceFilename = sourceFilename; - this.targetFilename = targetFilename; this.sourceMimetype = sourceMimetype; this.targetMimetype = targetMimetype; this.transformOptions = new HashMap(transformOptions); @@ -271,14 +268,14 @@ public class ProbeTransform getMessagePrefix(isLiveProbe) + "Failed to store the source file", e); } long length = sourceFile.length(); - LogEntry.setSource(sourceFilename, length); + LogEntry.setSource(sourceFile.getName(), length); return sourceFile; } private File getTargetFile() { - File targetFile = createTempFile("target_", "_" + targetFilename); - LogEntry.setTarget(targetFilename); + File targetFile = createTempFile("target_", "_" + sourceFilename); + LogEntry.setTarget(targetFile.getName()); return targetFile; } diff --git a/engines/base/src/main/resources/engine_config.json b/engines/base/src/main/resources/engine_config.json deleted file mode 100644 index 9e26dfee..00000000 --- a/engines/base/src/main/resources/engine_config.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/engines/base/src/test/java/org/alfresco/transform/base/QueueTransformServiceTest.java b/engines/base/src/test/java/org/alfresco/transform/base/QueueTransformServiceTest.java index 62e834a2..fc260165 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/QueueTransformServiceTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/QueueTransformServiceTest.java @@ -46,11 +46,14 @@ import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; @@ -187,13 +190,13 @@ public class QueueTransformServiceTest .build(); doReturn(request).when(transformMessageConverter).fromMessage(msg); - doReturn(new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()))) - .when(transformHandler).handleMessageRequest(request, null, null); + doAnswer(invocation -> {transformReplySender.send(destination, reply); return null;}) + .when(transformHandler).handleMessageRequest(request, null, destination); queueTransformService.receive(msg); verify(transformMessageConverter).fromMessage(msg); - verify(transformHandler).handleMessageRequest(request, null, null); + verify(transformHandler).handleMessageRequest(request, null, destination); verify(transformReplySender).send(destination, reply); } @@ -228,13 +231,13 @@ public class QueueTransformServiceTest .build(); doReturn(request).when(transformMessageConverter).fromMessage(msg); - doReturn(new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()))) - .when(transformHandler).handleMessageRequest(request, null, null); + doAnswer(invocation -> {transformReplySender.send(destination, reply); return null;}) + .when(transformHandler).handleMessageRequest(request, null, destination); queueTransformService.receive(msg); verify(transformMessageConverter).fromMessage(msg); - verify(transformHandler).handleMessageRequest(request, null, null); + verify(transformHandler).handleMessageRequest(request, null, destination); verify(transformReplySender).send(destination, reply); } } diff --git a/engines/base/src/test/java/org/alfresco/transform/base/fakes/FakeTransformEngineWithTwoCustomTransformers.java b/engines/base/src/test/java/org/alfresco/transform/base/fakes/FakeTransformEngineWithTwoCustomTransformers.java index 35c499e3..a01d0ffb 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/fakes/FakeTransformEngineWithTwoCustomTransformers.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/fakes/FakeTransformEngineWithTwoCustomTransformers.java @@ -46,7 +46,8 @@ import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING; public class FakeTransformEngineWithTwoCustomTransformers extends AbstractFakeTransformEngine { - @Override public TransformConfig getTransformConfig() + @Override + public TransformConfig getTransformConfig() { String docOptions = "docOptions"; String imageOptions = "imageOptions"; @@ -103,11 +104,11 @@ public class FakeTransformEngineWithTwoCustomTransformers extends AbstractFakeTr .build(); } - @Override public ProbeTransform getProbeTransform() + @Override + public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.txt", "quick.pdf", - MIMETYPE_TEXT_PLAIN, MIMETYPE_PDF, ImmutableMap.of(SOURCE_ENCODING, "UTF-8"), - 46, 0, 150, 1024, 1, - 60 * 2); + return new ProbeTransform("quick.txt", MIMETYPE_TEXT_PLAIN, MIMETYPE_PDF, + ImmutableMap.of(SOURCE_ENCODING, "UTF-8"), 46, 0, + 150, 1024, 1, 60 * 2); } } diff --git a/engines/example/.maven-dockerignore b/engines/example/.maven-dockerignore new file mode 100644 index 00000000..112bd182 --- /dev/null +++ b/engines/example/.maven-dockerignore @@ -0,0 +1 @@ +target/docker/ \ No newline at end of file diff --git a/engines/example/Dockerfile b/engines/example/Dockerfile new file mode 100644 index 00000000..1d9f749b --- /dev/null +++ b/engines/example/Dockerfile @@ -0,0 +1,26 @@ +FROM alfresco/alfresco-base-java:jre11-centos7-202207110835 + +ARG EXIFTOOL_VERSION=12.25 +ARG EXIFTOOL_FOLDER=Image-ExifTool-${EXIFTOOL_VERSION} +ARG EXIFTOOL_URL=https://nexus.alfresco.com/nexus/service/local/repositories/thirdparty/content/org/exiftool/image-exiftool/${EXIFTOOL_VERSION}/image-exiftool-${EXIFTOOL_VERSION}.tgz + +ENV JAVA_OPTS="" + +ARG GROUPNAME=Alfresco +ARG GROUPID=1000 +ARG EXAMPLEUSERNAME=example +ARG USERID=33009 + +COPY target/${env.project_artifactId}-${env.project_version}.jar /usr/bin + +RUN ln /usr/bin/${env.project_artifactId}-${env.project_version}.jar /usr/bin/${env.project_artifactId}.jar + +RUN groupadd -g ${GROUPID} ${GROUPNAME} && \ + useradd -u ${USERID} -G ${GROUPNAME} ${EXAMPLEUSERNAME} && \ + chgrp -R ${GROUPNAME} /usr/bin/${env.project_artifactId}.jar + +EXPOSE 8090 + +USER ${EXAMPLEUSERNAME} + +ENTRYPOINT java $JAVA_OPTS -jar /usr/bin/${env.project_artifactId}.jar diff --git a/engines/example/pom.xml b/engines/example/pom.xml new file mode 100644 index 00000000..8a7f918d --- /dev/null +++ b/engines/example/pom.xml @@ -0,0 +1,300 @@ + + + 4.0.0 + alfresco-transform-example + - Example + + + alfresco-transform-core + org.alfresco + 2.6.1-SNAPSHOT + ../../pom.xml + + + + alfresco/alfresco-transform-example + quay.io + ${project.artifactId} + + + + + org.alfresco + alfresco-base-t-engine + ${project.version} + + + org.alfresco + alfresco-base-t-engine + ${project.version} + tests + test-jar + test + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-test + test + + + com.vaadin.external.google + android-json + + + + + + org.dom4j + dom4j + + + + org.junit.jupiter + junit-jupiter + test + + + org.mockito + mockito-junit-jupiter + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + org.alfresco.transform.base.Application + + + + org.codehaus.mojo + license-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + + + + docker-it-setup + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + io.fabric8 + docker-maven-plugin + + + integration-tests + + start + stop + + + + + alfresco/alfresco-activemq:5.16.1 + + activemq + + 8161:8161 + 5672:5672 + 61616:61616 + + + Apache ActiveMQ 5.16.1 .* started + + 500 + 100 + + kill 1 + kill -9 1 + + + + + + ${image.name}:${image.tag} + + + 8090:8090 + + + + http://localhost:8090/transform/config + GET + 200...299 + + + 500 + 100 + + kill 1 + kill -9 1 + + + + + + + + + + + + + + + local + + + + io.fabric8 + docker-maven-plugin + + + build-image + package + + build + + + + + ${image.name}:${image.tag} + + ${project.basedir} + + true + + + + + + + + + + + + + + internal + + + + io.fabric8 + docker-maven-plugin + + + + + ${image.name}:${image.tag} + ${image.registry} + + ${project.basedir} + + true + + + + + + ${image.name}:${image.tag} + + ${project.basedir} + + true + + + + + + + + build-image + package + + build + + + + push-image + install + + push + + + + + + + + + + release + + + + io.fabric8 + docker-maven-plugin + + + + + ${image.name}:${project.version} + ${image.registry} + + ${project.basedir} + + true + + + + + + ${image.name}:${project.version} + + ${project.basedir} + + true + + + + + + + + + build + push + + + + + + + + + diff --git a/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformEngine.java b/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformEngine.java new file mode 100644 index 00000000..76f5b465 --- /dev/null +++ b/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformEngine.java @@ -0,0 +1,68 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2022 - 2022 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 . + * #L% + */ +package org.alfresco.transform.example; + +import com.google.common.collect.ImmutableMap; +import org.alfresco.transform.base.TransformEngine; +import org.alfresco.transform.base.probes.ProbeTransform; +import org.alfresco.transform.common.TransformConfigResourceReader; +import org.alfresco.transform.config.TransformConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class HelloTransformEngine implements TransformEngine +{ + @Autowired + private TransformConfigResourceReader transformConfigResourceReader; + + @Override + public String getTransformEngineName() + { + return "0200_hello"; + } + + @Override + public String getStartupMessage() + { + return "Startup "+getTransformEngineName()+"\nNo 3rd party licenses"; + } + + @Override + public TransformConfig getTransformConfig() + { + return transformConfigResourceReader.read("classpath:hello_engine_config.json"); + } + + @Override + public ProbeTransform getProbeTransform() + { + return new ProbeTransform("jane.txt", "text/plain", "text/plain", + ImmutableMap.of("sourceEncoding", "UTF-8", "language", "English"), + 11, 10, 150, 1024, 1, 60 * 2); + } +} \ No newline at end of file diff --git a/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformer.java b/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformer.java new file mode 100644 index 00000000..7bfb7e09 --- /dev/null +++ b/engines/example/src/main/java/org/alfresco/transform/example/HelloTransformer.java @@ -0,0 +1,61 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2022 - 2022 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 . + * #L% + */ +package org.alfresco.transform.example; + +import org.alfresco.transform.base.CustomTransformer; +import org.alfresco.transform.base.TransformManager; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +@Component +public class HelloTransformer implements CustomTransformer +{ + @Override + public String getTransformerName() + { + return "hello"; + } + + @Override + public void transform(String sourceMimetype, InputStream inputStream, String targetMimetype, + OutputStream outputStream, Map transformOptions, TransformManager transformManager) + throws Exception + { + String name = new String(inputStream.readAllBytes(), transformOptions.get("sourceEncoding")); + String greeting = String.format(getGreeting(transformOptions.get("language")), name); + byte[] bytes = greeting.getBytes(transformOptions.get("sourceEncoding")); + outputStream.write(bytes, 0, bytes.length); + } + + private String getGreeting(String language) + { + return "Hello %s"; + } +} \ No newline at end of file diff --git a/engines/example/src/main/resources/hello_engine_config.json b/engines/example/src/main/resources/hello_engine_config.json new file mode 100644 index 00000000..ecf994df --- /dev/null +++ b/engines/example/src/main/resources/hello_engine_config.json @@ -0,0 +1,19 @@ +{ + "transformOptions": { + "helloOptions": [ + {"value": {"name": "language"}}, + {"value": {"name": "sourceEncoding"}} + ] + }, + "transformers": [ + { + "transformerName": "hello", + "supportedSourceAndTargetList": [ + {"sourceMediaType": "text/plain", "targetMediaType": "text/plain" } + ], + "transformOptions": [ + "helloOptions" + ] + } + ] +} \ No newline at end of file diff --git a/engines/example/src/main/resources/jane.txt b/engines/example/src/main/resources/jane.txt new file mode 100644 index 00000000..61c30b63 --- /dev/null +++ b/engines/example/src/main/resources/jane.txt @@ -0,0 +1 @@ +Jane \ No newline at end of file diff --git a/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/ImageMagickTransformEngine.java b/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/ImageMagickTransformEngine.java index 94c05200..7a1041a2 100644 --- a/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/ImageMagickTransformEngine.java +++ b/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/ImageMagickTransformEngine.java @@ -68,8 +68,7 @@ public class ImageMagickTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.jpg", "quick.png", - MIMETYPE_IMAGE_JPEG, MIMETYPE_IMAGE_PNG, Collections.emptyMap(), + return new ProbeTransform("quick.jpg", MIMETYPE_IMAGE_JPEG, MIMETYPE_IMAGE_PNG, Collections.emptyMap(), 35593, 1024, 150, 1024, 60 * 15 + 1, 60 * 15); } } diff --git a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/LibreOfficeTransformEngine.java b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/LibreOfficeTransformEngine.java index 4d22132d..53ef2901 100644 --- a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/LibreOfficeTransformEngine.java +++ b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/LibreOfficeTransformEngine.java @@ -69,8 +69,7 @@ public class LibreOfficeTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.doc", "quick.pdf", - MIMETYPE_WORD, MIMETYPE_PDF, Collections.emptyMap(), + return new ProbeTransform("quick.doc", MIMETYPE_WORD, MIMETYPE_PDF, Collections.emptyMap(), 11817, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20); } } diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/MiscTransformEngine.java b/engines/misc/src/main/java/org/alfresco/transform/misc/MiscTransformEngine.java index 9a379fff..64abc611 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/MiscTransformEngine.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/MiscTransformEngine.java @@ -73,8 +73,7 @@ public class MiscTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.html", "quick.txt", - MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, transformOptions, + return new ProbeTransform("quick.html", MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, transformOptions, 119, 30, 150, 1024, 60 * 2 + 1, 60 * 2); } } diff --git a/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformEngine.java b/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformEngine.java index 9e3b4a43..d74f4b72 100644 --- a/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformEngine.java +++ b/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformEngine.java @@ -67,8 +67,7 @@ public class PdfRendererTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.pdf", "quick.png", - MIMETYPE_PDF, MIMETYPE_IMAGE_PNG, Collections.emptyMap(), + return new ProbeTransform("quick.pdf", MIMETYPE_PDF, MIMETYPE_IMAGE_PNG, Collections.emptyMap(), 7455, 1024, 150, 10240, 60 * 20 + 1, 60 * 15 - 15); } } \ No newline at end of file diff --git a/engines/tika/src/main/java/org/alfresco/transform/tika/TikaTransformEngine.java b/engines/tika/src/main/java/org/alfresco/transform/tika/TikaTransformEngine.java index 6c35fb12..70b17b9b 100644 --- a/engines/tika/src/main/java/org/alfresco/transform/tika/TikaTransformEngine.java +++ b/engines/tika/src/main/java/org/alfresco/transform/tika/TikaTransformEngine.java @@ -68,8 +68,7 @@ public class TikaTransformEngine implements TransformEngine @Override public ProbeTransform getProbeTransform() { - return new ProbeTransform("quick.pdf", "quick.txt", - MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, Collections.emptyMap(), + return new ProbeTransform("quick.pdf", MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, Collections.emptyMap(), 60, 16, 400, 10240, 60 * 30 + 1, 60 * 15 + 20); } } diff --git a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java index 47487691..88bb07fa 100644 --- a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java +++ b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java @@ -87,9 +87,9 @@ class TransformRegistryHelper renditionName = null; } - final List cachedTransformList = - renditionName == null ? null : - data.retrieveCached(renditionName, sourceMimetype); + final List cachedTransformList = renditionName == null + ? null + : data.retrieveCached(renditionName, sourceMimetype); if (cachedTransformList != null) { return cachedTransformList; diff --git a/pom.xml b/pom.xml index b828f5d6..ea02a4cd 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ engines/pdfrenderer engines/tika engines/aio + engines/example deprecated/alfresco-transformer-base @@ -58,6 +59,7 @@ model engines/base + engines/example deprecated/alfresco-transformer-base @@ -110,6 +112,14 @@ engines/aio + + example + + model + engines/base + engines/example + +