Intershop Enfinity pipelet hot deployment

18.06.2012.

This blog entry describes a process of deploying pipelet code directly to a target server. During the “hot deployment” of pipelets the application server doesn’t need to be restarted, which means a Intershop based service is available to customers during the time of deployment and changes are visible as soon as hot-deploy process is finished.

Pipelets processing

In the nutshell, pipelets are the building blocks used to implement pipelines. They are java classes that contain specific functionality. Although Intershop comes with large number of pipelets, typical sales channel will contain siginificant number of custom made pipelets that implement specific business functions. That enables breaking up of the business object layer into small, reusable units or building blocks. Each of those units or building blocks models a separate business function.

The interaction between pipelets is modeled by pipelines. Pipelets exchange data with other pipelets via the pipeline dictionary to read/write dynamic data produced during the pipeline execution. Each pipelet can be used once or multiple times by same or different pipelines.

Each pipelet consists of the three distinct files on the file system:

  • The .java class – containing program code
  • The .xml descriptor file containing pipelet parameters
  • The .xml descriptor file containing localizable pipelet descriptions.

The pipelet’s java classes are the core of the pipelet functionality while descriptor files tell the pipeline processor how to prepare parameters for a pipelet and what output to expect. Unlike pipelines and templates (which as text resources), pipelets are not reloaded separately on the server, but during the special case of pipelines reloading. Pipelets will or won’t be reloaded depending on the source checking parameter for the pipeline code in appserver.properties, located on a file system at the following path:

<eserver>/share/system/config/cluster

The property holding information about the automatic pipeline reload is called:

intershop.pipelines.CheckSource

In case that source checking is enabled, all pipelets used in the modified pipeline will be reloaded with it. For this case it is enough to copy the three required files to deploy the changes on the production system. However, since the source checking is typically not enabled on production environments (due to performance reasons), and the process of hot-deploying pipelines doesn’t reload pipelets, only way of hot-deploying new pipelets code is by explicitly invoking pipeline reload through Enfinity API.

Deployment procedure

The first step of deploying the pipelets is to copy the required files from a source to the target file system. Both .class and .xml files are usually located in the following path on the file system:

<cartridges>/target/<cartridge>/release/lib/<package path>

Once the files are copied to the target server, a pipeline that contains the pipelet has to be manually reloaded. The first step is to instantiate a domain manager and a pipeline manager, which will be used to fetch the wanted pipeline. The following code is used:

DomainMgr dmgr = (DomainMgr) NamingMgr.getInstance().lookupManager(DomainMgr.REGISTRY_NAME);

PipelineMgrImpl pmgr = (PipelineMgrImpl) NamingMgr.getInstance().lookupManager(PipelineMgr.REGISTRY_NAME);

Once the managers have been instantiated, a method lookupPipeline(Domain arg0, String arg1, String arg2) is used to fetch the wanted pipeline:

Pipeline pipeline = pmgr.lookupPipeline(dmgr.getDomainByName(domainName), cartridgeName, pipelineName);

To fetch the wanted pipeline, a domain name, cartridge name and pipeline name of the wanted pipeline have to be supported. Last step is to invoke a reloadPipeline(DPipelineIdentifier identifier) method on the pipeline manager object:

pmgr.reloadPipeline(pipeline.getPipelineIdentifier);

This method will reload the pipeline and all the pipelets contained in it.

A final code example would look like this:

DomainMgr dmgr = (DomainMgr) NamingMgr.getInstance().lookupManager(DomainMgr.REGISTRY_NAME);       
PipelineMgrImpl pmgr = (PipelineMgrImpl) NamingMgr.getInstance().lookupManager(PipelineMgr.REGISTRY_NAME);
Pipeline pipeline = pmgr.lookupPipeline(dmgr.getDomainByName(domainName), cartridgeName, pipelineName);
if (null != pipeline) {
    pmgr.reloadPipeline(pipeline.getPipelineIdentifier());
}

In the code snippet the variables domainName, cartridgeName and pipelineName are the input variables. In other words, all that is needed to reload the pipeline and its pipelets is the name of the domain and cartridge in which that pipeline is located and a name of the pipeline that needs to be reloaded. This code can be used to make a new pipelet, used for reloading a single pipeline.

Once the files have been copied to the target system and a pipelet containing reload code has been invoked a targeted pipeline, the new code will be reloaded and new logic will be functional without the need for restarting the application server and disrupting the service to customers.

NOTES:

Special care has to be taken in case of multiple nodes to invoke reload on each node. (For more information in general article about hot deployment on Intershop platform).

In case a pipelet is used by more than one pipeline, a special care has to be taken to reload each of the pipelines that are using it. If a certain pipeline is not reloaded it will use the old pipelet code while reloaded pipelines will use the new code, which can lead to business logic inconsistency.