Create Separate Distributions for the Authoring and Delivery Applications

Introduction

Goal

Create separate distributions for the authoring and delivery application so they can be deployed in separate containers.

Background

Typically Bloomreach Experience Manager's authoring (cms) and delivery (site) applications are deployed together on the same application server. However there are use cases where deploying the authoring and delivery applications separately on different application servers is preferable. In these cases the delivery application is deployed without the authoring application, therefore it cannot access the platform hosted by the latter.

The solution is to create a Maven WAR module containing all the dependencies of the platform and deploy it together with the delivery application on those delivery-only servers. The platform WAR will provide for access from the delivery application to the underlying storage repository.

This page describes how to configure the platform module and create two separate distributions that can be deployed on different application servers as shown in the following diagram:

For Enterprise projects also see Separate Distributions for Enterprise.

Create the Platform Module

To set up Bloomreach Experience Manager for deployment using a separate platform web application, follow the steps below.

Create a new Maven module in your project that will produce the platform.war. Don't forget to add it to the list of modules in the primary POM.

A sample pom.xml for your new module could look like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>myproject</artifactId>
    <groupId>com.example</groupId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <artifactId>platform</artifactId>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>org.onehippo.cms7</groupId>
      <artifactId>hippo-package-platform-dependencies</artifactId>
      <type>pom</type>
    </dependency>
  </dependencies>

  <build>
    <finalName>platform</finalName>
    <resources>
       <resource>
         <directory>src/main/webapp</directory>
         <filtering>false</filtering>
         <includes>
            <include>WEB-INF/web.xml</include>
         </includes>
       </resource>
     </resources>
  </build>

</project>
In case you create such a platform module, make sure it contains all the required dependencies. The above example only shows the default required dependencies, but you might need to think about custom derived functions, workflow, scheduler daemons, etc. 

Check the dependencies in the cms-dependencies/pom.xml file. For some of the installed features an artifact named *-cms-dependencies artifact is defined. Check if there is a specific *-platform-dependencies for this feature. If that is the case, add that dependency to the new platform/pom.xml.

An example of a dependency to add to the platform-dependencies/pom.xml would be the org.onehippo.cms7:hippo-essentials-components-cms. This jar contains the BlogListenerModule that the Platform webapp will to start.

The same is true for the CrispRegistryModule from org.onehippo.cms7:hippo-addon-crisp-repository.

Add web.xml under platform/src/main/webapp/WEB-INF with the following entries:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0"
         id="cms">

  <display-name>My Project Platform</display-name>
  <description>My Project Platform</description>

  <listener>
    <listener-class>org.hippoecm.hst.platform.container.HstPlatformContextLoaderListener</listener-class>
  </listener>

  <context-param>
    <description>The address of the repository</description>
    <param-name>repository-address</param-name>
    <param-value>vm://</param-value>
  </context-param>
  <context-param>
    <description>The (relative) location where to store files</description>
    <param-name>repository-directory</param-name>
    <param-value>WEB-INF/storage</param-value>
  </context-param>
  <context-param>
    <description>The location of the repository configuration file. Unless the location
      starts with file://, the location is retrieved from within the application package as
      resource.
    </description>
    <param-name>repository-config</param-name>
    <param-value>repository.xml</param-value>
  </context-param>

  <filter>
    <filter-name>HstFilter</filter-name>
    <filter-class>org.hippoecm.hst.container.HstFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>HstFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>LoggingServlet</servlet-name>
    <servlet-class>org.hippoecm.repository.LoggingServlet</servlet-class>
    <load-on-startup>3</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>Repository</servlet-name>
    <servlet-class>org.hippoecm.repository.RepositoryServlet</servlet-class>
    <load-on-startup>4</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>PingServlet</servlet-name>
    <servlet-class>org.hippoecm.repository.PingServlet</servlet-class>
    <init-param>
      <param-name>repository-address</param-name>
      <param-value>vm://</param-value>
    </init-param>
    <load-on-startup>5</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoggingServlet</servlet-name>
    <url-pattern>/logging/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>Repository</servlet-name>
    <url-pattern>/repository/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>PingServlet</servlet-name>
    <url-pattern>/ping/</url-pattern>
  </servlet-mapping>

  <env-entry>
    <env-entry-name>logging/contextName</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>platform</env-entry-value>
  </env-entry>

</web-app>

You see that there is configuration for logging in this file. To make that work, also update the log4j configuration files by adding Appender and AppenderRef configuration for it, like this:

<!-- platform.log -->
<RollingFile name="platform" fileName="${sys:catalina.base}/logs/platform.log"
             filePattern="${sys:catalina.base}/logs/platform.log.%d{yyyy-MM-dd}">
  <LookupFilter key="jndi:logging/contextName" value="platform" onMatch="ACCEPT"/>
  <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss} %-5p %t [%C{1}.%M:%L] %m%n"/>
  <Policies>
    <TimeBasedTriggeringPolicy/>
  </Policies>
</RollingFile>

and:

<Root level="warn">
  <AppenderRef ref="site"/>
  <AppenderRef ref="cms"/>
  <AppenderRef ref="platform"/>
  <AppenderRef ref="console"/>
</Root>

Create the CMS and Site Distributions

Create 2 new distribution XML files under src/main/assembly.

distribution-without-cms.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
  <id>distribution-without-cms</id>
  <formats>
    <format>tar.gz</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <componentDescriptors>
    <componentDescriptor>conf-component.xml</componentDescriptor>
    <componentDescriptor>webapps-without-cms-component.xml</componentDescriptor>
    <componentDescriptor>common-lib-component.xml</componentDescriptor>
    <componentDescriptor>shared-lib-component.xml</componentDescriptor>
  </componentDescriptors>
</assembly>

webapps-without-cms-component.xml

<component xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2 http://maven.apache.org/xsd/component-1.1.2.xsd">
  <files>
    <file>
      <source>platform/target/platform.war</source>
      <outputDirectory>webapps</outputDirectory>
      <destName>platform.war</destName>
    </file>
    <file>
      <source>site/webapp/target/site.war</source>
      <outputDirectory>webapps</outputDirectory>
      <destName>site.war</destName>
    </file>
  </files>
</component>

Add a new profile for building the regular and the new distribution in your primary POM:

    <profile>
      <id>separate-dist</id>
      <dependencies>
        <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-slf4j-impl</artifactId>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-api</artifactId>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-core</artifactId>
          <scope>provided</scope>
        </dependency>
      </dependencies>
      <build>
        <defaultGoal>validate</defaultGoal>
        <plugins>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <id>without-cms-assembly</id>
                <phase>validate</phase>
                <goals>
                  <goal>single</goal>
                </goals>
                <configuration>
                  <descriptors>
                    <descriptor>${project.basedir}/src/main/assembly/distribution-without-cms.xml</descriptor>
                  </descriptors>
                </configuration>
              </execution>
              <execution>
                <id>cms-included-assembly</id>
                <phase>validate</phase>
                <goals>
                  <goal>single</goal>
                </goals>
                <configuration>
                  <descriptors>
                    <descriptor>${project.basedir}/src/main/assembly/distribution.xml</descriptor>
                  </descriptors>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>

That's it!

Build with Maven:

mvn clean verify

Then run:

mvn -Pseparate-dist

You'll get two tar.gz files containing the WARs you need. Deploy the cms and site wars to the first server, and the site and platform WARs to the second.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?