TomEE on OpenShift with Maven?


I already blog posted about how to deploy TomEE on cloudfoundry using the standalone framework (TomEE on CloudFoundry). It was mainly based on the tomee-maven-plugin to create a tomee ready to start and cloudfoundry maven plugin to deploy it.

The main competitor of CloudFoundry is OpenShift. The question is can we do the same?

OpenShift doesn’t have a maven plugin (or i missed it) but i developped one here: OpenShift Maven Plugin.

Now we have tomee-maven-plugin and openshift-maven-plugin we just miss some configuration to be able to deploy our application quickly.

The project

For the sample i’ll take a simple war project.

The OpenShift cartridge selection

With OpenShift you deploy your application in “standalone” cartridges (it can be any container like Tomcat, TomEE, JBoss AS…or any runtime like PHP, NodeJS…). There is a TomEE cartridge (here) but it needs to be installed on an OpenShift node (server side). Since that’s not always possible or simply because sometimes you customize TomEE enough to not be able to rely on a default installation we’ll start from a DIY (do it yourself) cartridge.

The configuration

Note: i use maven property openshift.base to represent the folder containing the customized DIY cartridge.

Maven

What do we need on maven side?

  • create a tomee containing our application
  • deploy our customized DIY cartridge to OpenShift

TomEE maven plugin

What are the contraint on our TomEE?

  • our TomEE maven plugin will use the exploded war to be able to push to OpenShift lighter diff (OpenShift relies on git)
  • we’ll remove all TomEE webapps since we don’t need it
  • we want our application to be the root one (context “/”).
  • we don’t need to create a zip of our tomee or to attach it to maven lifecycle

Here is the XML version:

<plugin>
  <groupId>org.apache.openejb.maven</groupId>
  <artifactId>tomee-maven-plugin</artifactId>
  <version>1.6.0-SNAPSHOT</version>
  <executions>
    <execution>
      <id>create-tomee</id>
      <phase>package</phase>
      <goals>
        <goal>build</goal>
      </goals>
      <configuration>
        <attach>false</attach> <!-- maven doesn't need to take tomee as an artifact -->
        <zip>false</zip> <!-- we deploy an exploded version -->
        <removeTomeeWebapp>true</removeTomeeWebapp> <!-- we don't do remote EJBs -->
        <catalinaBase>${openshift.base}/diy/tomee</catalinaBase> <!-- matches our action_hooks -->
        <context>ROOT</context> <!-- / context -->
        <warFile>${project.build.directory}/${project.build.finalName}</warFile> <!-- exploded war file for better diff handling  -->
        <keepServerXmlAsthis>true</keepServerXmlAsthis> <!-- otherwise our variables will be replaced -->
      </configuration>
    </execution>
  </executions>
</plugin>

You can note it will be executed during package phase. That’s just to avoid to call multiple goals before deploying.

Note i set keepServerXmlAsthis to true too, i’ll explain why in the part about the OpenShift hooks.

OpenShift maven plugin

OpenShift maven plugin supports credentials to be passed in the plugin configuration block but if you already have set up rhc (the OpenShift client) you probably have a ~/.openshift/express.conf the plugin is able to read to extract your OpenShift url, user and password (this one is not by default in the file and you need to add the base64 of your password as value of the key “maven_plugin_password”).

Here the constraints are pretty simple:

  • we need to match the OpenShift domain and application we want to deploy
  • we don’t deploy in a Tomcat or TomEE (where webapps/ is handled particularly) so we need to deploy the whole repository we created
  • we need to add action_hooks (see next part)

So here is the XML version:

<plugin>
  <groupId>com.worldline.maven</groupId>
  <artifactId>openshift-maven-plugin</artifactId>
  <version>0.1-SNAPSHOT</version>
  <configuration>
    <application>dyot</application>
    <domain>blois</domain>

    <binary>${openshift.base}</binary>

    <!-- we deploy a diy -->
    <useWebapps>false</useWebapps>
  </configuration>
</plugin>

The action hooks stuff is not explicit since by default the plugin synchronizes src/main/openshift directory with the git repository of your application (our DIY cartridge).

The hooks

Now we are able to push a TomEE on OpenShift but if you just do it it will not start/stop (or at least not as expected).

OpenShift uses environment variables to pass to the cartridges the host/port/… the cartridge needs to listen to be accessible.

So to match this configuration we’ll create a custom server.xml in src/main/tomee/conf (synchronized by tomee-maven-plugin by default) containing:

<?xml version='1.0' encoding='utf-8'?>
<Server address="OPENSHIFT_DIY_IP" port="SHUTDOWN_PORT" shutdown="SHUTDOWN">
  <Listener className="org.apache.tomee.catalina.ServerListener" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <Service name="Catalina">
    <Connector port="HTTP_PORT" protocol="HTTP/1.1"
               connectionTimeout="20000"
               address="OPENSHIFT_DIY_IP" />

    <Engine name="Catalina" defaultHost="OPENSHIFT_DIY_IP">

      <Host name="OPENSHIFT_APP_DNS"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

Here you can see why keepServerXmlAsThis was set to true in tomee-maven-plugin configuration: if not host and ports will be replaced by the one provided in the plugin configuration (if not the default one ie localhost for the host, 8080 for the http port…).

Now we just need to say our cartridge to replace the variables of this server.xml and how to start/stop our TomEE.

To do so just create a folder “.openshift/action_hooks” in src/main/openshift (which will be synchronized by the openshift-maven-plugin) containing a start and a stop script.

The stop script is trivial since it just calls TomEE shutdown.sh script:

#! /bin/bash
nohup sh $OPENSHIFT_DATA_DIR/tomee/bin/shutdown.sh

The start one is a bit more complicated since it will synchronize the git working copy of the OpenShift node with the runtime instance, replace the variable in the server.xml and start the server:

#! /bin/bash

DEST=$OPENSHIFT_DATA_DIR/tomee/
SERVER_XML=$DEST/conf/server.xml
LOGS=$DEST/logs

rm -r $DEST
cp -r $OPENSHIFT_REPO_DIR/diy/tomee/ $DEST

sed -i 's/OPENSHIFT_DIY_IP/'$OPENSHIFT_DIY_IP'/g' $SERVER_XML
sed -i 's/OPENSHIFT_APP_DNS/'$OPENSHIFT_APP_DNS'/' $SERVER_XML
sed -i 's/HTTP_PORT/'$OPENSHIFT_DIY_PORT'/' $SERVER_XML
sed -i 's/SHUTDOWN_PORT/'$RANDOM'/' $SERVER_XML

rm -rf $LOGS
ln -s $OPENSHIFT_DIY_LOG_DIR $LOGS

nohup sh $DEST/bin/startup.sh

The deployment

If you didn’t already created your application on OpenShift just execute the command:

mvn openshift:create-application -Dopenshift.cartridge=diy-0.1

It will create your application using the DIY cartridge.

Then to deploy simply run:

mvn package mvn openshift:update-application
Advertisements

7 thoughts on “TomEE on OpenShift with Maven?

  1. mauroprogram

    hi Romain. Please you can please explain me how set the usename and password of my account openshift into the OpenShift maven plugin ?

    1) if i would deploy a new tomee on openshift using a computer that not has installed rhclient it is possible ? I not have into the pc the ~/.openshift/express.conf because it is another computer .
    2)before to use the openshift maven plug in i have to create the cartridge diy from the website of openshift for get the password ssh-rsa ????????? or it work without ssh-rsa??

    3) HOw i can set the mysql connection into tomee.xml whit sed -i ?????????

    Reply
    1. rmannibucau Post author

      Basically username is a subtag of configuration of the plugin (tag name is “user”) and password too but you can put the password in ~/.openshift/express.conf (even without rhc) with the key maven_plugin_password and a base64 value of your password. Side note: default_rhlogin is read too for username in this file.

      Your openshift server has to have the needed cartridge(s) installed yes.

      To use openshift mysql you can use templating of tomee (JdbcUrl = ${name of the var in openshift})

      Reply
  2. mauroprogram

    for set the datasource into tomee.xml i have to use this example????

    http://whyjava.wordpress.com/2012/11/21/configuring-jndi-datasource-with-openshift-tomcat-cartridge/

    Resource name=”jdbc/postgresqldb” auth=”Container” type=”javax.sql.DataSource”
    username=”${env.OPENSHIFT_POSTGRESQL_DB_USERNAME}” password=”${env.OPENSHIFT_POSTGRESQL_DB_PASSWORD}”
    url=”jdbc:postgresql://${env.OPENSHIFT_POSTGRESQL_DB_HOST}:${env.OPENSHIFT_POSTGRESQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}”
    driverClassName=”org.postgresql.Driver” initialSize=”5″ maxWait=”5000″
    maxActive=”120″ maxIdle=”5″ validationQuery=”select 1″
    poolPreparedStatements=”true”>

    the example above it is set into server.xml .of a tomcat on openshift.

    So i you ask:
    i can refer into tomee.xml the ${env.OPENSHIFT_MYSQL_DB_USERNAME} and other??

    it work also with the diy????
    finally i think to write my tomee.xml with the following entry :

    JdbcDriver com.mysql.jdbc.Driver

    JdbcUrl jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}”

    UserName “${env.OPENSHIFT_MYSQL_DB_USERNAME}”
    Password “${env.OPENSHIFT_M§YSQL_DB_PASSWORD}”
    JtaManaged true

    or i can use the Resources.xml into web.inf of a single webapp deployed into tomee into openshift?

    yu can that it can work the configuration above?

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s