Files
alfresco-transform-core/docs/transform-specific-code.md
2022-08-17 13:33:16 +01:00

140 lines
5.6 KiB
Markdown

## Transform specific code
To create a new t-engine an author uses a base t-engine (a Spring Boot
application) and implements the following interfaces. An implementation of
the `CustomTransformer` provides the actual transformation code and the
implementation of the `TransformEngine` says what it is capable of
transforming. The `TransformConfig` is normally read from a json file on the
classpath. Multiple `CustomTransformer` implementations may be in a singe
t-engine. As a result the author can concentrate on the code that transforms
one format to another without really worrying about all the plumbing.
Typically, the transform specific code uses a 3rd party library or an
external executable which needs to be added to the Docker image.
~~~
package org.alfresco.transform;
import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transformer.probes.ProbeTestTransform;
import java.util.Set;
/**
* Interface to be implemented by transform specific code. Provides information
* about the t-engine as a whole. So that it is automatically picked up, it must
* exist in a package under {@code org.alfresco.transform} and have the Spring
* {@code @Component} annotation.
*/
public interface TransformEngine
{
/**
* @return the name of the t-engine. The t-router reads config from t-engines
* in name order.
*/
String getTransformEngineName();
/**
* @return a definition of what the t-engine supports. Normally read from a json
* Resource on the classpath.
*/
TransformConfig getTransformConfig();
/**
* @return a ProbeTestTransform (will do a quick transform) for k8 liveness and
* readiness probes.
*/
ProbeTransform getProbeTransform();
}
~~~
implementations of the following interface provide the actual transform code.
~~~
package org.alfresco.transform;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
/**
* Interface to be implemented by transform specific code. The
* {@code transformerName} should match the transformerName in the
* {@link TransformConfig} returned by the {@link TransformEngine}. So that it is
* automatically picked up, it must exist in a package under
* {@code org.alfresco.transform} and have the Spring {@code @Component} annotation.
*
* Implementations may also use the {@link TransformManager} if they wish to
* interact with the base t-engine.
*/
public interface CustomTransformer
{
String getTransformerName();
void transform(String sourceMimetype, InputStream inputStream,
String targetMimetype, OutputStream outputStream,
Map<String, String> transformOptions,
TransformManager transformManager) throws Exception;
}
~~~
The implementation of the following interface is provided by the t-base,
allows the `CustomTransformer` to interact with the base t-engine. The
creation of Files is discouraged as it is better not to leave files on disk.
~~~
package org.alfresco.transform.base;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
/**
* Allows {@link CustomTransformer} implementations to interact with the base
* t-engine.
*/
public interface TransformManager
{
/**
* Allows a CustomTransformer to use a local source File rather than the
* supplied InputStream. To avoid creating extra files, if a File has already
* been created by the base t-engine, it is returned.
*/
File createSourceFile();
/**
* Allows a CustomTransformer to use a local target File rather than the
* supplied OutputStream. To avoid creating extra files, if a File has already
* been created by the base t-engine, it is returned.
*/
File createTargetFile();
/**
* Allows a single transform request to have multiple transform responses. For
* example, images from a video at different time offsets or different pages of
* a document. Following a call to this method a transform response is made with
* the data sent to the current {@code OutputStream}. If this method has been
* called, there will not be another response when {@link CustomTransformer#
* transform(String, InputStream, String, OutputStream, Map, TransformManager)}
* returns and any data written to the final {@code OutputStream} will be
* ignored.
* @param index returned with the response, so that the fragment may be
* distinguished from other responses. Renditions use the index
* as an offset into elements. A {@code null} value indicates
* that there is no more output and any data sent to the current
* {@code outputStream} will be ignored.
* @param finished indicates this is the final fragment. {@code False} indicates
* that it is expected there will be more fragments. There need
* not be a call with this parameter set to {@code true}.
* @return a new {@code OutputStream} for the next fragment. A {@code null} will
* be returned if {@code index} was {@code null} or {@code
* finished} was {@code true}.
* @throws TransformException if a synchronous (http) request has been made as
* this only works with requests on queues, or the first call to
* this method indicated there was no output, or another call is
* made after it has been indicated that there should be no more
* fragments.
* @throws IOException if there was a problem sending the response.
OutputStream respondWithFragment(Integer index);
}
~~~