Friday, August 24, 2012

JBoss ESB http-gateway service

We can call an ESB service in different ways; It can be invoked via queue messages, HTTP requests, webservices, and so on... In this post we will work with the JBoss ESB and see how we can invoke a service with a HTTP POST request.

Versions used:
- JBoss AS 5.1.0.GA (Community version)
- JBoss ESB 4.11 (not the standalone one, the version which is deployed in the AS)

Let's see the example!


pom.xml
<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>ar.com.pabloExample</groupId>
 <artifactId>helloworld-jboss-esb</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>helloworld-jboss-esb</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <jboss.home>/opt/jboss</jboss.home>
 </properties>

 <dependencies>

  <dependency>
   <groupId>org.jboss.soa.bpel.dependencies.esb</groupId>
   <artifactId>jbossesb-rosetta</artifactId>
   <version>4.11</version>
   <scope>system</scope>
   <systemPath>${jboss.home}/server/esb-default/deployers/esb.deployer/lib/jbossesb-rosetta.jar</systemPath>
  </dependency>
  
  <!-- For testing purposes -->

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.8.2</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>commons-httpclient</groupId>
   <artifactId>commons-httpclient</artifactId>
   <version>3.1</version>
   <scope>test</scope>
  </dependency>
  
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
   <scope>test</scope>
  </dependency>

 </dependencies>

 <build>
  <finalName>helloworld-jboss-esb</finalName>

  <plugins>

   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jboss-packaging-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
     <archiveName>helloworld-jboss-esb</archiveName>
    </configuration>
    <executions>
     <execution>
      <id>build-esb</id>
      <goals>
       <goal>esb</goal>
      </goals>
     </execution>
    </executions>
   </plugin>

   <!-- mvn jboss:hard-deploy -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jboss-maven-plugin</artifactId>
    <version>1.5.0</version>
    <configuration>
     <jbossHome>/opt/jboss</jbossHome>
     <serverName>esb-default</serverName>
     <fileName>target/helloworld-jboss-esb.esb</fileName>
    </configuration>
   </plugin>

   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
    </configuration>
   </plugin>

  </plugins>
 </build>

</project>

The jboss-maven-plugin is just a plugin to ease the process of copying the esb file generated to the jboss server. Of course this is not mandatory :)

The jboss-packaging-maven-plugin is the plugin responsible for creating the ESB file that will be deployed in the server.


jboss-esb.xml
<jbossesb
 xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.2.0.xsd"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.2.0.xsd"
 parameterReloadSecs="5">
 
 <services>

  <service name="helloWorldService" category="helloWorldCategory" description="Hello World" invmScope="GLOBAL">
  
   <listeners>
    <http-gateway name="http-gateway" payloadAs="STRING"/>
   </listeners>
  
   <actions mep="RequestResponse">

    <!-- This action prints the content of the message -->
    <action name="action1" class="org.jboss.soa.esb.actions.SystemPrintln">
     <property name="printfull" value="false" />
    </action>
    
    <action name="action2" class="ar.com.pabloExample.service.MessageCustomAction" process="process" />

    <!-- This action logs a user text and the service name -->
    <action name="action3" class="org.jboss.soa.esb.actions.ServiceLoggerAction">
     <property name="text" value="Message arrived" />
     <property name="log-payload-location" value="true" />
    </action>

   </actions>
  </service>
  
 </services>

</jbossesb>

In jboss-esb.xml we define a service with 3 actions:
"action1" & "action3" : they do some logging
"action2" : takes the "name" query parameter from the URL and creates the "hello <query parameter>" string which is put in the ESB message body

A listener is defined too. The HTTP listener will trigger the service whenever a POST request is make to a special URL (see the test section to see which is that URL).


MessageCustomAction.java
public class MessageCustomAction extends AbstractActionPipelineProcessor {

 public MessageCustomAction(final ConfigTree config) {
  // extract configuration
 }

 @Override
 public Message process(Message message) throws ActionProcessingException {

        HttpRequest req = HttpRequest.getRequest(message);
        Map<String, String[]> params = req.getQueryParams();
        
        String name = params.get("name")[0];
        
        message.getBody().add("Hello " + name);
  
        return message;
 }

}

Here we define the way to process the ESB message, we interpret it as a HTTP request and retrieve the "name" query parameter.


Let's test the ESB service!



HttpRequestServiceTest.java
public class HttpRequestServiceTest {
 
 private static Logger logger = Logger.getLogger(HttpRequestServiceTest.class);
 
 @Test
 public void httpRequestServiceTest() throws HttpException, IOException {
  
 HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("http://localhost:8080/helloworld-jboss-esb/http/helloWorldCategory/helloWorldService");
        post.setQueryString("?name=pablito");
        client.executeMethod(post);
        
        String result = post.getResponseBodyAsString();
        post.releaseConnection();

        logger.info("Service returned: " + result);
 }
}

In this test we simply do a HTTP post to the following URL:
http://localhost:8080/helloworld-jboss-esb/http/helloWorldCategory/helloWorldService

Note that using the default http-gateway the pattern to use would be like this:
http://<server>:<port>/<deployed esb file>/http/<category name>/<service name>


To run this test, create the ESB file and deploy it in the server:
  1. Set the jboss.home property in the pom.xml
  2. mvn clean package -Dmaven.test.skip=true jboss:hard-deploy
Now run the test with mvn test and you're done!


Download the example:


https://subversion.assembla.com/svn/pablo-examples/helloworld-jboss-esb

Tuesday, August 7, 2012

Installing JBoss ESB in JBoss AS 5.1

We will see the steps to install JBoss ESB in a JBoss AS instance. The ESB can be run in a standalone mode which we are not analyzing in this post. The steps to install the JBoss ESB are really simple and the installation already includes JBPM3 within it. In another post we will see different ESB examples.

Versions used:

JBoss AS 5.1.0.GA - Download
JBoss ESB 4.11 Community - Download
Eclipse Indigo SR2 - Download
JBoss Tools 3.3 for SOA - Download
Ant 1.8.4 - Download


Create a new JBoss instance, we will create esb-default based on default
cd /opt/jboss/server
cp default esb-default -r

In your download folder, extract the JBoss ESB zip file:
cp jbossesb-4.11.zip /opt
cd /opt/jbossesb-4.11
unzip jbossesb-4.11.zip

Now, let's get into the install directoy and create a new deployment.properties file
cd /opt/jbossesb-4.11/install/
cp deployment.properties-example deployment.properties

Now edit the new deployment.properties file and modify the following lines:
org.jboss.esb.server.config=default
...
org.jboss.esb.server.home=/jbossesb-server-4.5.GA
to these
org.jboss.esb.server.config=esb-default
...
org.jboss.esb.server.home=/opt/jboss-5.1.0.GA

Now, while in the install directory let's install the ESB in the AS:
ant deploy

To run the server:
./run.sh -c esb-default

In Eclipse IDE with JBoss Tools installed, in order to create a new ESB example:
File -> New -> Other -> ESB Project

In target runtime create a new server based on your esb-default instance. At the end of the wizard, choose Server Supplied ESB Runtime (because we've installed the ESB in the JBoss esb-default instance)

The following guides are essential while working with JBoss ESB:
ESB Tools Reference Guide
ESB Services Guide
ESB Programmers Guide