How to tell if the SOA Platform is running

When you start up a SOA managed server, there is a time interval when the managed server is up, but the SOA platform is not yet up. This is the time while SOA is loading all of the composites, and so on. Sometimes we want to know when SOA is actually ready, not just the managed server, but the soa-infra application. For example, if we wanted to start testing a composite, there would be no point doing that until SOA was running.

So it seems like a common requirement to be able to tell when SOA is ready. The most reliable way to do this is to check an MBean, and to make that available to an external waiting process (like a build job) we can expose the check using a simple Servlet.

In this post, we will look at how to do just that. The code in the sample is available in my git repo on java.net, you can grab it with:

git clone git://java.net/ci4fmw~ci-samples

Then look in the is-soa-running directory.

The code in this sample was written by Robert Patrick, and it is set up to build and deploy with Maven. It is written for SOA 11.1.1.7, but it will work for other versions too.

There is one library from SOA Suite that you will need to compile this code. Since we don’t have the libraries in any public Maven repository, you will need to add this library into your own Maven repository using a command like this:

mvn install:install-file
   -Dfile=/path/to/soahome/oracle_common/modules/oracle.jmx_11.1.1/jmxframework.jar
   -DgeneratePom=true
   -DgroupId=com.oracle.soa
   -DartifactId=jmxframework
   -Dversion=11.1.1.7
   -Dpackaging=jar

This will allow us to use that library in our build.

Let’s take a look at the project. We have a POM to build the project, a simple Java class to check the MBean, a simple Servlet to present the result, and some basic deployment descriptors. First, let’s look at the code that checks the MBean, this is in src/main/java/com/redstack/CheckSOAStatus.java:

package com.redstack;

/**
* @author robert.patrick
*/

import java.io.IOException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeDataSupport;

import oracle.as.jmx.framework.PortableMBeanFactory;

public final class CheckSOAStatus
{

  /**
   * check whether the SOA platform is running on this server
   */
  public static boolean checkStatus(String serverName) throws IOException
  {
    MBeanServer server = null;
    try {
      server = new PortableMBeanFactory().getMBeanServer();
    }
    catch (Exception e) {
      String msg = "PortableMBeanFactory.getMBeanServer() failed: " +
      e.getMessage();
      System.err.println(msg);
      e.printStackTrace(System.err);
      throw new IOException(msg, e);
    }

    ObjectName name;
    try {
      name = new ObjectName("oracle.soa.config:name=soa-infra,j2eeType=CompositeLifecycleConfig,Application=soa-infra");
    }
    catch (Exception e) {
      String msg = "Malformed Object Name: " + e.getMessage();
      System.err.println(msg);
      e.printStackTrace(System.err);
      throw new IOException(msg, e);
    }

    Boolean isReady;
    try {
      CompositeDataSupport compositeData = (CompositeDataSupport)
      server.getAttribute(name, "SOAPlatformStatus");
      isReady = (Boolean)compositeData.get("isReady");
    }
    catch (Exception e) {
      String msg = "Error getting MBean data: " + e.getMessage();
      System.err.println(msg);
      e.printStackTrace(System.err);
      throw new IOException(msg, e);
    }
    return isReady.booleanValue();
  }
}

Basically, we are connecting to the MBean server, and looking up an object named oracle.soa.config:name=soa-infra,j2eeType=CompositeLifecycleConfig,Application=soa-infra, then getting the SOAPlatformStatus attribute and then checking isReady. This gives us a true if SOA is finished starting up, or a false otherwise.

Now let’s take a look at the Servlet:

package com.redstack;

/**
* @author robert.patrick
*/
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CheckSOAStatusServlet extends HttpServlet
{
  public void doGet(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
  {
    String serverName = System.getProperty("weblogic.Name");
    boolean status = CheckSOAStatus.checkStatus(serverName);
    if (status) {
      res.setStatus(HttpServletResponse.SC_OK);
      PrintWriter out = res.getWriter();
      out.println("<HTML><HEAD><TITLE>Check SOA Status</TITLE></HEAD>\n");
      out.println("<BODY>SOA Server on " + serverName +
      " is finished loading its composites.</BODY></HTML>");
    }
    else
      res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
      "SOA Server on " + serverName +
      " is not finished loading its composites.");
    }
  }

Here we are basically just calling that class to have it check the status and reporting it back in the output. We also set the HTTP status code differently, so we can either check the text, or just the HTTP code to get the outcome.

Here is the web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.5">
  <servlet>
    <servlet-name>Check SOA Status Servlet</servlet-name>
    <servlet-class>com.redstack.CheckSOAStatusServlet</servlet-class>
    <run-as>
      <role-name>soa-admin</role-name>
    </run-as>
  </servlet>
  <servlet-mapping>
    <servlet-name>Check SOA Status Servlet</servlet-name>
    <url-pattern>/statuscheck</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>/statuscheck</welcome-file>
  </welcome-file-list>
  <security-role>
    <role-name>soa-admin</role-name>
  </security-role>
</web-app>

We are just mapping the Servlet to a URL – /statuscheck in this case, and also we define a role that this Servlet needs to run as. As we can see in the WebLogic deployment descriptor, we map this to the administration user:

<?xml version="1.0" encoding="ISO-8859-1"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90">
  <run-as-role-assignment>
    <role-name>soa-admin</role-name>
    <run-as-principal-name>weblogic</run-as-principal-name>
  </run-as-role-assignment>
</weblogic-web-app>

The POM is also fairly straight forward:

<?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>
  <groupId>com.redstack</groupId>
  <artifactId>statuscheck</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>statuscheck</name>
  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.oracle.soa</groupId>
      <artifactId>jmxframework</artifactId>
      <version>11.1.1.7</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>statuscheck</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <groupId>com.oracle.weblogic</groupId>
        <artifactId>weblogic-maven-plugin</artifactId>
        <version>12.1.2-0-0</version>
        <executions>
          <!--Deploy the application to the server-->
          <execution>
            <id>deploy</id>
            <phase>pre-integration-test</phase>
            <goals>
              <goal>deploy</goal>
            </goals>
            <configuration>
              <!--The admin URL where the app is deployed. Here use the plugin's default value t3://localhost:7001-->
              <adminurl>http://your.server:7001</adminurl>
              <user>weblogic</user>
              <password>welcome1</password>
              <!--The location of the file or directory to be deployed-->
              <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source>
              <!--The target servers where the application is deployed. Here use the plugin's default value AdminServer-->
              <targets>soa_server1</targets>
              <verbose>true</verbose>
              <name>${project.build.finalName}</name>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

We set the project coordinates, and list our two dependencies – the jmxframework library we saw earlier and the Java EE WebApp API. Then we have the normal configuration to tell Maven what version of Java to use to compile this, and how to build the WAR.

The weblogic-maven-plugin entry in the build section demonstrates how you could use the WebLogic Maven Plugin’s deploy goal to deploy the WAR to a server.

Then you can simply hit http://your.server:8001/checkstatus to see if SOA is fully up and running.

Enjoy!

About Mark Nelson

Mark Nelson is an Architect ("IC6") in the Platform Architecture Team in Oracle Development. Mark's focus area is continuous delivery, configuration management and provisioning - making it simple to manage the configuration of complex environments and applications built with Oracle Database, Fusion Middleware and Fusion Applications, on-premise and in the cloud. Before joining the Platform Architecture team, Mark was a senior member of the A-Team since 2010, and worked in Sales Consulting at Oracle since 2006 and various roles at IBM since 1994.
This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

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