Oracle Application Container Cloud Service: Create a Tomcat Cluster with MySQL Session Persistence


Options



Before You Begin

Purpose

This tutorial shows you how to create a Tomcat cluster using MySQL Persistence on the Oracle Application Container Cloud Service.

Time to Complete

90 minutes

Background

What is a Cluster?

A cluster, in this context, consists of several Tomcat servers that work together to appear as a single system. This is achieved by using load balancers to tie the servers together using each server's network port and IP address. Each node in the cluster shares session data in a MySQL database. The result is a cluster of Tomcat servers appears as a single server to client systems.

What are are the Benefits?

There are a number of benefits to using clusters that include:

  • Performance and Scaling: Since more than one server performs a task or unit of work, response time should be faster. In addition, a cluster can be scaled out to handle more and more work by adding servers to the cluster. This is made possible by load balancing.

    • Load Balancing: A load balancer is a special server that allocates work to servers in the cluster. When requests come into the cluster, the balancer takes the request and passes it off to an individual server. Load balancers can use anything from complex algorithms to route traffic, to a simple round robin approach.

  • High Availability: High availability refers to systems which provide a high uptime while being resistant to faults in the system. Highly available systems are designed to eliminate a single point of failure. For example in a cluster, if one of the servers crashes, the other servers in the cluster continue running and function normally. From outside the system, there appears to be no change in the way the cluster operates if a node goes down.

Context

In this OBE, you will create a local cluster using the Apache HTTP server as a load balancer and two Tomcat servers as cluster nodes. After that system is setup, you will convert one of the Tomcat servers for deployment on the Oracle Application Container Cloud Service. Then, you deploy that Tomcat node so the cluster runs and can be managed in the cloud.

What Do You Need?

Detailed steps for installing these products are provided on their respective web sites. For brevity, those steps are not covered in this guide, except for Tomcat. The following sections assume the required software is installed.

Setting up Apache as a Load Balancer

Overview

In this section, we will configure an Apache 2.4 server to act as a load balancer for a Tomcat cluster. The steps outlined are for Windows, but tips related to Linux are included at the end of the section. It is assumed that you have installed or downloaded the required software listed above.

An Apache HTTP server can be used as the load balancing front end for a Tomcat cluster. This is accomplished using the mod_jk module. The mod_jk module serves as a redirector to servlet containers like Tomcat and can also be used to setup a cluster of Tomcat servers. The cluster uses AJP (Apache Jserv Protocol) to communicate between the Tomcat servers and Apache. AJP is a binary version of HTTP that is optimized for communication between Apache HTTPD server and Apache Tomcat over a TCP connection.

Configuring your Apache Server

Follow these steps to configure your server.

  1. Install the mod_jk Apache module. This module allows Apache to function as load balancer for our Tomcat instances.

    1. Unzip the mod_jk zip file into a directory.

    2. Copy the mod_jk.so to the ApacheHome/modules directory.

  2. Create a configuration file to store the load balancing information.

    1. Change into the ApacheRoot/conf directory.

    2. Create a mod-jk.conf file.

  3. Edit the mod-jk.conf file and add the following information.

    Apache Configuration File

    
    # This file configures mod_jk for creating Tomcat clusters
    
    # Load the module
    LoadModule jk_module modules/mod_jk.so
    
    # Set path to workers file
    JkWorkersFile conf/workers.properties
    
    # Shared Memory file - For Unix only. Comment out for Windows.
    # JkShmFile logs/mod_jk.shm
    
    # Path to Logs
    JkLogFile logs/mod_jk.log
    
    # Log level - Info is default. Should work for most situations.
    JkLogLevel info
    
    # Mount workers for mod_jk
    JkMount /status/* status
    JkMount /clusterjsp/* loadbalancer
    

    Each configuration option is described with a comment in the mod-jk.conf file. The last set of configuration options require further explanation.

    • JkMount /status/* status - This creates an Apache status page with information about each node in the cluster. Going to http://hostname/status in your browser displays detailed information about the cluster.

    • JkMount /clusterjsp/* loadbalancer - This option indicates that any URL http://hostname/clusterjsp will be handled by the Tomcat cluster. If you wanted to have the cluster hand all HTTP traffic change the path to the root only /*.

  4. Save the file.

  5. Create the workers.properties file. The workers.properties file identifies the Tomcat instances that will be included in the cluster. Each "worker" is identified by host name and port. This example has 2 workers for the load balancer and a status page.

  6. Edit the workers.properties file and add the following information.

    workers.properties

    
    worker.list=loadbalancer,status
    
    worker.worker1.port=8009
    worker.worker1.host=localhost
    worker.worker1.type=ajp13
    
    worker.worker2.port=8010
    worker.worker2.host=localhost
    worker.worker2.type=ajp13
    
    worker.loadbalancer.type=lb
    worker.loadbalancer.balance_workers=worker1,worker2
    
    worker.status.type=status
    

    This indicates that two Tomcat servers are in the cluster on ports 8009 and 8010.

  7. Save the file.

  8. Edit the httpd.conf file. Add the following lines to the bottom of the file.

    httpd.conf Changes

    
    # Enable mod_jk to create a load balancer
    Include conf/mod-jk.conf
    
  9. Save the file.

  10. Start or restart your Apache server to load the new settings:

    • ApacheHome/bin/httpd.exe

Installing Apache and the mod_jk Module on Linux

If you wish to install and configure `mod_jk` on Linux there are a few configuration file variations depending upon the distribution.

Installing Apache on Oracle Linux

Here are some tips for installing Apache on Oracle Linux (RedHat). Perform the following commands as root or using sudo.

  • To install Apache Server on use the command:

    yum install httpd

  • To install mod_jk use the following command:

    yum install mod_jk

The Apache home directory is located in /etc/httpd. Other than that, the file names and locations are very similar to Windows. The Windows instructions can be followed with little variation.

Installing mod_jk on Ubuntu Linux

  • To install Apache HTTP server on Ubuntu use the following command:

    sudo apt-get install apache2

  • To install mod_jk on Ubuntu use the following command:

    sudo apt-get install libapache2-mod-jk

The locations of files on Ubuntu is different. When you install the libapache2-mod-jk package, that installs the module along with required configuration files, so there is no need to include a new mod-jk.conf file. Here is the location of the pertinent files.

  • Apache home: /etc/apache2

  • mod_jk configuration file: /etc/apache2/mods-available/jk.conf

  • worker.properties file: /etc/libapache2-modjk/

Modify the files in these new locations to configure Apache on Ubuntu.

Note: When the mod_jk package is installed, symbolic links are placed in the /etc/apache2/mods-enabled directory for jk.conf and jk.load. This enables the module for Apache on Ubuntu.

Configuring MySQL for Tomcat Session Sharing

Make the the following changes to your MySQL system after installation. The steps assume that the MySQLHome\bin directory is in your path and your MySQL server is running.

Creating a User Account and Password for the Application

Add a new user to the MySQL server by performing the following steps.

  1. Login as root.

    mysql -u root -p

  2. Create a user for this application.

    CREATE USER 'YourUser'@'localhost' IDENTIFIED BY 'YourPassword';

  3. Give the user admin privileges.

    GRANT ALL PRIVILEGES ON *.* TO 'YourUser'@'localhost' WITH GRANT OPTION;

  4. Log out.

Setting up MySQL for Session Sharing

Next, setup a database to store session data.

  1. Login to MySQL using the account you created.

  2. Create a database for you session data if one does not exist.

    create database YourDatabaseName;

  3. Use the database.

    use YourDatabaseName;

  4. Create a tomcat_sessions table to store session data.

    tomcat_sessions SQL

    
    create table tomcat_sessions (
      session_id     varchar(100) not null primary key,
      valid_session  char(1) not null,
      max_inactive   int not null,
      last_access    bigint not null,
      app_name       varchar(255),
      session_data   mediumblob,
      KEY kapp_name(app_name)
    );

MySQL is now configured for session sharing in a Tomcat cluster.

Configuring Tomcat to be used in a Cluster

Installing Tomcat

We will be installing two copies of Tomcat to create a local cluster. To begin with, one copy of Tomcat is installed and configured. Then a copy will be made of the first Tomcat installation and modified to be a second Tomcat instance.

To install Tomcat perform the following steps.

  1. Download the Tomcat 8.5 .zip or .tar.gz file.

  2. Uncompress Tomcat.

  3. Copy or move the uncompressed Tomcat directory to where you want to install Tomcat, for example c:\tom1.

Updating the Configuration Files

The next step in the process is to update the configuration files.

  1. Open the server.xml file in the TomcatHome/conf directory and make the following changes:

    1. Remove all the comments from the file.

    2. Change the Engine element about midway down the file. Add an attribute pair jvmRoute="worker1".

      This change helps identify which Tomcat server has been selected by the load balancer to process the current request. In this example, the server on port 8080 will be identified as worker1.

    When complete, the server.xml file should look like this.

    server.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
    
      <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">
    
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
    
          <Host name="localhost"  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>
    
  2. Open the context.xml file in the TomcatHome/conf directory and make the following changes:

    • Add the Manager and Store elements as shown in the following example.

    • Notice the connectionURL attribute in the Store element. This specifies your Java JDBC connection string. A typo here prevents the database from connecting. So check your logs if session data is not making it to the database.

    • By default MySQL attempts to connect using SSL (HTTPS). This works when your application use Oracle Application Container Cloud Service. However, when testing locally append the useSSL=false option to the connect string so HTTP is used.

    • The example assumes the default port of 3306. If you use a nonstandard port for MySQL you need to append the port number to the host name, for example:

      localhost:3306

    • Most of the attributes correspond to fields in the tomcat_sessions table.

    context.xml

    
    <Context>
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    
        <Manager className="org.apache.catalina.session.PersistentManager"
                 maxIdleBackup="10">
          <Store className="org.apache.catalina.session.JDBCStore"
                 connectionURL="jdbc:mysql://localhost/YourDatabaseName?user=UserName&amp;password=UserPassword&amp;useSSL=false"
                 driverName="com.mysql.jdbc.Driver"
                 sessionAppCol="app_name"
                 sessionDataCol="session_data"
                 sessionIdCol="session_id"
                 sessionLastAccessedCol="last_access"
                 sessionMaxInactiveCol="max_inactive"
                 sessionTable="tomcat_sessions"
                 sessionValidCol="valid_session" />
        </Manager>
    </Context>
    
  3. Open the catalina.properties file in the TomcatHome/conf directory and add the following two lines.

    catalina.properties Changes

    
    org.apache.catalina.session.StandardSession.ACTIVITY_CHECK=true
    org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
    

    These settings are required to use a JDBC session store.

  4. Save the file.

  5. Copy the latest MySQL Java JDBC driver file into the TomcatHome/lib directory. For example, the following file was used in creating this OBE: mysql-connector-java-5.1.40-bin.jar

This completes the initial configuration for the Tomcat server.

Creating and Deploying the ClusterJSP Application

Reviewing the ClusterJSP Application

To ensure that session sharing is working, an application for testing sessions is required. ClusterJsp is an application composed of JavaServer Pages (JSP) pages that allows you to test sessions in a cluster. The application was originally included with the GlassFish application server.

The Maven project for ClusterJsp application is included in the zip file for this OBE in the maven directory. The application consists of two main files. To see the scripts navigate to the clusterjsp/maven/src/main/webapp directory. The files listed there are.

  • index.jsp: Included for test purposes.

  • HaJsp.jsp: The main session testing script. Load this page to test and see session information. In addition, the page allows you to add session data to a session.

  • ClearSession.jsp: This script is called from HaJsp.jsp to reset the session and its data.

The web.xml configuration file contains some important information. Navigate to clusterjsp/maven/src/main/webapp/WEB-INF to see the file. It should look like the following file.

web.xml


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>clusterjsp</display-name>
  <distributable/>
  <servlet>
    <servlet-name>HaJsp</servlet-name>
    <display-name>HaJsp</display-name>
    <jsp-file>/HaJsp.jsp</jsp-file>
  </servlet>
  <servlet>
    <servlet-name>ClearSession</servlet-name>
    <display-name>ClearSession</display-name>
    <jsp-file>/ClearSession.jsp</jsp-file>
  </servlet>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>HaJsp.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Note: Notice the <distributable/> tag. This indicates to Tomcat that this application can be distributed in a Tomcat cluster. This is required for session sharing.

Deploying and Testing the ClusterJsp Application

Building and Deploying the Application

Deploying a test application is the next step in the process. To deploy the ClusterJsp application perform the following steps.

  1. Open a command prompt window.

  2. Navigate to maven directory.

  3. Run the Maven command to build the project: mvn clean package

  4. Copy the clusterjsp.war file into your TomcatHome\webapps directory.

Starting Tomcat and Testing the Application

When Tomcat starts, it will unzip and install the clusterjsp.war file into the clusterjsp directory. Perform the following steps to start Tomcat and test the ClusterJsp application.

  1. Open a command prompt window.

  2. Change into the TomcatHome/bin directory.

  3. Start Tomcat in the foreground with the following command:

    catalina.bat run

    Tomcat should start running after a few seconds.

  4. Open a web browser and verify that Tomcat is running using the URL: http://localhost:8080.

  5. Once you have confirmed Tomcat is running, open the HaJsp.jsp page with the URL: http://localhost:8080/clusterjsp/HaJsp.jsp.

    When the page loads, it should look something like the following:

    HaJSP.jsp Sample Page
    Description of this image

    You can fill out the form to add session name/value pairs into the session.

Once you have confirmed Tomcat is functioning properly, shutdown Tomcat by pressing Control-C in the command prompt window.

Adding a Second Tomcat Node to the Cluster

With the first Tomcat server setup and working, you can now make a copy of that server and then modify the configuration files to create a second server for the cluster. To setup a second server perform the following steps.

  1. With the first Tomcat server in the cluster created, that Tomcat server can be copied and modified to create additional servers in the cluster. For example, copy the contents of c:\tom1 to c:\tom2.

  2. After copying the directory, you need to update the new Tomcat server so that it runs on different network ports from the first Tomcat server. You will need to make the following changes to the new server.xml file, in order from top to bottom.

    1. For the Server tag change the port attribute to 8006.

    2. Under the Service tag, the first Connector tag. Change the port attribute to 8081. This is the port the server will listen on for connections.

    3. In the same tag, change the redirectPort attribute to 8444.

    4. In the second Connector tag change the port attribute to 8010 and the redirectPort attribute to 8444.

      Notice that the two redirectPort attributes match match in the two Connector tags.

    5. In the Engine tag, change the jvmRoute attribute value to "worker2". This change allows you to see which worker was selected by the load balancer to serve your request in the HaJsp.jsp page.

    Tom2 server.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    <Server port="8006" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
    
      <Service name="Catalina">
        <Connector port="8081" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8444" />
    
        <Connector port="8010" protocol="AJP/1.3" redirectPort="8444" />
    
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker2">
    
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
    
          <Host name="localhost"  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>
    

The completes the configuration updates for the second Tomcat node.

Starting and Testing your Local Tomcat Cluster

With the Apache server and two Tomcat servers configured, you are ready to test your cluster.

  1. Change into the TomcatHome/bin directory for each Tomcat server and and start the server using the catalina script.

    catalina.bat run

  2. Change into the ApacheHome/bin/ directory and start Apache server.

    httpd.exe

    Now the Apache HTTP server is the front end load balancer for the two Tomcat servers.

  3. Test your basic setup.

    1. Open http://localhost in a browser. If you have a default Apache setup, it should respond with "It Works!".

    2. To test your if your cluster is up, open http://localhost/status in your browser. This will display a mod_jk status page about the nodes in the cluster. The following figure provides an example of what the page looks like.

      Output from the mod_jk Status Page
      Description of this image
  4. Test your cluster and session sharing.

    1. Open a browser and connect to the HaJsp.jsp page using this URL: http://localhost:8080/clusterjsp/HaJsp.jsp

      The session information should appear just like in the earlier example.

    2. Open a second browser or private browsing window and the same URL: http://localhost/clusterjsp/HaJsp.jsp>.

    3. Repeat the previous step until the page is served by worker 2. When that happens you should get data like the following:

      Sample Worker 2 Session Data

      
      HttpSession Information:
      Served From Server: localhost
      Server Port Number: 80
      Executed From Server: Hostname
      Executed Server IP Address: 192.168.2.21
      Session ID: 23BA587217DD06BD8E7D005E5E0A9A46.worker2
      Session Created: Fri Oct 21 09:56:16 MDT 2016
      Last Accessed: Fri Oct 21 09:57:38 MDT 2016
      Session will go inactive in 1800 seconds
      
    4. Add session data to this session that identifies the worker and the session. Include information that identifies the session. For example:

      Sample Worker 2 Session Data

      
      HttpSession Information:
      Served From Server: localhost
      Server Port Number: 80
      Executed From Server: Hostname
      Executed Server IP Address: 192.168.2.21
      Session ID: 23BA587217DD06BD8E7D005E5E0A9A46.worker2
      Session Created: Fri Oct 21 09:56:16 MDT 2016
      Last Accessed: Fri Oct 21 09:57:38 MDT 2016
      Session will go inactive in 1800 seconds
      
      Data retrieved from the HttpSession:
      worker2: 23BA = Session 23BA
      

      The session data appears at the bottom of the page. So if a cluster node fails, this data should still be stored in our database session store.

    5. Stop the second Tomcat server.

      Now the cluster failover kicks in.

    6. Reload your page. If everything is working, the data you created on worker 2 is now served by by worker 1. Except for the time, the data should appear like it did before.

      Sample Worker 2 Session Data

      
      HttpSession Information:
      Served From Server: localhost
      Server Port Number: 80
      Executed From Server: Hostname
      Executed Server IP Address: 192.168.2.21
      Session ID: 23BA587217DD06BD8E7D005E5E0A9A46.worker2
      Session Created: Fri Oct 21 09:56:16 MDT 2016
      Last Accessed: Fri Oct 21 09:57:38 MDT 2016
      Session will go inactive in 1800 seconds
      
      Data retrieved from the HttpSession:
      worker2: 23BA = Session 23BA
      

If a server fails, the other servers in the cluster will still serve up the session data.

Preparing a Tomcat Instance for Deployment on Oracle Application Container Cloud Service

Overview

With a local Tomcat cluster setup and working, we can now look at setting up a Tomcat instance for deployment on Oracle Application Container Cloud Service. First, be aware that the Tomcat instance will run in an Oracle Linux (RedHat) environment inside of a container. Therefore, any modifications need to be made to the Unix versions of the Tomcat scripts, not the Windows versions. The following list is an overview of the steps that need to be done to a Tomcat instance to make it Cloud ready.

  • Make a copy of a working Tomcat cluster instance.

  • Create a launch script to set environment variables and then launch Tomcat.

  • Update the Tomcat configuration for the cloud.

  • Configure Oracle Application Container Cloud Service deployment files for your Tomcat application.

  • Compress you application into an application archive for Oracle Application Container Cloud Service.

  • Setup a MySQL Cloud Service instance to store session data.

Once these steps are complete, you can deploy a Tomcat cluster node to Oracle Application Container Cloud Service. That node can be scaled up or down to act as a single cluster system.

Setting up the Launch Script and Passing Environment Data to Tomcat

The first task to make Tomcat ready for the cloud is to make a new launch script. In a cloud environment, the application needs to read environment variables from the container so it can launch with assigned values for network port and other values. The script launches the application on Oracle Application Container Cloud Service using the system provided environment variables. If no environment variables are provided, the script provides default values for running the application locally. Thus, the script can be used to launch the application locally or in the cloud. The following steps provide details for creating the launch script.

Note: If you wish to test the steps from this point forward, you need to execute Tomcat inside a Linux virtual machine or on a Linux machine. The script you provide to the system execute in a Linux environment.

  1. Copy the contents of c:\tom1 to a new directory, for example tom-accs. This creates a Tomcat instance you can modify for the cloud.

  2. You will use a new launch script, start.sh, to launch Tomcat in a container.
  3. The start.sh script checks for the existence of any required environment variables. Then, the script uses the sed string processor to substitute configuration values with the environment variables. The server.template.xml and context.template.xml files are used as input. After sed processing, server.xml and context.xml are written to the conf directory. Then, the catalina.sh script is called with the run option to launch the application in the foreground. The sample script code for this is provided in the cloud-script directory for the project download.

    start.sh Script

    
    #!/bin/bash
    
    # Set defaults if env vars are not set
    
    # Uncomment following if you need to troubleshoot
    # env | sort
    
    if [ -z "$PORT" ];
    then
        PORT="8080"
        echo "PORT set to default $PORT"
    fi
    
    if [ -z "$MYSQLCS_USER_NAME" ];
    then
      MYSQLCS_USER_NAME="LocalMySQLUser"
      echo "MYSQLCS_USER_NAME set to default $MYSQLCS_USER_NAME"
    fi
    
    if [ -z "$MYSQLCS_USER_PASSWORD" ];
    then
      MYSQLCS_USER_PASSWORD="LocalMySQLPassword"
      echo "MYSQLCS_USER_PASSWORD set to default $MYSQLCS_USER_PASSWORD"
    fi
    
    if [ -z "$MYSQLCS_CONNECT_STRING" ];
    then
      MYSQLCS_CONNECT_STRING="localhost:3306/localDbName"
      echo "MYSQLCS_CONNECT_STRING set to default $MYSQLCS_CONNECT_STRING"
    fi
    
    
    echo "======"
    echo "Starting with the following values: "
    echo "PORT set to $PORT"
    echo "MYSQLCS_USER_NAME set to $MYSQLCS_USER_NAME"
    echo "MYSQLCS_USER_PASSWORD set to $MYSQLCS_USER_PASSWORD"
    echo "MYSQLCS_CONNECT_STRING set to $MYSQLCS_CONNECT_STRING"
    echo "======"
    
    # Update server.xml with env vars
    
    sed "s/__PORT__/${PORT}/g" tom-accs/conf/server.template.xml > tom-accs/conf/server.xml
    
    
    # Update context.xml with env vars
    
    sed "s#__MYSQLCS_CONNECT_STRING__#${MYSQLCS_CONNECT_STRING}#g; s/__MYSQLCS_USER_NAME__/${MYSQLCS_USER_NAME}/g; s/__MYSQLCS_USER_PASSWORD__/${MYSQLCS_USER_PASSWORD}/g;" tom-accs/conf/context.template.xml > tom-accs/conf/context.xml
    
    exec tom-accs/bin/catalina.sh run
    

    Note: The MySQLCS variables are are service bindings for the MySQL Cloud Service. The service bindings are setup using the cloud service GUI or by using a deployment.json file.

  4. Modify the start.sh script for your local environment if you wish to test the script locally.

Making Configuration Changes for ACCS

The launch script is set, now you need to update the Tomcat configuration files to use system properties for the values passed in to the application. The following steps detail the changes you need to make.

  1. Copy the TomcatHome/conf/context.xml file to context.template.xml.

  2. Edit the context.template.xml file.

  3. For the Store tag change the connectionURL attribute value to:

    connectionURL="jdbc:mysql://__MYSQLCS_CONNECT_STRING__?user=__MYSQLCS_USER_NAME__&amp;password=__MYSQLCS_USER_PASSWORD__&amp;useSSL=false"

    The sed script will replace the values wrapped in underscores "__" before Tomcat is started.

    context.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    
        <Manager className="org.apache.catalina.session.PersistentManager"
            maxIdleBackup="4">
    
          <Store className="org.apache.catalina.session.JDBCStore"
                 connectionURL="jdbc:mysql://__MYSQLCS_CONNECT_STRING__?user=__MYSQLCS_USER_NAME__&amp;password=__MYSQLCS_USER_PASSWORD__&amp;useSSL=false"
                 driverName="com.mysql.jdbc.Driver"
                 sessionAppCol="app_name"
                 sessionDataCol="session_data"
                 sessionIdCol="session_id"
                 sessionLastAccessedCol="last_access"
                 sessionMaxInactiveCol="max_inactive"
                 sessionTable="tomcat_sessions"
                 sessionValidCol="valid_session" />
        </Manager>
    
    </Context>
    
  4. Save the file.

  5. Copy the server.xml file to server.template.xml.

  6. Edit the server.template.xml file.

  7. For the first Connectortag under the Service tag change the value to "__PORT__".

  8. For the Engine tag remove the jvmRoute attribute and value. This is no longer needed since Oracle Application Container Cloud Service uses Oracle Traffic Director for load balancing instead of the Apache server. So this value would no longer be relevant.

    Your server.tempalte.xml file should now look like this.

    server.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
    
      <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
    
      <Service name="Catalina">
    
        <Connector port="__PORT__" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    
        <Engine name="Catalina" defaultHost="localhost">
    
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
    
          <Host name="localhost"  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>
    
  9. Save the file.

That completes the configuration changes for Tomcat server.

Updating the ClusterJsp Application

One change needs to be made to the ClusterJsp application for Oracle Application Container Cloud Service. We need to add a line to the HaJsp.jsp file that identifies the current container instance that has served the current page to you. Perform the following steps to make the change.

  1. Change into the clusterjsp/maven/src/main/webapp directory of the ClusterJsp applicatoin.

  2. Edit the HaJsp.jsp file.

  3. After the line that gets the server IP address, add this JSP code:

    <LI>Executed ACCS Container Name: <b><%= System.getenv("APAAS_CONTAINER_NAME") %></b></LI>

    This will provide the system generated container name for the container that served the request for the current page.

  4. Save the file.

  5. Change into the maven directory.

  6. Rebuild the application.

    mvn clean package

  7. Delete the old clusterjsp.war file and clusterjsp directory from the webapp directory for your Tomcat instance.

  8. Copy the newly generated clusterjsp.war file from the project's target directory to the webapp directory of the Tomcat instance.

  9. Start your test instance with the start.sh script so the new version of the ClusterJsp application is deployed.

  10. Test the Tomcat instance to ensure the application is deployed and working.

    Note: To test the session data persistence a local copy of MySQL needs to be running with the required database and table installed.

Setting up a MySQL Cloud Service Instance

Setting up a MySQL Cloud Service instance is not covered in this course. To see examples of how to configure the service, see the MySQL Cloud Service documentation. However, you still need to setup a MySQL database and table like that shown in the Configuring Tomcat forMySQL Session Sharing section of this OBE. The tomcat_sessions table need to be available in Oracle MySQL Cloud Service for the cluster application to work.

Creating Configuration Files for Deployment

Overview

The application is configured and ready for the cloud. Before it can be deployed to Oracle Application Container Cloud Service, a couple of configuration files are needed for deployment. The manifest.json is a required file that contains your launch command and metadata about your application. The deployment.json is an optional file that includes configuration information about your application. In addition, the configuration can be performed in the Oracle Application Container Cloud Service GUI.

Creating a manifest.json File

The mainfest.json file provides the launch command used for the application, Java version, and some metadata. In this example, the ./start.sh script is called to launch the application. Notice in the script that the tom-accs/bin/catalina.sh run command is used so that Tomcat executes in the foreground. The container expects an application to execute in the foreground until it completes. The following is a sample manifest.json for the Tomcat instance.

manifest.json


{
  "runtime":{"majorVersion":"8"},
  "command":"./start.sh",
  "notes":"Tomcat Cluster with MySQL Session Sharing"
}

This manifest file assumes that the Tomcat instance will be installed in the ~/tom-accs directory of the container.

Creating a deployment.json File

The deployment.json is an optional configuration file you can reference when deploying your application using the REST API.

deployment.json


{
  "memory": "1G",
  "instances": 2,
  "services": [
    {
      "id": "MySQL Service Info",
      "name": "YourServiceNameHere",
      "type": "mysqlcs",
      "username": "YourUserName",
      "password": "YourPassword"
    }
  ],
  "environment": {}
}

Here is a quick review of the fields in the deployment.json file.

  • memory: The size of each instance. One gigabyte in this example.

  • instances: The initial number of instances to create.

  • services: Information about services is included here. In this case, the environment variable data for the MySQL Cloud Service.

  • identifier: Just a string to identify what these valu pairs are for. Any string value is ok here, but it should be descriptive.

  • name: The actual name of the MySQL cloud service we are connecting to. The needs to match the name for the actual service instance.

  • type: This identifies which kind of service these values are for. In this case, the values are for MySQL Cloud Service.

  • username: The user name for the MySQL Cloud Service. This is used to log into the Cloud Service.

  • password: The MySQL password for this user name.

Deploying your Tomcat Instance for Oracle Application Container Cloud Service

Creating the Application Archive

To deploy an application to Oracle Application Container Cloud Service your application must be bundled in a properly formatted archive. The archive can be in the zip or tar.gz formats. The basic requirements are pretty straightforward.

  • The start.sh launch script must be in the root directory of the archive.

  • The manifest.json file must be in the root directory of the archive.

When the archive is decompressed, the start.sh script and manifest.json files are placed in the home directory of the container. For this Tomcat example, the Tomcat instance is placed in the ~/tom-accs directory.

Here are some sample commands to create the archive for this example.

zip -r tom-accs-app.zip tom-accs start.sh manifest.json

tar cvfz tom-accs-app.tgz tom-accs start.sh manifest.json

Where tom-accs is the directory containing the Tomcat instance.

Deploying to Oracle Application Container Cloud Service

To deploy to Oracle Application Container Cloud Service follow these steps.

  1. Open the Oracle Application Container Cloud Service Service Console.

  2. Click Create Application.

  3. Select Java as the platform.

  4. Enter a name for your application. Enter a Description as well if you wish.

  5. Select the Upload Application Archive option.

  6. Navigate to your application archive on your local machine and select your archive.

  7. Click Create.

Your application is deployed to Oracle Application Container Cloud Service. You should now be able to scale the application up or down and sessions will be shared between each instance.

Deploying Your Application Using the REST API

Before you can deploy your application, you must copy it to the storage service. The REST URL for the Storage Cloud Service can be found on the details page for the service. You need your Oracle Cloud service credentials (username, password, identity domain) to use the REST API. With your credentials, you create cURL scripts to upload your application to the storage service.

  1. Open a command-line window (or Terminal in Linux).

  2. Create a storage container named apps to store your applications using the following cURL command:

    Note: Replace the words in bold with your account credentials.

    curl -i -X PUT \
      -u <Username>:<Password> \
      https://<Identity-Domain>.storage.oraclecloud.com/v1/Storage-<Identity-Domain>/apps
  3. Upload your application archive (tom-accs-app.zip) to the storage container:

    curl -i -X PUT \
    -u <Username:Password> \
    https://<Identity-Domain>.storage.oraclecloud.com/v1/Storage-<Identity-Domain>/apps/tom-accs-app.zip -T <Path-to-local-file>/tom-accs-app.zip
    
  4. Deploy your application with the following script. The example script shows placeholders for the required information:

    curl -i -X POST  \ -u <Username>:<Password> \
      -H "X-ID-TENANT-NAME:<Identity-Domain>" \
      -H "Content-Type: multipart/form-data" \
      -F "name=Tomcat-Cluster" \
      -F "runtime=java" \
      -F "subscription=Monthly" \
      -F "deployment=<Path-to-local-file>/deployment.json" \
      -F "archiveURL=apps/tom-accs-app.zip" \
      -F "notes=Tomcat Cluster application" \
      https://apaas.<region>.oraclecloud.com/paas/service/apaas/api/v1.1/apps/<Identity-Domain>
    

    Here are a few key points about this example:

    • -H specifies headers that are added to the HTTP request.
    • -F allows cURL to submit data like it's coming from a form (so, POST as the HTTP method).
    • archiveURL specifies where your archive file is located. The URL consists of your application's name, a slash, and the archive's file name.

That completes the setup of the cluster. You should now be able to deploy and test the application.

Want to Learn More

Credits

Curriculum Developer: Michael Williams