WCM Deployment Engine

Document created by resplin Employee on Jun 6, 2015Last modified by alfresco-archivist on Aug 31, 2016
Version 2Show Document
  • View in full screen mode

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



{{AVMWarning}}
AVM
Back to WCM Developer Documentation

Please note that this page describes functionality that was added in Alfresco v3.2.  For earlier versions of Alfresco, FSR callbacks can be used to approximate the mechanism described here.

The WCM Deployment Engine is responsible for receiving deployments from an Alfresco WCM authoring environment and delegating the contents of the deployment to the appropriate deployment receiver target.   There are two implementations of the WCM Deployment engine,  the standalone deployment engine which is a small lightweight framework that is independent of the alfresco repository and a deployment engine that is is a subsystem within the Alfresco repository.      


Standalone Deployment Engine


The standalone deployment engine receives deployments from an Alfresco WCM Authoring environment.  By default, out of the box, it is configured with a single deployment target which deploys content to a flat file system.

Additional deployment targets, possibly written by yourself, can be registered with the deployment engine to cater for special requirements.    The deployment engine manages communication with the Alfresco WCM Authoring environment so you just need to write a small amount of code to do your deployment.


Installation


The standalone deployment engine is installed via the 'Alfresco Deployment Installer' and out of the box is configured with a single  File System Deployment Target.


Configuration


Configuration via a 'deployment.properties' file and the 'application-context.xml' file which are located in the installation directory (for example on windows c:/Alfresco/Deployment or on linux /opt/alfresco/deployment).    Deployment target definitions and plug in definitions go into the deployment directory.

The 'Target Name' field you use in the configure deployment receiver should match the deployment.filesystem.default.name property value in alfresco-global.properties

deployment.properties

The deployment.properties file contains simple configuration for the standalone deployment receiver.   The file is created by the deployment project deployer and can be edited by using a text editor.   After making changes to deployment.properties the deployment engine needs to be restarted.



; filesystem receiver configuration
deployment.filesystem.datadir=depdata
deployment.filesystem.logdir=deplog
deployment.filesystem.metadatadir=depmetadata
deployment.filesystem.autofix=true
deployment.filesystem.errorOnOverwrite=false

; default filesystem target configuration
deployment.filesystem.default.rootdir=target
deployment.filesystem.default.name=default

; Deployment Engine configuration
deployment.rmi.port=44100
deployment.rmi.service.port=44101

; Stand alone deployment server specific properties
deployment.user=admin
deployment.password=admin



application-context.xml

Here is the sample application-context.xml file showing how the deployment.properties, the context files and the targets are read.



<beans>
     <bean id='properties'
          class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'>
        <property name='ignoreUnresolvablePlaceholders'>
            <value>true</value>
        </property>
        <property name='locations'>
            <list>
                <value>classpath:deployment.properties</value>
            </list>
        </property>
    </bean>
   
    <import resource='classpath*:deployment/*-context.xml' />  
    <import resource='classpath*:deployment/*-target.xml' />
   
</beans>



log

The standalone deployment engine uses log4j for problem determination, logging for the deployment engine are placed in this directory.

deployment directory

Your spring definitions of the deployment targets are read from this directory.   All files matching the pattern deployment/*-context.xml and deployment/*-target.xml are loaded by the deployment engine.

Targets are loaded after the context files.    So each target has all spring beans available to it when it is defined.


Startup


The Standalone WCM Deployment Engine is implemented as a set of java libraries and is inherently multi-platform.  
To simplify the command line, Bourne shell scripts are provided for UNIX and Windows batch files are provided for Windows.

run the deploy_start script to start the standalone deployment engine.

run the deploy_stop script to stop the standalone deployment engine.


On Windows


If you have used the deployment installer to install the Standalone Deployment Engine then there will be Start Menu actions available to start or stop the Standalone Deployment Engine from the Start Menu.   These are simply calling the deploy_start.bat and deploy_stop.bat scripts.

You can also call the deploy_start and deploy_stop scripts from a command prompt.

It is also possible to install the Standalone Deployment Engine as a Windows service which can automatically start when Windows starts.


Multi NIC Receivers (Especially Linux)


When deploying to a deployment engine running on a multi-NIC system it may be necessary to bind the RMI registry to a particular IP address. To do this you must add the following to the java command in deploy_start.sh/.bat:

-Djava.rmi.server.hostname=x.x.x.x

Where x.x.x.x is the IP address assigned to the NIC you want to bind to.

Look here for more information.

Thanks to Rakesh Kalra at Care.com


WCM Deployment Subsystem


Installation


The web delivery run time is included within the alfresco repository.   It is contained by the 'wdr_deployment_receiver' subsystem which can be optionally added to an alfresco repository through the wcm bootstrap.    The wcm bootstrap process starts the built in deployment engine, otherwise it is not defined or active. 

Make sure you have an up to date version of wcm-bootstrap-context.xml.

File System Deployment Target

AVM Deployment Target

DM Deployment Target


Configuration


Deployment targets are defined in spring configuration files with a name ending with 'target.xml'
There is a special location for you to add your deployment target definitions.   
<extension root>/alfresco/extension/deployment
for example c:\tomcat\shared\classes\alfresco\extension\deployment.

Please note : You should not place files into the WEB-INF folders which are private to alfresco and will be over-written on alfresco upgrade.

Property configuration values are made in alfresco-global.properties.

A sample 'filesystem' target is provided in  C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\alfresco\deployment\filesystem-target-sample.xml

If you want to enable this target you would copy the file to the extension/deployment directory and rename it to 'filesystem-target.xml'   You can then configure where the filesystem target stores its data by configuring 'deployment.filesystem.default.rootdir' and 'deployment.filesystem.default.metadatadir' in alfresco-global.properties



If you want more than one filesystem target you would copy filesystem-target-sample.xml to a name name of your choosing, in this case 'lemon-target.xml'.

And change the following properties
deployment.filesystem.lemon.name
deployment.filesystem.lemon.rootdir
deployment.filesystem.lemon.metadatadir




Reinitialise


Enterprise editions of Alfresco can restart subsystems through the JMX console.   So its not necessary to re-start alfresco to change the settings of the deployment engine.


Authentication


The standalone deployment engine requires authentication to control who can shut it down.   The built in deployment engine is managed as an alfresco subsystem so does not need this configuration.

In addition, each deployment target can require authentication for who is allowed to use it.  

An adapter interface, org.alfresco.deployment.impl.server.DeploymentReceiverAuthenticator is used to connect the deployment engine with an authentication system.   

Out of the box two authentication implementations are provided.   


  • org.alfresco.deployment.impl.server.DeploymentReceiverAuthenticatorSimple which is a simple name/password matcher
  • org.alfresco.deployment.impl.DeploymentReceiverAuthenticatorAuthenticationService which uses Alfresco's authentication service.   This Authentication service is only available inside an Alfresco repository.

You can also plug in your own authentication adapters.


Deployment Service Configuration


WCM deployment service


The WCM deployment service is the client (sending) side of WCM deployment.

Follow the general rules of Repository Configuration

So if you want to change the deployment service.  Put your own settings in <tomcatHome>/shared/classes/extension

deployment-service-context.xml


number of send threads


To assist with cases where files are being deployed over a network with high latency the deployment client is multi-threaded and sends several files at once.   By default 5 sends are done in parallel.  

From 3.2 Enterprise onwards you can set the following property in alfresco-global.properties



deployment.service.numberOfSendingThreads



To change the settings via spring configuration, change the number of sends in parallel change the numberOfSendingThreads property.

deployment-service-context.xml

Example reducing the number of threads to 4.



  <bean id='deploymentService' class='org.alfresco.repo.deploy.DeploymentServiceImpl' lazy-init='default' autowire='default' dependency-check='default'>
    <property name='avmService'>
      <ref bean='indexingAVMService' />
    </property>
    <property name='numberOfSendingThreads'>
      <value>4</value>
    </property>
    <property name='deploymentReceiverTransportAdapters'>
     <map>
      <entry key='default'>
       <ref bean='rmiFSRAdapter' />
      </entry>
     </map>
    </property>
  </bean>

number of deployments in parallel


Deployment is controlled through the Action Service which controls how many deployments happen in parallel.  If you need to deploy to many servers then you may need to increase the number of deployments in parallel.   But if you run out of processing power or memory then you may need to reduce this setting.

From 3.2 Enterprise onwards you can set the following properties in alfresco-global.properties



deployment.service.corePoolSize=2
deployment.service.maximumPoolSize=3

To change the settings via spring configuration.
Extract from action-services-context.xml showing configuration of the deployment pool.



<bean id='deploymentAsyncThreadPool' class='org.alfresco.util.ThreadPoolExecutorFactoryBean' lazy-init='default' autowire='default' dependency-check='default'>
- <property name='poolName'>
  <value>deploymentAsyncAction</value>
  </property>
- <property name='corePoolSize'>
  <value>2</value>
  </property>
- <property name='maximumPoolSize'>
  <value>3</value>
  </property>
</bean>

Payload transformation


The data streams out of Alfresco and into the WCM Deployment Engine can be transformed by content transformation.

To support use/cases such as


  • file compression for slow networks.
  • encryption for sensitive data.
  • character code page conversion.
  • transformation of content as it is deployed.

Users wishing to build their own transformers will implement the interfaces org.alfresco.deployment.DeploymentTransportInputFilter and org.alfresco.deployment.DeploymentTransportOutputFilter  

Three sample transformers are provided in the package org.alfresco.deployment.transformers. You can use the existing three transformers as a model for writing your own payload transformers.


CompressionTransformer : compresses the outgoing stream and decompresses the incomming stream.
SampleEncryptionTransformer : encrypts the outgoing stream and decrypts the incomming stream.
TestCompressionTransformer : does nothing but enables testing. (NOTE: Appears to be missing as of r19681.)

On the Alfresco Server, content transformers are defined in the spring configuration file 'deployment-service-context.xml'
On the Deployment Engine, transformers are defined in spring configuration file 'deployment-receiver-context.xml'.

The content transformers may have initialisation parameters.

Here is an extract from deployment-service-context.xml showing the configuration of two transformers.  The first transformer has two initialisation properties.



     <bean id='deploymentEncryptor' class='org.alfresco.deployment.transformers.SampleEncryptionTransformer'>
        <property name='password'>
          <value>Alfresco</value>
        </property>
        <property name='cipherName'>
          <value>PBEWithMD5AndDES</value>
        </property>
     </bean> 
    
     <bean id='deploymentCompressor' class='org.alfresco.deployment.transformers.CompressionTransformer'>
     </bean> 

Once the content transformers have been defined in 'deployment-service-content.xml' or 'deployment-receiver-context.xml' then they need to be plugged into the transport adapter.


Transports


The Alfresco deployment service supports the configuration of multiple transport adapters to enable connection to remote deployment engines using different network protocols.

Each transport adapter provide an implementation of the Transport protocol and is provided with an optional list of payload transformers.    Transport adapters implement the interface DeploymentReceiverTransportAdapter which defines a single method to obtain an instance of DeploymentReceiverTransport.

Transport adapters are configured on the Alfresco WCM Authoring Server in the spring configuration file 'deployment-service-context.xml'.
In the deployment engine transformers are configured in the 'deployment-receiver-context.xml' file.   An instance of Alfresco server may support many different transports but each deployment engine only exposes a single transport.

By default only the 'default' transport is defined which communicates over the Java RMI protocol. 

Here is an extract from deployment-service-context.xml showing the configuration of two transformer adapters.




     <bean id='rmiFSRAdapter' class='org.alfresco.deployment.impl.client.DeploymentReceiverTransportAdapterRMI'>
     </bean>
    
     <bean id='encryptedRMIFSRAdapter' class='org.alfresco.deployment.impl.client.DeploymentReceiverTransportAdapterRMI'>
          <property name='transformers'>
            <list>
             <ref bean='deploymentEncryptor'></ref>
            </list>
        </property>
     </bean>



The final piece of configuration is in the configuration of the deployment server, which is passed a list of transport adapters.

The name 'default' is reserved to mean the communication method used by older versions of Alfresco.  You are free to name your own adapters.

Here is an extract from deployment-service-context.xml showing the configuration of two transformer adapters.

    <bean id='deploymentService' class='org.alfresco.repo.deploy.DeploymentServiceImpl'>
       <property name='avmService'>
           <ref bean='indexingAVMService'/>
       </property>
      
       <property name='deploymentReceiverTransportAdapters'>
           <map>
              <entry key='default'>
                <ref bean='rmiFSRAdapter'></ref>
              </entry>
              <entry key='encrypted RMI'>
                <ref bean='encryptedRMIFSRAdapter'></ref>
              </entry>
           </map>
       </property>
    </bean>



Here is an extract from deployment-receiver-context.xml showing the configuration of the transport adapter to support the encrypted RMI defined above.


  
    <bean id='deploymentReceiverEngine'
     class='org.alfresco.deployment.impl.server.DeploymentReceiverEngineImpl'
        init-method='init'>
       
        <property name='pollDelay'><value>5000</value></property>
       
        <property name='commandQueue'><ref bean='deploymentReceiverCommandQueue' /></property>
       
        <property name='readerManagement'>
         <ref bean='deploymentReaderManagement' />
        </property>
       
        <property name='authenticator'>
         <bean class='org.alfresco.deployment.impl.server.DeploymentReceiverAuthenticatorSimple'>
             <property name='user'><value>${deployment.user}</value></property>
               <property name='password'><value>${deployment.password}</value></property>
         </bean>
        </property>
       
        <property name='transformers'>
          <list>
            <ref bean='deploymentEncryptor'/>
          </list>
        </property>
       
        <property name='housekeepers'>
         <set>
         <ref bean='commandQueueHousekeeper'/>
         </set>
        </property>
    </bean>



Once the transport adapters have been defined then the 'Edit Web Project Settings' UI action will enable the transport adapter to be selected.

Transport Name 3_2.GIF


Targets


A deployment target is the destination for a wcm deployment.    You can implement your own targets or use the ones built into the alfresco repository,  the File System Deployment Target and the AVM Deployment Target

If you have written your own target.   Add the implementation of your target to the alfresco classpath, you can have a separate JAR file, look at wdr-deployment as a template.

Add a spring configuration file to the classpath.  The deployment engine reads files called *-target.xml rather than the usual *-context.xml.    


  • The standalone server picks up configuration files from
    • deployment/*-target.xml
  • The built in deployment engine picks up files from
    • alfresco/deployment/*-target.xml.
    • alfresco/extension/deployment/*-target.xml.

Each target configuration file needs to register the target with the deploymentReceiverEngine bean which is the WCM deployment engine.  

A utility class DeploymentTargetRegistrationBean takes the name of your target, the deployment target registry and the definition of your bean and goes ahead and registers your target.   If you try to register a target with the same name more than once then the last definition wins.

Here's an example of registering a target called sampleTarget which is a File System Deployment Target




<bean
  class='org.alfresco.deployment.impl.server.DeploymentTargetRegistrationBean'
  init-method='register'>

 
  <property name='name'>
   <value>sampleTarget</value>
  </property>
 
 
  <property name='registry'>
   <ref bean='deploymentReceiverEngine' />
  </property>
 
  <property name='target'>
 
  
   <bean
    class='org.alfresco.deployment.impl.fsr.FileSystemDeploymentTarget'
    init-method='init'>
   
   
    <property name='rootDirectory'>
     <value>sampleTarget</value>
    </property>
   
   
          <property name='metaDataDirectory'>
              <value>${deployment.filesystem.metadatadir}/sampleTarget</value>
          </property>
    <property name='autoFix'>
     <value>${deployment.filesystem.autofix}</value>
    </property>
    <property name='postCommit'>
     <list>
      <bean class='org.alfresco.deployment.SampleRunnable' />
     </list>
    </property>
    <property name='fileSystemReceiverService'>
     <ref bean='fileSystemReceiverService' />
    </property>
    <property name='name'><value>sampleTarget</value></property>
    <property name='authenticator'>
     <bean
      class='org.alfresco.deployment.impl.server.DeploymentReceiverAuthenticatorSimple'>
      <property name='user'>
       <value>Giles</value>
      </property>
      <property name='password'>
       <value>Watcher</value>
      </property>
     </bean>
    </property>
   </bean>
  </property>
</bean>


Implementing your own targets


The deployment engine has been built to make it easier to write new deployment targets, for example many people have been trying with mixed success to deploy to databases and other applications.   The deployment engine deals with communication with the alfresco authoring environment, you just need to implement your business logic.

Implementations must implement org.alfresco.deployment.DeploymentTarget.




Packaging the deployment engine to run over HTTP


HTTP is a well known protocol that is supported via a wide variety of web servers.

The deployment engine can be packaged as a WAR (Web Archive) file and then run by a java web server such as Jetty or Tomcat.

To run a deployment engine over http requires two configuration changes.  

a) In the Alfresco authoring server configuration define a transport adapter that uses spring http. 

b) On the Standalone Deployment Receiver or wcm_deployment subsystem expose the transport interface via spring http


Client Side configuration (Deployment Service)


Here is an extract from deployment-service-context.xml showing the configuration of the spring http adapter.  

    <bean id='springHttpFSRAdapter' class='org.alfresco.repo.deploy.DeploymentReceiverTransportAdapterSpringHTTP'>
       <property name='urlPattern'>
         <value>http://{0}:{1}/ASDR/deployment</value>
       </property>
    </bean>

The final piece of configuration on the Alfresco authoring server is to pass this adapter into the deployment service.



     <bean id='deploymentService' class='org.alfresco.repo.deploy.DeploymentServiceImpl'>
        <property name='avmService'>
            <ref bean='indexingAVMService'/>
        </property>
       
        <property name='deploymentReceiverTransportAdapters'>
            <map>
               <entry key='default'>
                 <ref bean='rmiFSRAdapter'></ref>
               </entry>
              
               <entry key='spring HTTP'>
                 <ref bean='springHttpFSRAdapter'></ref>
               </entry>
            </map>
        </property>
     </bean>

Server Side Configuration


To expose the Deployment Engine over http requires a web server which will receive the http messages and delegate the content to the Deployment Engine.

The following example illustrates how to package the Standalone Deployment Engine as a web archive (WAR) to be served by a Java servlet engine such as Tomcat or Jetty.

The files have been taken from an installed instance of the Community release of 3.2 standalone deployment receiver and re-packaged.



ASDR.war
    WEB-INF
        deployment-config.xml
        deployment-servlet.xml
        web.xml
 
    classes
        commons-logging.properties
        deployment.properties
        log4j.properties
       
        deployment
             default-target.xml
             deployment-context.xml
       
    lib
        alfresco-core-3.2.jar
        alfresco-deployment-3.2.jar
        alfresco-repository-3.2.jar
        commons-logging-1.1.jar
        jug-lgpl-2.0.0.jar
        spring-2.0.8.jar
        log4j-1.2.15.jar

web.xml


Here are the contents of the web.xml file.



<web-app>
   <display-name>FSR</display-name>
   
   <description>FSR in a HTTP Server</description>
  
   <distributable/>

    <servlet>
      <servlet-name>deployment</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>deployment</servlet-name>
      <url-pattern>/deployment</url-pattern>
   </servlet-mapping>

   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/deployment-config.xml</param-value>
   </context-param>
      
</web-app>



deployment-servlet.xml


Here are the contents of the deployment-servlet.xml file.



<beans xmlns='http://www.springframework.org/schema/beans'
       xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
       xmlns:p='http://www.springframework.org/schema/p'
       xmlns:util='http://www.springframework.org/schema/util'
       xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd'>


   <bean id='deploymentReceiverTransportHTTP'
         class='org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter'
         p:service-ref='deploymentReceiverEngine'>
      <property name='serviceInterface'>
         <value>org.alfresco.deployment.DeploymentReceiverTransport</value>
      </property>     
   </bean>

   <bean id='urlMapping'
          class='org.springframework.web.servlet.handler.SimpleUrlHandlerMapping'>
      <property name='mappings'>
         <props>
            <prop key='/deployment'>deploymentReceiverTransportHTTP</prop>
         </props>
      </property>
   </bean>

</beans>


deployment-config.xml


Here are the contents of the deployment-config.xml file.



<beans xmlns='http://www.springframework.org/schema/beans'
       xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
       xmlns:p='http://www.springframework.org/schema/p'
       xmlns:util='http://www.springframework.org/schema/util'
       xsi:schemaLocation='http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util-2.5.xsd'>


    <bean id='properties'
          class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'>
        <property name='ignoreUnresolvablePlaceholders'>
            <value>true</value>
        </property>
        <property name='locations'>
            <list>
                <value>classpath:deployment.properties</value>
            </list>
        </property>
    </bean> 


    <import resource='classpath*:deployment/*-context.xml' />  
    <import resource='classpath*:deployment/*-target.xml' />
   
</beans>


deployment-context.xml


Here is the content of the deployment-context.xml file



<beans xmlns='http://www.springframework.org/schema/beans'
       xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
       xmlns:p='http://www.springframework.org/schema/p'
       xmlns:util='http://www.springframework.org/schema/util'
       xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd'>


    <bean id='deploymentReceiverCommandQueue' class='org.alfresco.deployment.impl.server.DeploymentCommandQueueImpl' >
    </bean>

       
    <bean id='deploymentReaderManagement' class='org.alfresco.deployment.impl.server.ReaderManagementPool' >
    </bean>
   
    <bean id='fileSystemReceiverService' class='org.alfresco.deployment.impl.fsr.FileSystemReceiverServiceImpl'
          init-method='init'>
         
        <property name='errorOnOverwrite'><value>${deployment.filesystem.errorOnOverwrite}</value></property>
       
        <property name='dataDirectory'>
            <value>${deployment.filesystem.datadir}</value>
        </property>
       
        <property name='logDirectory'>
            <value>${deployment.filesystem.logdir}</value>
        </property>
       
        <property name='commandQueue'><ref bean='deploymentReceiverCommandQueue' /></property>
       
    </bean>
   
    <bean id='fileSystemReceiverHousekeeper' class='org.alfresco.deployment.impl.fsr.FileSystemReceiverHousekeeper'
     init-method='init'>
     <property name='fileSystemReceiverService'><ref bean='fileSystemReceiverService'/></property>
    </bean>
   
    <bean id='commandQueueHousekeeper' class='org.alfresco.deployment.impl.server.DeploymentCommandQueueHousekeeper'
     init-method='init'>
     <property name='commandQueue'><ref bean='deploymentReceiverCommandQueue' /></property>
    </bean>
   
    <bean id='deploymentReceiverEngine'
     class='org.alfresco.deployment.impl.server.DeploymentReceiverEngineImpl'
        init-method='init'>
       
        <property name='pollDelay'><value>5000</value></property>
       
        <property name='commandQueue'><ref bean='deploymentReceiverCommandQueue' /></property>
       
        <property name='readerManagement'>
         <ref bean='deploymentReaderManagement' />
        </property>
       
        <property name='authenticator'>
         <bean class='org.alfresco.deployment.impl.server.DeploymentReceiverAuthenticatorSimple'>
             <property name='user'><value>${deployment.user}</value></property>
               <property name='password'><value>${deployment.password}</value></property>
         </bean>
        </property>
       
       
        <property name='housekeepers'>
         <set>
         <ref bean='commandQueueHousekeeper'/>
         </set>
        </property>
    </bean>


</beans>





3.2

Attachments

Outcomes