Friday, December 5, 2008

Integrating XMPP into JBoss ESB

I am looking for a better way to integrate new providers into JBoss ESB, while I have no success on this journey I can share some thoughts about some cool stuff as I will show you know.

First of all I am using the Ignite opensource APIs and Products. In order to have my own Jabber Server, I installed Openfire, which is pretty easy.

Once I started the service I opened the Admin UI in my browser and did a very simple setup, you can see the Openfire opening the address: http://localhost:9090 :




I added 2 users: edgar and joão(John if english), my objective is that JBoss ESB will hold the buddy "Joao", where I can interact with them via my IM program that supports a XMPP/Jabber protocol, GTalk in windows for instance.

I wanna send some message from my IM program, and I wanna transform this "buddy message" into a ESB Message in the bus.

I am using a strategy to use Schedulers as my listeners, so I created a class that basically uses the Smack API to interact with Xmpp protocol. See my following scheduler:


package org.demo.smackesb;

import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.client.ServiceInvoker;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.listeners.message.MessageDeliverException;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.message.format.MessageFactory;
import org.jboss.soa.esb.schedule.ScheduledEventListener;
import org.jboss.soa.esb.schedule.SchedulingException;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Packet;

public class XmppListener implements ScheduledEventListener {

protected boolean started = false;
protected ConnectionConfiguration config;
protected XMPPConnection connection;

public void onSchedule() throws SchedulingException {

}

public void initialize(ConfigTree arg0) throws ConfigurationException {

try {
config = new ConnectionConfiguration("localhost", 5222, "es");

connection = new XMPPConnection(config);

connection.connect();

connection.login("joao", "123", "Home");

PacketFilter filter = new AndFilter(new PacketTypeFilter(
org.jivesoftware.smack.packet.Message.class),
new FromContainsFilter("edgar"));

PacketListener myListener = new MyTracker();

connection.addPacketListener(myListener, filter);

} catch (XMPPException e) {

e.printStackTrace();
}
}

public void uninitialize() {
connection.disconnect();

}

class MyTracker implements PacketListener {

public void processPacket(Packet packet) {

// dispatch messages to ESB from a Jabber Client

org.jivesoftware.smack.packet.Message msg = (org.jivesoftware.smack.packet.Message) packet;

System.out.println("Will forward the Message: " + msg.getBody());

try {

ServiceInvoker invoker = new ServiceInvoker("Extra", "Jabber");

Message message = MessageFactory.getInstance().getMessage();

message.getBody().add(msg.getBody());

invoker.deliverAsync(message);

} catch (MessageDeliverException e) {

e.printStackTrace();
}

}

}

}





Basically, I have my Service transforming incoming buddy message to ESB messages, see my jboss-esb.xml:


I am using Smooks as well to show that you can transform the incoming messages into really business messages to JBoss ESB.

See a screenshot of the demo working:





Download this demo from here, and if you wanna deploy into to your ESB, just drop it into your sample/quickstart folder, and call the command "ant deploy".

Another approach you may keep in mind when you are looking for some solution to integrate Xmpp with Java is Mobicents, which is a technology really nice for such integrations like that.

Hope you enjoy.

Tuesday, October 21, 2008

Integrating Apache Camel with JBoss ESB

Motivation

JBoss ESB supports the EIP(Enterprise Integration Patterns) in many aspects and counting with sofisticated resources, for instance: Drools for CBR(Content Based Router), or jBPM for Business Processor, besides of components for implementing Splitters, Aggregators, Filters and so on. However, not only to prove that JBoss ESB is an open and flexible ESB, I decided integrate it with Apache Camel, and this entry will show you some aspects of this work.

Little About Apache Camel

From Camel website (http://activemq.apache.org/camel/)

"Apache Camel is a Spring based Integration Framework which implements the Enterprise Integration Patterns with powerful Bean Integration.

Camel lets you create the Enterprise Integration Patterns to implement routing and mediation rules in either a Java based Domain Specific Language (or Fluent API), via Spring based Xml Configuration files or via the Scala DSL. This means you get smart completion of routing rules in your IDE whether in your Java, Scala or XML editor.

Apache Camel uses URIs so that it can easily work directly with any kind of Transport or messaging model such as HTTP, ActiveMQ, JMS, JBI, SCA, MINA or CXF Bus API together with working with pluggable Data Format options. Apache Camel is a small library which has minimal dependencies for easy embedding in any Java application."

In addition to this, Camel has several components that allows us apply an "Event-Driven" approach, the list of providers or protocols is really interesting, that's why Camel called my atention some months back, and working with a SOA project, where one of the requirements is listen many "non-common" protocols! So I believe that Camel can help me to avoid reinvent de wheel. Moreover, you can ask me: "Hey sir, tell me some about you bunch of components that you can use on Camel?", and I can answer with the following:
  • Apache Mina
  • RelaxNG
  • XMPP
  • Microsoft MQ
  • JCR
  • JBI
  • IRC
  • HL7
  • ESPER(CEP/ESP)
  • ATOM
  • Others , see more here

A Real Use Case: Turning On Camel into JBoss ESB

Depending of the point of view, you can definetely think that it is crappy, although I personally believe that Camel can work with JBoss ESB, once you have many events(Messages) happening on that protocols mapped by Camel's componets, you can eventually catch one of these messages(events) via Apache Camel, where we consider an "Unaware ESB Message from an Unaware Client" and publish it into a provider(protocol) that JBoss ESB supports, such as JMS, File System, WebServices, JBoss Remoting an so on. See the following image where I try describe visually this bahaviour:


In my case, I wanna listen everything what happens into a UDP server connection, and due to performance I would like to use something on top of NIO: So Apache Mina is one of my options, I could create a new JBoss ESB Courier(provider), new ProviderListener and everything from scratch, but I decided test Apache Camel, and my experience is that it was incredible cool,easy and under my performance testing really interesting, comparing with the previous UDP Server made using basic Java IO implementation.

First of all, I used the JBoss ESB's internal scheduler infrastructure, I enabled a SchedulerProvider to start my "Camel Listener", on this point I just wanna enable the Apache Camel run into ESB(inESB). See in the following code the provider configuration:


After this I created a listener for my service, just to tell which "Timer Event Listener" I wanna invoke when my CRON expression had been executed. In the following code, you can see my ESB Timer listener activating my UDP component listener based in Camel:

The class you can see in my listener is basically the timer listener processor that will be fired when the cron expression happens. In that case I am implementing the JBoss ESB's interface: org.jboss.soa.esb.schedule.ScheduledEventListener, especifically the method onSchedule(), which is fired my my listener according the CRON expression in my scheduler provider. In particular, on that method I invoke the Camel capabilities, as you can see in the following code:

The Camel portion is really easy to understand: This frameworks works with URI concept, so the compoenents "endpoints" no matter for input or output are configured using those URI and a Java DSL for it, in the example you can see above, We hve a method process which is resposible for handling the message/information that arrives in the configured component(endpoint), in that case I am telling that this method will listen eveything that happens in a UDP server in my host 0.0.0.0 in the port 2222, so the message that I receive I can do everything I want with, and after I route this information for another component, in that case we are forwarding the message to a filesystem, in that case a Filesystem can be a gateway for JBoss ESB, but we could route the info for a JMS or HTTP(JBR) gateway as well.

I believe I can improve a lot the integration between JBoss ESB and Camel, there are some issues, like redeployments in ESB and CamelContexts stoping and restarting that I can synchronize, but for awhile it is working pretty well.

I hope this post can be useful for you, if you need any further information please comment here.

More info:

http://www.jboss.org/jbossesb

http://activemq.apache.org/camel/

http://mina.apache.org/

Tuesday, October 14, 2008

Getting Started with JBoss ESB 4.4 and JBoss Tools 3-beta - Part I

Introduction

This entry introduce you how create ESB Projects using JBoss ESB with Eclipse IDE.

Softwares Used for this Tutorial

  • JBoss ESB Server 4.4
  • Eclipse Ganymed (latest version is ok)
  • Nightlly build (JBossTools-3.0.0.Beta1) for example: JBossTools-3.0.0.Beta1-N200810131557
  • JDK for sure :)
Installing the Software

In Eclipse Ganymed you have a way to avoid mess your Eclipse installation, you may use the dropins folder to make the reference between your original Eclipse installation and the folder were you had unziped your plugin and where the contents are located in. See the following links for more detailed information in how get it ready :

Configuring JBoss ESB in Eclipse

Once you have the installation process done, go to the Window/Prefereces, and expand the item JBoss Tools on the left, you will see the JBoss ESB Runtimes as one of the items in this section, click on it and in the right window click in the add button and select the JBoss ESB Server path. See the Image 1: and 2:

Image 1 - The Preferences Window
Image 2 - The JBoss ESBConfiguration
Creating a New Project

Now, go to the file/new/other ... And Select ESB/ESB Project, as you can see in the image 3, select this item and press Next Button:

Image 3 - Creating a new ESB Project

Fill "MyFirstEclipseESBProject" in the "Project Name" field and click on the "Finish" button.

After this, the Project is created and you will be ready to develop your services based on JBoss ESB. See the last image of this post:














Tuesday, October 7, 2008

esbgen: An easy way to create JBoss ESB Projects

The esbgen.sh or .bat is a simple command line tool that can help you create or just setup your first JBoss ESB Project.
If you think it could be interesting (for sure it is ;]), you can download the zip from esbgen from this JIRA ISSUE: https://jira.jboss.org/jira/browse/JBESB-2098, please VOTE there :)

In JIRA, you can find out the instructions, and here you can see esbgen in action on the screencast.

Hope you enjoy it!

Thursday, September 25, 2008

First look in jBPM BAM Console

This is an entry just to show you guys some screenshots from jBPM BAM Console, which we are doing a "technology-preview" for one client that is using heavily BPM concepts under JBoss Technologies, integrating with several legacy technologies.

Actually is very common people ask about BAM (Business Activity Monitoring), this discipline will be covered in JBoss jBPM through a Seam Application, using Ajax Technologies, RichFaces and other interesting resources, in addition to this, the BAM Console will offer an easy way to apply your company theme(css, colors, images) in the UI basically using Facelets.Here will go some screenshots of this great new in jBPM:

Dashboad

ReportsStatistics

So, who said that we are not working in Business Sphere when we talk about our JBoss SOA Platform? I think you can see a nice answer for this question :). As soon as possible, I will try blog more about these new features into our SOA related projects.

I would like to say thanks to my friend Eduardo Guerra, which is our JBoss Consultant working on this customer and who took these screenshots.

Thursday, September 4, 2008

POSOS: Plain Old Services Objects in JBoss ESB

Introduction

What? One more buzzword? You can complain with Burr Sutter, he is the guy that created this one for what some customers are wondering and they asked me how do that possible in JBossESB! The question is: "We would like use or reuse as easy as possible my just plain Pojos or "legacy beans" acting as ESB Actions configured in the listeners from protocol's providers in ESB.

ESB Traditional Actions for Experienced Developers...Easy Pojos for non-experienced ones

When you are writing your ESB Action classes, you have some rules to follow, for instance: a) extends AbstractActionLifecycle or , b) A Constructor with a ConfigTree object as a parameter , c) The process methods must returns a Message as well as you need a Message parameter using this type, so your simplest ESB Action is not that easy for non-experienced ESB Action developers.

Ok, Show me this POJO that can run inside JBoss ESB

See the following pojo:

Easy right? See the changes I did to enable this simple POJO as an Action Processor for a Listener in ESB, basically creating two annotations: @In and @MessageParam, which can tell me which methods from the pojo I have to invoke from my processor method in the action, as well as the parameters that I can get via the attributes stored in the Message.Body :

Basically, what I did was a first action, that is traditional action, where I put a value in the message body identified by the name "s", which is the value from "name" in the annotation @MessageParam, so the value will be transfered for my methods as a parameter properly, my action is very simpple as you can see in the following image:



On this point, I am using a strategy similar you can see at any regular Web application, which a portion can store some information into some context that will be accessible when necessary.

The convention here is that, I am telling that the annotation @In (like Seam) in the method must be processed into the BUS, in addition, the parameter @MessageParameter tells me that I have to get an object identified by name "s" from the Message.Boby from my ESB Message.

To do that, I created an Action that can accept into one of their properties, which a called "classses", a list of full classes names separated by commas. It is the easiest way to discover the classes without use any other sofisticated engine. See those actions configured into JBoss ESB Eclipse Plugin in the following image:


The following code shows how I configured my jboss-esb.xml, and the configuration of the actions. Look that I can fill in the classes property in how many annottated pojos I want, once they are annotated with our "Esb" annotations:

Once again, the only thing I did on my pojo was add the following annotations, as you can see in the following image:


Conclusions

Of course something much more sophisticated could be done, but like I did is easy for anybody understand, maybe in the future use some similar strategy that RestEasy does, or even create something in memory using JavaAssist.
Another point, I also created annother annotation @Out which would be useful when you change the information inside the parameter that you receive from Message.Body, but after the method you wanna take the changed value to the Message.body context with the changed information... Perharps it sounds like a bijection originally a concept from in JBoss Seam applied for JBoss ESB as well. The actual sources are not the most beautyful, but are working fine, e-mail-me if you need the source code, which basically runs as any other regular quickstart.

I hope someday see such feature like that out-of-the-box in JBoss ESB, while it is not true, I am happy with I have done.

Thursday, August 21, 2008

JBoss Profiler 2.0 Plugin for JON

I just started create a JON-plugin based on actual MBean that is the controller for execute the profiler commands, basically what I am doing for now is just "declare" the Services and Actions based on JMX-Actions, take a look on the actual result:

In addition, the Profiler Actions, I will be working a little bit more, when I get it done I will commit and create a distro into JBoss Profiler web site:

We are promoting a lot JON and RHQ-Project in Brazil, for many customers, JON is a good answer for an "Enterprise JBoss Management", if you have some MBeans ready that are really important for your Application, you can manage them using RHQ or JON much better than if you try do just using the legendary JMX-Console. Basically I did an rhq-plugin.xml describing my MBeans, see the following code:

For more information in how create Plugins for RHQ/JON:
  • http://support.rhq-project.org/display/RHQ/RHQ+Plugin+Community
  • http://support.rhq-project.org/display/RHQ/Writing+Custom+Plugins
Here some others screenshots:

New Commands available

Some Metrics, in a near future we will have profiler's reports available here

Installing, testing and Using JBoss Profiler 2.0 - beta2

This entry will show how start use the jboss-profiler beta2, first of all , download the software from here:
http://www.jboss.org/downloading/?projectId=jbossprofiler&url=/jbossprofiler/downloads/jboss-profiler-2.0.Beta2.tar.gz , save in some folder in your disk and unzip it.

Once you have the files in your disk, basically to setup jboss-profiler you will have to do the following steps:
  1. Copy jboss-profiler.jar to jbossas/bin
  2. Copy jboss-profiler.properties to jbossas/bin
  3. Edit jboss-profiler.properties in jbossas/bin to include the classes to be profiled
  4. Copy jboss-profiler-plugins.jar to jbossas/bin
  5. Edit run.conf (Unix) or run.bat (Windows) in jbossas/bin to include JBoss Profiler in JAVA_OPTS ( See you run.conf and add use this example: JAVA_OPTS="-javaagent:jboss-profiler.jar -Djboss-profiler.properties=jboss-profiler.properties -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000")
  6. Copy also to jbossas/bin the javaassist.jar if you are using JBoss AS 4.2.x
  7. Copy jboss-profiler.sar to jbossas/server//deploy
  8. Boot application server, if the following log appears everything is ok:
========================================================================= JBoss Bootstrap Environment JBOSS_HOME: /opt/java/jboss/profiler/as JAVA: /opt/java/jdk1.6.0_03/bin/java JAVA_OPTS: -Dprogram.name=run.sh -server -javaagent:jboss-profiler.jar -Djboss-profiler.properties=jboss-profiler.properties -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.net.preferIPv4Stack=true CLASSPATH: /opt/java/jboss/profiler/as/bin/run.jar:/opt/java/jdk1.6.0_03/lib/tools.jar ========================================================================= JBoss Profiler 2.0.Beta2 (Sun Microsystems Inc. 1.6.0_03) JBoss Profiler depends on external communication module 10:55:51,681 INFO [Server] Starting JBoss (MX MicroKernel)... 10:55:51,707 INFO [Server] Release ID: JBoss [Trinity] 4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)

Profiling your Application with JBoss Profiler beta2

In order to show the testing, I will do some profiler in JBPM classes, just to check what is happening behind the scenes. To do that I have to edit the jboss-profiler.properties in jbossas.bin directory to add the reference for JBPM's classes, as which is: org.jbpm.* (includes=org.jbpm.*).

Actually JBoss Profiler uses JMX and MBeans as its infrastructure which allows you profiler either JBoss 4.2.x or future 5.x versions. When you deploy the .sar file, you can see the profiler in the jmx-console as you can see in the following image:

You can do several options using the commands via JMX-Console, or as well as you can use command-line interface. At this moment we will use the JBoss profiler CLI, so go to jboss-profiler2-beta-2-folder/ in your shell (Unix or Win) and type the following command: java -jar jboss-profiler-client.jar , the result will be the following:

[jsilva@jsilva jboss-profiler-2.0.Beta2]$ java -jar jboss-profiler-client.jar
Usage: Client [-h host] [-p port]
startProfiler : Start the profiler
stopProfiler : Stop the profiler
snapshot : Take a snapshot
getSnapshot : Get a snapshot
listSnapshots : List snapshots
clearSnapshots : Clear snapshots
gc : Trigger garbage collection
enable : Enable the profiler
disable : Disable the profiler
load : Load a snapshot
save : Save a snapshot
diff : Difference between snapshots
add : Add classes (repository must be enabled)
remove : Remove classes (repository must be enabled)


As far you can see you have all these options to invoke profiler operations, for testing I used the following:

1- java -jar jboss-profiler-client.jar snapshot - Which generated a snapshot.
2-java -jar jboss-profiler-client.jar listSnapshots - Which shows all snapshots I had taken from my App Server.
[jsilva@jsilva jboss-profiler-2.0.Beta2]$ java -jar jboss-profiler-client.jar listSnapshots
1: 21 August 2008 11:23:54:296 -> 21 August 2008 11:24:17:117
2: 21 August 2008 11:39:05:687 -> 21 August 2008 11:39:31:255
3: 21 August 2008 11:41:59:145 -> 21 August 2008 11:43:25:691

3- java -jar jboss-profiler-client.jar getSnapshot 3 - Which tells to my client flush in my disk the info about my snapshot number 3, after this if you type a ls (dir for win), you can see the folder with thesnapshot timestamp. Please enter on this folder and list the files and folders again, the results would be something like:

[jsilva@jsilva 20080821114159145-20080821114325691]$ ls
caller classes classes.txt hotspots.txt methods.txt overview.txt packages.txt threads


On the files above you can see the information about your classes, in my case, I just did some operations with my simple bpm application. Take a look on the overview.txt report content:

From: 21 August 2008 11:41:59:145
To : 21 August 2008 11:43:25:691

Threads:
========
Thread-60 20063.47 ms

Most time:
==========
Count Ms % Method
1 13453.22 67.05 org.jbpm.persistence.db.DbPersistenceServiceFactory#getSessionFactory()
1 6078.74 30.30 org.jbpm.db.hibernate.HibernateHelper#createConfiguration(String, String)
3 134.04 0.67 org.jbpm.configuration.ObjectFactoryImpl#getObject(org.jbpm.configuration.ObjectInfo)
6 116.03 0.58 org.jbpm.configuration.ObjectFactoryImpl#loadClass(String)
1 84.82 0.42 org.jbpm.persistence.db.DbPersistenceServiceFactory#openService()
1 79.14 0.39 org.jbpm.persistence.db.DbPersistenceServiceFactory#getConfiguration()
1 56.08 0.28 org.jbpm.persistence.db.StaleObjectLogConfigurer#wrap(org.apache.commons.logging.Log)
14 29.55 0.15 org.jbpm.calendar.Day#(String, java.text.DateFormat, org.jbpm.calendar.BusinessCalendar)
24 4.53 0.02 org.jbpm.calendar.Holiday#(String, java.text.DateFormat, org.jbpm.calendar.BusinessCalendar)
2 3.51 0.02 org.jbpm.calendar.Holiday#parseHolidays(java.util.Properties, org.jbpm.calendar.BusinessCalendar)

Hotspots:
=========
Count Ms Avg % Method
1 13453.22 13453.22 67.05 org.jbpm.persistence.db.DbPersistenceServiceFactory#getSessionFactory()
1 6078.74 6078.74 30.30 org.jbpm.db.hibernate.HibernateHelper#createConfiguration(String, String)
1 84.82 84.82 0.42 org.jbpm.persistence.db.DbPersistenceServiceFactory#openService()
1 79.14 79.14 0.39 org.jbpm.persistence.db.DbPersistenceServiceFactory#getConfiguration()
1 56.08 56.08 0.28 org.jbpm.persistence.db.StaleObjectLogConfigurer#wrap(org.apache.commons.logging.Log)
3 134.04 44.68 0.67 org.jbpm.configuration.ObjectFactoryImpl#getObject(org.jbpm.configuration.ObjectInfo)
6 116.03 19.34 0.58 org.jbpm.configuration.ObjectFactoryImpl#loadClass(String)
14 29.55 2.11 0.15 org.jbpm.calendar.Day#(String, java.text.DateFormat, org.jbpm.calendar.BusinessCalendar)
2 3.51 1.76 0.02 org.jbpm.calendar.Holiday#parseHolidays(java.util.Properties, org.jbpm.calendar.BusinessCalendar)
1 1.35 1.35 0.01 org.jbpm.util.XmlUtil#parseXmlInputSource(org.xml.sax.InputSource)

Allocations:
============
org.jbpm.db.hibernate.StringMax 149
org.jbpm.db.hibernate.ConverterEnumType 49
org.jbpm.configuration.AbstractObjectInfo 32
org.jbpm.calendar.Holiday 24
org.jbpm.calendar.Day 14
org.jbpm.configuration.FieldInfo 9


Conclusion

JBoss Profiler 2 is built on top of really cool technologies, such as JBoss AOP and JavaAssist, feel you free to contribute with bug-fixes, documentation or with whatever you think could be valuable for the project, it would be a great chance for joining at a JBoss Project as a contributor, as far the actual contributors: Jesper Pedersen, Clebert Succonic and I are not dedicated as a full-time developers for Profiler, the work you can see as the result is a really big effort that Jesper and Clebert are doing. Beyond simple CLI interface, we are planning 2 really cool news, one of that is a new JBoss Profiler console based on RichFaces and related technologies, besides a Plugin for JBoss Operations Network/RHQ Project as well.

Visit: http://www.jboss.org/jbossprofiler/

Monday, August 4, 2008

RESTEasy+jBPM: A Proof of Concept for a Process Server

This is a post where I will try share some thoughts about where REST could be useful inside a SOA architecture based on Open Source Technologies using REST and Business Process Management, in that case we will be using jBPM and RESTEasy, which is the JBoss's implementation for JSR311- Java Restful WebServices.


RESTEasy

RestEasy is a project that is getting a good relevance in terms of integration with some projects inside JBoss.ORG and even other projects. If you are trying use a simple REST implementation you should take a look on this projects, basically there are few steps you must to do to put RestEasy working for your Application, so see the following Steps:
  1. Download the RESTEasy from JBoss.ORG

  2. There is a worth documentation in RESTEasy Wiki, which I strongly recommend you read it first, in addition to this, in order to see some foundation for practical REST application, you can read this great blog entry written by Carol McDonald

  3. To make the things works, I recomend you read this link: http://wiki.jboss.org/wiki/RESTeasyInstal, RESTEasy is pretty easy to understand and apply in even legacy Java applications, where you can expose some methods simply putting some annotations into your pojos. Basically the steps are:
  • RESTeasy is deployed as a WAR archive and thus depends on a Servlet container. When you download RESTeasy and unzip it you will see that it contains an exploded WAR. Make a deep copy of the WAR archive for your particular application. Place your JAX-RS annotated class resources and providers within one or more jars within /WEB-INF/lib or your raw class files within /WEB-INF/classes. RESTeasy is configured by default to scan jars and classes within these directories for JAX-RS annotated classes and deploy and register them within the system:

Custom configuration

RESTeasy is implemented as a ServletContextListener? and a Servlet and deployed within a WAR file. If you open up the WEB-INF/web.xml in your RESTeasy download you will see this:


<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>

<listener>
<listener-class>org.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>

<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>


The ResteasyBootstrap listener is responsible for initializing some basic components of RESTeasy as well as scanning for annotation classes you have in your WAR file. It receives configuration options from <context-param> elements. Here's a list of what options are available

  • And that's all! Everything you need is ready to run your REST
    Services in any JEE App Server.



Proof of Concept of a “Process Server”

We have several open source BPM Engines , I am using JBoss jBPM because I wanna show you a Web-Console where the process are running on, in addition a graphical tool to design my processes.
First of all I have a really simple “Controller” based on REST principles, nothing too complex or beautiful so far, but is useful, so I created a simple class called RestService.java where you can find many useful methods to operate business process using jBPM. Based on my own experience could be considered a “best practice” you design your URLs first, who knows some day we could create a tool (ant or maven), that could based on a text file containing one URL per line, where after reading it could create an abstract class with the methods. (Maybe a good way to forget any XML). Based on this practice I wanna give the ability for PHP, .net or even HTML interact with my “Process Server”, to do that I canhave the following URLs:
  1. /start/process/{some
    process}/{some user to be associated to my Swilanes}, it I can pass
    via a GET method and I can keep the process id as my return

  2. /signal/process/{the process id I
    must have stored somewhere}/{user} , via a GET I can navigate into
    my process

  3. /process/{process id}/add/var ,
    via a GET I can get a way to add some variables for my process
    execution

    Based on these 4 actions I defined above, I can show you now how implement them:


1- Start a new Process Instance

  • For jBPM you must have access to Context, which is the key object to operate processes using jBPM.

  • The following code shows this method in action:

@GET

@Path("/start/process/{processdefinition}/{user}")


@ProduceMime("text/plain")


public
String startProcesInstance(


@PathParam("processdefinition")String
processDefintion,


@PathParam("user")String
user) {


JbpmContext
ctx = JbpmConfiguration.getInstance().createJbpmContext();


try
{


ProcessInstance
instance = ctx.newProcessInstance(processDefintion);


instance.getContextInstance().setVariable("user",
user);


Token
t = instance.getRootToken();


t.signal();



ctx.save(instance);





return
new
Long(instance.getId()).toString();


}


catch
(Exception e) {


e.printStackTrace();


}


finally
{


ctx.close();


}


return
"ERROR";



2 - Signaling your Process

Once you have your Process Id, you can operate it and do whatever you want, this is one of the “Key-benefits” in jBPM, the ability to keep everything related to the process stored in the database, and not in the memory, it allow you have several application interacting with your Process Engine, for my testing, I have jBPM Server (jBPM+JBoss [could be any other AppServer]) in one IP address, and a TomCat with my simple REST application based in RESTEasy. Keep in mind, that having your process stored in regular tables in many Databases supported by Java, you shall create many kinds of applications, you may use Hibernate for persistence, query and cache as well as JDBC or even Spring helpers. See the following source code to allow this action:

@GET

@Path("/signal/process/{id}/{user}")


@ProduceMime("text/plain")


public
String signalProcess(


@PathParam("id")String
id,


@PathParam("user")String
user) {



JbpmContext ctx =
JbpmConfiguration.getInstance().createJbpmContext();


try{


GraphSession graphSession = ctx.getGraphSession();


ProcessInstance processInstance =
graphSession.loadProcessInstance((
new
Long(id)).longValue());


processInstance.signal();

ctx.save(processInstance);


return
processInstance.getRootToken().getNode().getName();



} catch

(Exception e ) {



e.printStackTrace();



return
"ERROR";



}



finally
{



ctx.close();



}


}






3 – Adding variables to your processes via a simple URL

  • For many reasons, you might need some variables for your processes, maybe for a decision taken or for anything else, so the following source shows how you can get the HttpServletRequest using the injection executed by the REST implementation. This method shows you how you can use contextual http objects, besides your variables from URL.

  • This could be really useful to capture other information, or even process some files not using GET method,
    but the POST method for instance, see the following implementation:

@GET


@Path("/process/{id}/add/var")


@ProduceMime("text/plain")


public
String addVariables(


@PathParam("id")String
id,


@Context
HttpServletRequest request) {



JbpmContext ctx =
JbpmConfiguration.getInstance().createJbpmContext();


try{


GraphSession graphSession = ctx.getGraphSession();


ProcessInstance processInstance =
graphSession.loadProcessInstance((
new
Long(id)).longValue());


Enumeration params = request.getParameterNames();

String param;


StringBuilder b = new StringBuilder();


while
(params.hasMoreElements()) {

param = (String) params.nextElement();


processInstance.getContextInstance().setVariable(param,
request.getParameter(param));


b.append(String.format("Param:%s=%s
is Stored in BPM Context\n"
,param,request.getParameter(param)));

}

ctx.save(processInstance);



return

b.toString();




}
catch
(Exception e ) {



e.printStackTrace();



return
"ERROR";



}



finally
{



ctx.close();



}


}


Time for Testing


As far you can see, everything on our example just returns basic “plain texts” as results, so we canuse those everywhere, in The Developers Conference (A Brazilian Java Conference) I did an examples really “old school”, I used a Borland Delphi 5 client, in terms of integration, I can get an existing Delphi or Visual Basic Application and integrate them with my “Process Server”, than for our Proof of Concept. My process for testing is really easy, as far you can see
in the following image:







This is a simple “Buying Process”, where could be used for many different scenarios, on our case, we try simulate a simple Delphi client interacting with this process. On Delphi's side, I need just a component to interact with HTTP requests
and nothing else, so in my case I used TidHTTP object for it.

My Process Server in Action

When we execute the following URL: http://192.168.161.1:8080/flowlet/start/process/buyticket/edgar , we are informing the process name: buyticket and
the user ir
edgar , and the result we can expect is a text with process id as the text returned via Http, see the following image:






After execute our method, the process instance id is 124, this id might be used for this process interaction, at this moment, my application is used a process which was deployed in my Process Server, and then we can create a new instance from the process called buyticket , so everything is stored in the database, and we can create any kind of
information based on database tables about our process instances,
such as: “Execution time”, “Troubleshooting” and so on.

Now,it's time to see our JBoss jBPM Console in action, take a look on my process listing and you can see the process instance id: 124:







And you can see where in the process, you process instance actually is stopped:






Now, it's time to navigate through the process instance, so I will execute the following rest URL:
http://192.168.161.1:8080/flowlet/signal/process/124/edgar , the result are the following screen shots:







This method, basically execute the signal into the process instance, and move the process to the next node, as far you can in the result and in the following image in the jBPM Console:







Adding the variables based on HttpServletRequest shall be executed using the
following URL:
http://192.168.161.1:8080/flowlet/process/124/add/var?payment=Yes&blog=Edgar
, so based on the Java Web technologies, you can assume that you have 2 variables: payment and blog, so what we wanna do now is to transfer these variables from http context, which are durable just while the server is running or some clustering replication in really durable information stored in the database as process variables. In addition to this capacity, imagine that we need some variable to define some execution path in the process instance handling, like a decision handler based on some expression(EL) based on some variable, for instance:
expression='{payment=="No"}'; this expression can decide in the decision-node “Is Payment Approved?” which path(direction) the process will go as the next execution node and transitions. See the results in the following images:







Now, we can signal the process again, and the results in our jBPM Server could be as the following :









Conclusion

Basically, as far you can see Process Server is something beyond a product, can be a concept that you can apply in many different ways, and one of that, for sure could be using Open-Source technologies, such as we had shown here on this entry.
















Wednesday, July 23, 2008

RESTEasy tips: Part 1

If you are planning build an application using RESTFul WebServices (I don't like this terminology), RESTEasy for sure could be your #1 option. Besides a cool documentation here, I will publish here a cool example of how use RESTEasy method to upload some file via HTTP protocol.


I don't wanna introduce nothing about REST, Bill Burke, already did it at this entry on his blog. I strongly recommend you read it first. Bill Burke is the RESTEasy Project leader, so you can find out accurate information about all over the Projec
t.

Figuring Out a Service to be used for the most Stupid and Poor HTML Client

When we are talking about integration, we never can forget about limited languages used to build an UI, so my example shows a really simple HTML, where I wanna inform any file and upload to a specific folder where my Web container is running on. The client to this service can be from the simplest html until the a really nice extJS in PHP or Asp.net.

<form method="POST" action="http://localhost:8080/flowlet/upload/process" enctype="multipart/form-data">
<label style="COLOR: #1a3663; FONT-WEIGHT: bold; FONT-SIZE: x-small; FONT-FAMILY: 'Verdana';">Please enter with the jar file location:</label><br>

<input type="file" size="50" name="file">
<input type="submit" value="Upload now!">

</p>
</form>


As far you can see, the action from my html form is just a simple URL and the method is POST, basically I will inform the file name, and then using Commons FileUpload I will upload a file using a RESTFul service.

Using javax.http.HttpServletRequest into your RESTFul Service

When you create your first service based on REST Model, you can feel really excited with REST approach, however you still need access some commons objects from a Java Web Application, so you may need access the Request object to get all their methods to interact with your application. In my case, I must get the Request object to use with my file upload component. To do that, with REST is really great, basically we will use something similar to what you can see in Dependency Injection in EJB3 or Seam. See the the code to implement a method to do this action:

 @POST
@Path("/upload/process")
@ProduceMime("text/plain")

public String uploadProcess(@Context HttpServletRequest req) throws Exception {

FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);

List items = upload.parseRequest(req);
Iterator iter = items.iterator();

while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();

if (item.isFormField()) {
System.out.println("FORM FIELD");

} else {
if (!item.isFormField()) {

String fileName = item.getName();
System.out.println("File Name:" + fileName);

File fullFile = new File(item.getName());
File savedFile = new File("/home/jsilva/Desktop/test", fullFile.getName());

item.write(savedFile);
}
}
}

return "OK";
}


You see, that I can catch the request through the annotation @Context as reference parameter in my simple Java method. You can get several other contextual object just using this annotation.

I hope this tip could be quite useful for your RESTEasy development.