alfresco-transform-core/deprecated/alfresco-transformer-base
Alan Davis babe26b0ba
HXENG-64 refactor ATS (#657)
Refactor to clean up packages in the t-model and to introduce a simpler to implement t-engine base.

The new t-engines (tika, imagemagick, libreoffice, pdfrenderer, misc, aio, aspose) and t-router may be used in combination with older components as the API between the content Repo and between components has not changed. As far as possible the same artifacts are created (the -boot projects no longer exist). They may be used with older ACS repo versions.

The main changes to look for are:
* The introduction of TransformEngine and CustomTransformer interfaces to be implemented.
* The removal in t-engines and t-router of the Controller, Application, test template page, Controller tests and application config, as this is all now done by the t-engine base package.
* The t-router now extends the t-engine base, which also reduced the amount of duplicate code.
* The t-engine base provides the test page, which includes drop downs of known transform options. The t-router is able to use pipeline and failover transformers. This was not possible to do previously as the router had no test UI.
* Resources including licenses are automatically included in the all-in-one t-engine, from the individual t-engines. They just need to be added as dependencies in the pom. 
* The ugly code in the all-in-one t-engine and misc t-engine to pick transformers has gone, as they are now just selected by the transformRegistry.
* The way t-engines respond to http or message queue transform requests has been combined (eliminates the similar but different code that existed before).
* The t-engine base now uses InputStream and OutputStream rather than Files by default. As a result it will be simpler to avoid writing content to a temporary location.
* A number of the Tika and Misc CustomTransforms no longer use Files.
* The original t-engine base still exists so customers can continue to create custom t-engines the way they have done previously. the project has just been moved into a folder called deprecated.
* The folder structure has changed. The long "alfresco-transform-..." names have given way to shorter easier to read and type names.
* The t-engine project structure now has a single project rather than two. 
* The previous config values still exist, but there are now a new set for config values for in files with names that don't misleadingly imply they only contain pipeline of routing information. 
* The concept of 'routing' has much less emphasis in class names as the code just uses the transformRegistry. 
* TransformerConfig may now be read as json or yaml. The restrictions about what could be specified in yaml has gone.
* T-engines and t-router may use transform config from files. Previously it was just the t-router.
* The POC code to do with graphs of possible routes has been removed.
* All master branch changes have been merged in.
* The concept of a single transform request which results in multiple responses (e.g. images from a video) has been added to the core processing of requests in the t-engine base.
* Many SonarCloud linter fixes.
2022-09-14 13:40:19 +01:00
..
2022-09-14 13:40:19 +01:00
2022-09-14 13:40:19 +01:00
2022-09-14 13:40:19 +01:00

Common code for Transform Engines (Deprecated)

This project holds the original code that was common to all ACS T-Engine transformers. Although it is still possible to create T-Engines this way, the newer engine/base project provides a simpler way to do it.

When upgrading to 3.0.0, you will find that a number of classes in the alfresco-transform-model have moved. See the alfresco-transform-model README

This project provides a base 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.

For more details on build a custom T-Engine, please refer to the current docs in ACS Packaging, including:

Overview

A transformer project is expected to provide the following files:

src/main/resources/templates/transformForm.html
src/main/java/org/alfresco/transformer/<TransformerName>Controller.java
src/main/java/org/alfresco/transformer/Application.java
  • transformForm.html - A simple test page using thymeleaf that gathers request parameters so they may be used to test the transformer.
<html xmlns:th="http://www.thymeleaf.org">
<body>
  <div>
    <h2>Test Transformation</h2>
    <form method="POST" enctype="multipart/form-data" action="/transform">
      <table>
        <tr><td><div style="text-align:right">file *</div></td><td><input type="file" name="file" /></td></tr>
        <tr><td><div style="text-align:right">file *</div></td><td><input type="file" name="file" /></td></tr>
        <tr><td><div style="text-align:right">sourceExtension *</div></td><td><input type="text" name="sourceExtension" value="" /></td></tr>
        <tr><td><div style="text-align:right">targetExtension *</div></td><td><input type="text" name="targetExtension" value="" /></td></tr>
        <tr><td><div style="text-align:right">sourceMimetype *</div></td><td><input type="text" name="sourceMimetype" value="" /></td></tr>
        <tr><td><div style="text-align:right">targetMimetype *</div></td><td><input type="text" name="targetMimetype" value="" /></td></tr>
        <tr><td><div style="text-align:right">abc:width</div></td><td><input type="text" name="width" value="" /></td></tr>
        <tr><td><div style="text-align:right">abc:height</div></td><td><input type="text" name="height" value="" /></td></tr>
        <tr><td><div style="text-align:right">timeout</div></td><td><input type="text" name="timeout" value="" /></td></tr>
        <tr><td></td><td><input type="submit" value="Transform" /></td></tr>
	  </table>
	</form>
  </div>
  <div>
    <a href="/log">Log entries</a>
  </div>
</body>
</html>
  • TransformerNameController.java - A Spring Boot Controller that extends TransformController to handle 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.
...
@Controller
public class TransformerNameController extends TransformController
{
    private static final Logger logger = LoggerFactory.getLogger(TransformerNameController.class);

    TransformerNameExecutor executor;

    @PostConstruct
    private void init()
    {
        executor = new TransformerNameExecutor();
    }

    @Override
    public String getTransformerName()
    {
        return "Transformer Name";
    }

    @Override
    public String version()
    {
        return commandExecutor.version();
    }

    @Override
    public ProbeTestTransform getProbeTestTransform()
    {
        // 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);
            }
        };
    }

    @Override
    public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
                                 Map<String, String> transformOptions, File sourceFile, File targetFile)
    {
        executor.transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
    }
}
  • TransformerNameExecuter.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<String, String> 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 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

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

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
}

Building and testing

The project can be built by running the Maven command:

mvn clean install

Artifacts

The artifacts can be obtained by:

<dependency>
  <groupId>org.alfresco</groupId>
  <artifactId>alfresco-transformer-base</artifactId>
  <version>1.0</version>
</dependency>

and the Alfresco Maven repository:

<repository>
  <id>alfresco-maven-repo</id>
  <url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
</repository>

The build plan is available in TravisCI.

Contributing guide

Please use this guide to make a contribution to the project.