Preparing and Deploying a JBoss server to execute SPADE

This article explains how to prepare and deploy a JBoss server so that is can be used by the "vanilla" version of SPADE.

Introduction

The current "vanilla" version of SPADE, nest-spade-war, is configured to run in a JBoss server. Therefore, in this article, you will learn how to prepare and deploy such a server. If you already have one running then you may be able to skip this section, though a brief glance at it may be useful to make sure your current server behaves as expected.


NOTE: These instructions are for a JBoss 7.1.1 installation on SLC 6.4. Other versions of the application and OS may need modifications to be successful.


Installation the Basic JBoss server

To start with, you can simply download the server and make sure it runs on your system. The following commands do just that. Once the server is running you will see the last line containing "JBoss AS 7.1.1.Final "Brontes" started", you can then shut it down using CTRL-C.

mkdir -p ~/server/downloads
cd ~/server/downloads
wget http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.tar.gz
cd ~/server
tar zxvf downloads/jboss-as-7.1.1.Final.tar.gz
cd ~/server/jboss-as-7.1.1.Final
bin/standalone.sh -server-config standalone.xml

Now that the basic server is installed you need to customize it for SPADE.

Customizing the DataSource and Transaction Timeout

SPADE uses a database to store information about the files it handles. Therefore the JBoss server needs to be modified to provide access to a suitable database. In order to run the example scenarios you can use the inbuilt ExampleDS that is provided with the JBoss server. The commands below change the default setting for the ExampleDS to place it in the ~/spade/h2 directory and simplify its use with the h2console application you will be using later. They also change the default transaction timeout to be 1 hour as the default 5 minutes can be too short and cause transactions to be aborted while they are still valid.


NOTE: For production you should use a production quality database as outlined here


mkdir -p ~/spade/h2
cd ~/server/jboss-as-7.1.1.Final
cp -rp standalone/configuration/standalone.xml standalone/configuration/standalone.xml.`date +%Y-%m-%d`
cat > patch_1.txt << EOF
*** standalone.xml.2012-11-21	2012-03-09 22:14:05.000000000 -0800
--- standalone.xml              2012-11-21 14:41:34.086167289 -0800
***************
*** 91,101 ****
          <subsystem xmlns="urn:jboss:domain:datasources:1.0">
              <datasources>
                  <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
!                     <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
                      <driver>h2</driver>
                      <security>
                          <user-name>sa</user-name>
!                         <password>sa</password>
                      </security>
                  </datasource>
                  <drivers>
--- 91,101 ----
          <subsystem xmlns="urn:jboss:domain:datasources:1.0">
              <datasources>
                  <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
!                     <connection-url>jdbc:h2:~/spade/h2/spade;DB_CLOSE_DELAY=-1</connection-url>
                      <driver>h2</driver>
                      <security>
                          <user-name>sa</user-name>
!                         <password></password>
                      </security>
                  </datasource>
                  <drivers>
***************
*** 251,257 ****
                  </process-id>
              </core-environment>
              <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
!             <coordinator-environment default-timeout="300"/>
          </subsystem>
          <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
              <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
--- 251,257 ----
                  </process-id>
              </core-environment>
              <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
!             <coordinator-environment default-timeout="3600"/>
          </subsystem>
          <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
              <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
EOF
patch standalone/configuration/standalone.xml patch_1.txt
rm patch_1.txt

You are now ready to consider how you want to deploy the JBoss server.

Setting up the JBoss server to run as a Service

Under normal conditions SPADE should always be running, waiting for the next bundle of files to be transferred or received, therefore it makes sense to set JBoss server to run as a system service. However, as the user running SPADE may not have root privileges, the changes below to the default JBoss server files are designed to enable that user, or the system, to manage the service.

To begin with, the jboss-as.conf file is modified to use the user's area that than the system's one.

cd ~/server/jboss-as-7.1.1.Final/
cp -rp bin/init.d/jboss-as.conf bin/init.d/jboss-as.conf.`date +%Y-%m-%d`
cat > patch_2.txt << EOF
*** jboss-as.conf.2012-11-21    2012-03-09 22:14:02.000000000 -0800
--- jboss-as.conf               2013-07-25 03:21:22.000000000 -0700
***************
*** 4,18 ****
--- 4,32 ----
  # The username who should own the process.
  #
  # JBOSS_USER=jboss-as
+ JBOSS_USER=this_user

  # The amount of time to wait for startup
  #
  # STARTUP_WAIT=30
+ STARTUP_WAIT=10

  # The amount of time to wait for shutdown
  #
  # SHUTDOWN_WAIT=30
+ SHUTDOWN_WAIT=30
+
+ # Location of JBoss files
+ #
+ # JBOSS_HOME=/usr/share/jboss-as
+ JBOSS_HOME=this_home/server/jboss-as-7.1.1.Final

  # Location to keep the console log
  #
  # JBOSS_CONSOLE_LOG=/var/log/jboss-as/console.log
+ JBOSS_CONSOLE_LOG=\$JBOSS_HOME/standalone/log/console.log
+
+ # Location of JBoss PID file
+ #
+ # JBOSS_PIDFILE=/var/run/jboss-as/jboss-as-standalone.pid
+ JBOSS_PIDFILE=\$JBOSS_HOME/standalone/jboss-as-standalone.pid
EOF
export PATCH_USER=s/this_user/$USER/g
sed -i.bck -e ${PATCH_USER} patch_2.txt
unset PATCH_USER
export PATCH_HOME=s/this_home/`echo $HOME | sed -e 's/\//\\\\\//g'`/g
sed -i.bck -e ${PATCH_HOME} patch_2.txt
unset PATCH_HOME
patch bin/init.d/jboss-as.conf patch_2.txt
rm patch_2.txt*

Next, the jboss-as-standalone.sh file is modified to execute SPADE as the user rather than root and write the logs into a standard area.

cd ~/server/jboss-as-7.1.1.Final/
cp -rp bin/init.d/jboss-as-standalone.sh bin/init.d/jboss-as-standalone.sh.`date +%Y-%m-%d`
cat > patch_3.txt << EOF
*** jboss-as-standalone.sh.2013-07-02    2012-03-09 22:14:02.000000000 -0800
--- jboss-as-standalone.sh               2013-07-29 11:14:19.000000000 -0700
***************
*** 9,15 ****
  # config: /etc/jboss-as/jboss-as.conf
  
  # Source function library.
! . /etc/init.d/functions
  
  # Load Java configuration.
  [ -r /etc/java/java.conf ] && . /etc/java/java.conf
--- 9,17 ----
  # config: /etc/jboss-as/jboss-as.conf
  
  # Source function library.
! if [ -r /etc/init.d/functions ] ; then
!   . /etc/init.d/functions
! fi
  
  # Load Java configuration.
  [ -r /etc/java/java.conf ] && . /etc/java/java.conf
*************** prog='jboss-as'
*** 57,63 ****
  CMD_PREFIX=''
  
  if [ ! -z "\$JBOSS_USER" ]; then
!   if [ -x /etc/rc.d/init.d/functions ]; then
      CMD_PREFIX="daemon --user \$JBOSS_USER"
    else
      CMD_PREFIX="su - \$JBOSS_USER -c"
--- 59,65 ----
  CMD_PREFIX=''
  
  if [ ! -z "\$JBOSS_USER" ]; then
!   if [ -r /etc/rc.d/init.d/functions ]; then
      CMD_PREFIX="daemon --user \$JBOSS_USER"
    else
      CMD_PREFIX="su - \$JBOSS_USER -c"
*************** start() {
*** 85,96 ****
    #\$CMD_PREFIX JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT 2>&1 > \$JBOSS_CONSOLE_LOG &
    #\$CMD_PREFIX JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT &
  
!   if [ ! -z "\$JBOSS_USER" ]; then
!     if [ -x /etc/rc.d/init.d/functions ]; then
        daemon --user \$JBOSS_USER LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT -c \$JBOSS_CONFIG 2>&1 > \$JBOSS_CONSOLE_LOG &
      else
        su - \$JBOSS_USER -c "LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT -c \$JBOSS_CONFIG" 2>&1 > \$JBOSS_CONSOLE_LOG &
      fi
    fi
  
    count=0
--- 87,100 ----
    #\$CMD_PREFIX JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT 2>&1 > \$JBOSS_CONSOLE_LOG &
    #\$CMD_PREFIX JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT &
  
!   if [ ! -z "\$JBOSS_USER"  -a "\`whoami\`" != "\$JBOSS_USER" ]; then
!     if [ -r /etc/rc.d/init.d/functions ]; then
        daemon --user \$JBOSS_USER LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT -c \$JBOSS_CONFIG 2>&1 > \$JBOSS_CONSOLE_LOG &
      else
        su - \$JBOSS_USER -c "LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT -c \$JBOSS_CONFIG" 2>&1 > \$JBOSS_CONSOLE_LOG &
      fi
+   else
+       bash -c "LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=\$JBOSS_PIDFILE \$JBOSS_SCRIPT -c \$JBOSS_CONFIG" 2>&1 > \$JBOSS_CONSOLE_LOG &
    fi
  
    count=0
EOF
patch bin/init.d/jboss-as-standalone.sh patch_3.txt
rm patch_3.txt

Finally, you can now create the service file itself using the following commands. (The first set of commands are only needed if you do not already have a ~/bin directory that is not in your PATH variable.)

mkdir -p ~/bin
cat >> ~/.bash_profile << EOF
PATH=\${HOME}/bin:\${PATH}
export PATH
EOF

. ~/.bash_profile
cat > ~/bin/jboss-as << EOF
#!/bin/sh
#
# JBoss standalone control script
#
# chkconfig: - 80 20
# description: JBoss AS Standalone
# processname: standalone

JBOSS_INIT_D=this_home/server/jboss-as-7.1.1.Final/bin/init.d
JBOSS_CONF="\$JBOSS_INIT_D/jboss-as.conf"
export JBOSS_CONF
\$JBOSS_INIT_D/jboss-as-standalone.sh \$*
EOF
export PATCH_HOME=s/this_home/`echo $HOME | sed -e 's/\//\\\\\//g'`/g
sed -i.bck -e $PATCH_HOME ~/bin/jboss-as
unset PATCH_HOME
chmod +x ~/bin/jboss-as

The ~/bin/jboss-as file can, if you wish, be copied into the /etc/init.d directory by the host's system adminstrator so that it can be used as usual for a starting and stopping the service.


NOTE: As the service calls a script in a user account, that user account must be as secure as the root one.


In order to test that everything was modified correctly run the following two lines.

touch ~/server/jboss-as-7.1.1.Final/standalone/log/console.log
tail -f ~/server/jboss-as-7.1.1.Final/standalone/log/console.log

Now open a second window on the server's host and execute the following command.

jboss-as start

You should see, in your original window, that JBoss server is starting. Once that has completed, then running the following command will stop it.

jboss-as stop

Your JBoss server in now ready to run the SPADE application.

Enabling Secure Sockets (Optional)

One of the mechanisms by which two SPADE instances can communicate is email, and another can be over HTTPS. When this is the case the JBoss server may will need access to the other server's certificates that are held in a truststore. If the server's certificates are signed by a common Certificate Authority the CA certificates distributed with Java will probably work. If, on the other hand, the certificates are not signed by them, you will need to either create a truststore that contains those certificates or add those certificate to the existing Java truststore so that the two servers to communicate. Creating a truststore is explained elsewhere, but bear in mind that if you create your own truststore it will not contain the standard Certificates for other sites, so you may want to add those too.

If you need to use your own truststore, rather than the Java default one, the following commands will set up the JBoss server to use it.


NOTE: The environmental variable TRUSTSTORE_PASSWORD should be set to the key store's password before the commands are run.


cd ~/server/jboss-as-7.1.1.Final/
cp -rp bin/standalone.sh bin/standalone.sh.`date +%Y-%m-%d`
cat > patch_4.txt << EOF
*** standalone.sh.2012-11-21    2012-03-09 22:14:02.000000000 -0800
--- standalone.sh               2012-11-21 14:51:20.762876787 -0800
*************** while true; do
*** 183,188 ****
--- 183,190 ----
           -jaxpmodule "javax.xml.jaxp-provider" \\
           org.jboss.as.standalone \\
           -Djboss.home.dir=\"\$JBOSS_HOME\" \\
+          -Djavax.net.ssl.trustStore=\"\$JBOSS_HOME/extras/cacerts\" \\
+          -Djavax.net.ssl.keyStorePassword=\"truststore_password\" \\
           "\$@"
        JBOSS_STATUS=\$?
     else
*************** while true; do
*** 195,200 ****
--- 197,204 ----
           -jaxpmodule "javax.xml.jaxp-provider" \\
           org.jboss.as.standalone \\
           -Djboss.home.dir=\"\$JBOSS_HOME\" \\
+          -Djavax.net.ssl.trustStore=\"\$JBOSS_HOME/extras/cacerts\" \\
+          -Djavax.net.ssl.keyStorePassword=\"truststore_password\" \\
           "\$@" "&"
        JBOSS_PID=\$!
        # Trap common signals and relay them to the jboss process
EOF
# Remember that the environmental variable TRUSTSTORE_PASSWORD should be set to the key stores password(!)
export PATCH_PASSWRD=s/truststore_password/${TRUSTSTORE_PASSWORD}/g
sed -i.bck -e $PATCH_PASSWRD patch_4.txt
unset PATCH_PASSWRD
patch bin/standalone.sh patch_4.txt
rm patch_4.txt*