Promena Sample
All Promena images use mirror-jdk
transformer and promena-connector-http
connector module. You can perform a transformation in any sample using Promena#IntelliJ plugin on mirror-jdk/example
(it contains the examples in Java and Kotlin).
Deployment
Manual
This deployment shows how to run Promena in a cluster without Kubernetes
or OpenShift
. It means that you have to specify akka.cluster.seed-nodes
property manually (see Joining to Seed Nodes for more details). The seed node has to start first. It is done by waiting for the seed node promena-connector-http
connector module to be run by the worker nodes. It is only for demonstration purposes and shouldn't be used in production.
This sample uses promena-file-http
Promena image with promena-connector-http
connector module. It also demonstrates how to set promena-communication-file
communication module - communication.file.internal.directory.path
(see docker-compose.yml
) property indicates the same location in the volume that is mounted on all Promena nodes.
Use start.bin
to build Promena image and start containers, logs.bin
to see logs, stop.bin
to stop containers and clean.bin
to delete volumes.
It isn't the recommended way to deploy Promena.
Kubernetes & OpenShift
Generally, they have common elements. The only difference is that Kubernetes uses Deployment
and OpenShift uses DeploymentConfig
.
Unlike Manual, you don't have to specify seed nodes manually. This kind of deployment uses promena-cluster-management-kubernetes
module - it chooses leader dynamically and you don't have to worry.
These samples use promena-file-http-kubernetes
Promena image with promena-connector-http
connector module and promena-cluster-management-kubernetes
module. It also demonstrates how to set promena-communication-file
communication module but it is based on the local volume. If your cluster contains more than one node you have to provide a volume that is accessible on all nodes.
Kubernetes
kubectl apply -f namespace.yaml
kubectl apply -f cluster-role.yaml
kubectl apply -f cluster-role-binding.yaml
kubectl apply -f persistent-volume.yaml
kubectl apply -f persistent-volume-claim.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
OpenShift
oc apply -f namespace.yaml
oc apply -f cluster-role.yaml
oc apply -f cluster-role-binding.yaml
oc apply -f persistent-volume.yaml
oc apply -f persistent-volume-claim.yaml
oc apply -f deployment-config.yaml
oc apply -f service.yaml
Transformer
You can generate the template of a transformer using archetype (see Promena - Development Guide for more details).
appender-jdk-general
demonstrates the common case when you don't want to deal with specific communication implementation. See Processor
.
appender-jdk-specific
demonstrates how to deal with specific communication. For example, for promena-communication-file
communication module, it operates directly on the file. See Processor
.
Module
You can generate the template of a module using archetype (see Promena - Development Guide for more details).
Promena-cluster-listener
demonstrates 2 cases:
- How to subscribe Cluster Events -
MemberClusterListener
- How to use Cluster Metrics Extension -
MetricsClusterListener
,module-promena-cluster-listener.properties
Alfresco
These samples demonstrate how to integrate Alfresco with Promena. This folder also contains alfresco-jvm-console-mirror-jdk-example
that allows you to perform a transformation using Promena using Alfresco dynamically. It requires Alfresco JVM Console - IntelliJ plugin.
Visit Promena Alfresco for more details about modules.
Use start.bin
to build Promena image and start containers, logs.bin
to see logs, stop.bin
to stop containers and clean.bin
to delete volumes.
Communication
Both Promena images in these samples use promena-connector-http
connector module. Alfresco Content Services is the client side and it has to use alfresco-promena-connector-http
module to integrate with Promena HTTP connector (with the following properties in alfresco-global.properties
):
promena.connector.http.host=promena
promena.connector.http.port=8080
Alfresco Content Services also uses alfresco-promena-core
module that is the crucial module.
Memory
In order to use promena-communication-memory
communication module, you have to specify in alfresco-global.properties
:
promena.core.communication.external.id=memory
No additional properties in Promena are required.
File
In order to use promena-communication-file
communication module, you have to specify in alfresco-global.properties
:
promena.core.communication.external.id=file
promena.core.communication.external.file.directory.path=/tmp/promena-communication
Property promena.core.communication.external.file.directory.path
and communication.file.internal.directory.path
(see docker-compose.yml
) have to indicate the same location (it was described in Manual section).
Connector
Sample http-activemq
demonstrates how to use alfresco-promena-connector-http
module and alfresco-promena-connector-activemq
module simultaneously.
It also uses promena-communication-memory
communication module.
Integration with HTTP Promena connector was described in one of the previous sections. Integration with ActiveMQ Promena connector requires to specify the following property in alfresco-global.properties
:
messaging.broker.url=failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true
You also have to specify broker url in Promena (see docker-compose.yml
):
spring.activemq.broker-url=failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true
Each connector provides its own PromenaTransformationExecutor
implementation so if you want to inject a bean, you have to specify one of them.
Transformer & Rendition
There are two samples - the first one for Alfresco Content Services 6.1.2 (transformer-rendition-predefined_6.1.2
module) and the second one for Alfresco Content Services 6.2.0 (transformer-rendition-predefined_6.2.0
module). They do exactly the same thing - replace the standard Alfresco Transformer and Rendition system with the equivalent in Promena environment. This functionality is provided by alfresco-promena-transformer-rendition_6.1.2
and alfresco-promena-transformer-rendition_6.2.0
modules.
Additionally, they use alfresco-promena-predefined-rendition
module to provide:
- Rendition -
avatar32
,avatar
,imgpreview
,doclib
,medium
andpdf
(see Promena Alfresco - Development Guide#Definition/Rendition to find out how to write own rendition) - Content Transformer - conversion between various document formats (see Promena Alfresco - Development Guide#Definition/Content Transformer to find out how to write own content transformer)
If you want to check how it works, just upload a document to the repository using Alfresco Share (for renditions) and wait for Solr to index documents (content transformer).
These samples also demonstrate how to increase concurrency level within a single instance. On Alfresco Content Services side, you have to increase the concurrency level of a connector. In case of ActiveMQ, set in alfresco-global.properties
:
promena.connector.activemq.spring.jms.listener.concurrency=4
promena.connector.activemq.spring.jms.listener.max-concurrency=4
On Promena side, increase the number of actors of transformers (see docker-compose.yml
):
transformer.pl.beone.promena.transformer.converter.libreoffice.LibreOfficeConverterTransformer.actors=4
transformer.pl.beone.promena.transformer.converter.imagemagick.ImageMagickConverterTransformer.actors=4
They use promena-file-activemq-transformer-rendition-predefined
Promena image with promena-connector-activemq
connector module and promena-communication-file
communication module that were described in one of the previous sections, converter-libreoffice
, converter-imagemagick
and converter-pdfbox
transformers.
Image
Folder image
contains several examples of projects that provide Promena Docker image for this guide. Open their pom.xml
files to see some inclusions of modules and transformers.
Constructing transformation
A transformation can be constructed in two ways:
- Without any dependency:
fun transformation(): Transformation =
singleTransformation("mirror", TEXT_PLAIN, emptyParameters() + ("sleep" to 2000)) next
singleTransformation("mirror", TEXT_PLAIN, emptyParameters() + ("sleep" to 3000))
- With
application-model
dependency of the specific transformer (less loose coupling):
fun transformation(): Transformation =
jdkMirrorTransformation(TEXT_PLAIN, jdkMirrorParameters(sleep = 2000)) next
jdkMirrorTransformation(TEXT_PLAIN, jdkMirrorParameters(sleep = 3000))