Wednesday, June 10, 2009

JBoss AOP in a Real World scenario

See the following statement:

" Tell me what is happening between your Application Server and your Database"


AOP is not something really new, besides you can use AOP for many real scenarios nowadays, like the proposed above, so, lets do it.
Installing JBoss AOP distro in your JBoss AppServer

Download the latest JBoss AOP binary, unzip this in your hard disk, in the jboss-aop folder, you have 2 options for updating, one for JBoss 4.x and other for 5.x.
  • /jboss-aop-2.1.1.GA/jboss-40-install/jboss-aop-jdk50.deployer or
  • /jboss-aop-2.1.1.GA/jboss-50-install/jboss-aop-jdk50.deployer
Both contains a build.properties, which you must edit it and inform the following properties:
  • jboss.home= put here your App Server directory home
  • jboss.config= put here the profile which you will update the AOP capabilities (eg: aop)
In your shell, in the appropriated deployer installer dir, you will call the "ant " command, it will update your JBoss Profile.
Enabling AOP in your JBoss Profile

In your profile, in the folder $jboss_home/$profile/deploy/jboss-aop-jdk50.deployer/META-INF, you will edit the file jboss-service.xml , will change the EnableLoadtimeWeaving attribute to true, according the following image:

After you change the AOP service, you must copy to the bin directory of your JBoss, the jar file called pluggable-instrumentor.jar that is in the lib folder of your JBoss AOP home directory.

The last step, you must add the following parameter in the JAVA_OPTS in the run.conf file:

-javaagent:pluggable-instrumentor.jar

Done, your AOP is updated in your JBoss AppServer.

Intecepting every JDBC Call made from your AppServer

JBoss AOP is an AOP Framework, which combined with AppServer make this kind of task really easy, where once you have a .aop file, it is a "deployable" file, that JBoss will deploy and make our aspects live in the App Server.

We will create a simple Interceptor, which is a simple class that implements org.jboss.aop.advice.Interceptor , that everything we need, is present , see the following source code:

public class JDBCMetricInterceptor implements Inteceptor {

public JDBCMetricInterceptor() {

}

public Object invoke(Invocation invocation) throws Throwable {

StringBuilder builder = new StringBuilder();
try {
builder.append("\n\t============== JDBC CALL ===============");


if (invocation instanceof MethodInvocation) {
MethodInvocation mi = (MethodInvocation) invocation;
builder.append("\n\ttype: Method Invocation");
builder.append("\n\tmethod: " + mi.getMethod().getName());

Object[] args = mi.getArguments();

if (null != args && args.length > 0) {

builder.append(String.format("\n\tHey, I saw %s parameter(s)",
args.length));
for (Object object : args) {
builder.append(String.format(
"\n\tParameters sent: %s of %s",   object,  (null==object)? "Null parameter": object.getClass().getName()));

}

}


}

return invocation.invokeNext();
} finally {
builder.append("\n\tJDBC Invocation end");
builder.append("\n\t========================================");
logger.info(builder.toString());
}
}

}



First of all, you might think: "We can intercept the java.sql.Statement class... and that's all", but JBoss AOP can't do that with "Java Standard Classes". So we will define a "definition" that our target will be: "Every class inside the package of the HSQLDB driver , which is org.hsqldb.jdbc, besides these classes must implement the class java.sql.Connection, which we assume that will execute the SQL to the database", right? See the code of the jboss-aop.xml file:



*(..))">




Once you deploy the generated aop file, when you boot the AppServer, you will see the AOP logging our messages:

Ofcourse, create anything with JBoss AOP is easier when we have in Brazilian office some help from Flavia Rainone, thanks Flavia.

Have fun with AOP, and keep in mind that you may use that in many real scenarios, is not necessary to be so geek for find out some opportunity to use it.

Thursday, April 2, 2009

Smooks+JBoss ESB applied : Getting Quotes from YahooFinance

I've been doing some researching for creating a cool sample using CEP into JBoss, while I am still working on it, I decided put a simple sample using Smooks for transforming CSVs from Yahoo Finance into XMLs, which is a format much easier for integrating with everything else.

Getting Stock Symbols and Quotes from Yahoo Finance in CSV Format


Yahoo offers an URL that gives you information about the quotes, it is not a WebServices, "REST Service" or nothing especial or too complex, it is basically an HTTP URL, that you may pass some additional info, and you can see the Quotes information by a glimpse into a CSV output. Look the following URL format:

http://finance.yahoo.com/d/quotes.csv?s= a BUNCH of STOCK SYMBOLS separated by "+" &f=a bunch of special tags

These special tags you can get more information here

I decided use this URL: http://finance.yahoo.com/d/quotes.csv?s=RHT+MSFT+ORCL+JAVA&f=snb3pt1d1 , and what does these parameters means?

a) s= The symbols, in that case: Red Hat, Microsoft, Oracle and Sun Microsystems.

b) f= It means which information I wanna in my "report", I decided put:
  • s = symbol s - symbol
  • n- companyName
  • b- bid
  • 3p - last bid
  • t1 - time
  • d1 - TradeDate
The result will give me the following information:

[java] "RHT","RED HAT INC",17.90,17.68,"4:04pm","4/2/2009"
[java] "MSFT","Microsoft Corpora",19.33,19.31,"4:00pm","4/2/2009"
[java] "ORCL","Oracle Corporatio",18.83,18.58,"4:00pm","4/2/2009"
[java] "JAVA","Sun Microsystems,",8.38,8.00,"4:00pm","4/2/2009"

Time to make it available into my JBoss ESB.

Using Smooks

The only thing that I am doing for testing is send the data obtained from the Yahoo URL to my Service JMS Quee Gateway, you may use Commons Http Client if you want something more sophisticated, othewise you may create a simple code as you can see in the following code-listing:


public static void main(String args[]) throws Exception
{
SendJMSMessage sm = new SendJMSMessage();
sm.setupConnection();
StringBuilder quotesData = new StringBuilder();
try {
// Create a URL for the desired page
URL url = new URL("http://finance.yahoo.com/d/quotes.csv?s=RHT+MSFT+ORCL+JAVA&f=snb3pt1d1");

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {

quotesData.append(str + "\n");


}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}

System.out.println("Sending:\n" + quotesData.toString());
sm.sendAMessage(quotesData.toString());
sm.stop();

}





This is a basic JMS client (use the quickstarts as a template).

Now, the only I thing I have to do is configure my smooks-res.xml file as well as my "Smooks Actions" in jboss-esb.xml, in the following image, you can see on the left side the jboss-esb.xml and smooks-res:


The only thing I had done was editing some XML, and everything is ready.

This is one more practical example of JBoss ESB and its transformation engine.

Download the solution

You can download the solution from here

Tuesday, February 24, 2009

A Simple RestEasy Maven Archetype

I've been looking for better and faster ways to develop some of my solutions, while Gradle is quite promising in my opinion, I still prefer Apache Maven for collaborative projects, even Ant sounds good when you can predict any scenario for your application/project.

I had searching a lot about a RestEasy Archetype, but I haven't found. RestEasy is a project which Maven is strongly used, although I am not sure if I did my search properly, but just in case I create a simple RestEasy Archetype, which you can download from here.

Once you have Maven installed and configured, you just will unzip this zip file, and will type mvn install. You will see the following results into your console:

[INFO] [jar:jar]
[INFO] [install:install]
[INFO] Installing /Users/edgarsilva/redhat/dev/NetBeansProjects/resteasy-archetype/target/resteasy-archetype-1.0-SNAPSHOT.jar to /Users/edgarsilva/.m2/repository/org/jboss/resteasy/resteasy-archetype/1.0-SNAPSHOT/resteasy-archetype-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Wed Feb 25 04:26:00 BRT 2009
[INFO] Final Memory: 9M/16M
[INFO] ------------------------------------------------------------------------
edgar-silvas-macbook:resteasy-archetype edgarsilva$


Now, you are ready to create RestEasy projects using Maven Archetypes, to do that, you can use your preferred IDE or just can type in the console for instance, the following command:

mvn archetype:create -DarchetypeVersion=1.0-SNAPSHOT -Darchetype.interactive=false -DgroupId=sample -DarchetypeArtifactId=resteasy-archetype -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=org.jboss.resteasy -DartifactId=sample

This command, will create a project called "sample" which contains everything you need for developing and deploying RestEasy Applications into JBoss Application Server.

In the following image, you can see the project opened using NetBeans:


If you run mvn:install you will see Maven in action downloading everything required for building your project. In addition, this archetype includes JBoss AppServer tasks, which you can use for deploying, starting or stooping the server anytime you want. After typing mvn install, this goal will compile and generated a war file into target folder, however you may call the command mvn jboss:start that you will see the following output:

[jsilva@jsilva esresteasy]$ mvn jboss:start
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'jboss'.
[INFO] artifact org.codehaus.mojo:jboss-maven-plugin: checking for updates from central
[INFO] ------------------------------------------------------------------------
[INFO] Building esresteasy
[INFO] task-segment: [jboss:start]
[INFO] ------------------------------------------------------------------------
[INFO] [jboss:start]
[INFO] Starting JBoss...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Feb 25 16:30:56 BRT 2009
[INFO] Final Memory: 3M/74M
[INFO] ------------------------------------------------------------------------
[jsilva@jsilva esresteasy]$


Not only starting JBoss AppServer, you are also able to deploy your application using the command: mvn jboss:deploy :

[jsilva@jsilva esresteasy]$ mvn jboss:deploy
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'jboss'.
[INFO] ------------------------------------------------------------------------
[INFO] Building esresteasy
[INFO] task-segment: [jboss:deploy]
[INFO] ------------------------------------------------------------------------
[INFO] [jboss:deploy]
[INFO] Deploying /opt/java/workspace/esresteasy/target/esresteasy.war to JBoss.
[INFO] No server specified for authentication - using defaults
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Wed Feb 25 16:39:41 BRT 2009
[INFO] Final Memory: 3M/74M
[INFO] ------------------------------------------------------------------------



If you look the JBossApp Server console you can see your project deployed into JBoss:

16:39:39,812 INFO [TomcatDeployment] deploy, ctxPath=/esresteasy, vfsUrl=
16:39:39,930 ERROR [STDERR] 52 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider DataSourceProvider
16:39:39,935 ERROR [STDERR] 57 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider DefaultTextPlain
16:39:39,936 ERROR [STDERR] 58 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.StringTextStar
16:39:39,937 ERROR [STDERR] 59 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.InputStreamProvider
16:39:39,939 ERROR [STDERR] 61 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.ByteArrayProvider
16:39:39,941 ERROR [STDERR] 63 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.FormUrlEncodedProvider
16:39:39,942 ERROR [STDERR] 64 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.FormUrlEncodedProvider
16:39:39,944 ERROR [STDERR] 66 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Added built in provider org.jboss.resteasy.plugins.providers.StreamingOutputProvider
16:39:39,950 ERROR [STDERR] 72 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.providers - Adding built in provider org.jboss.resteasy.plugins.providers.IIOImageProvider
16:39:40,084 ERROR [STDERR] 206 [http-127.0.0.1-8080-1] INFO org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap - Adding scanned resource: esresteasy.Hello
16:39:40,087 INFO [STDOUT] FOUND JAX-RS resource: esresteasy.Hello



I am looking for an easy way to pass information of some users inputs to fill some information into my pom.xml, the same strategy used in seam-gen for instance and also in esb-gen, but I am still looking for how to do that.

Seems that Maven Archetype is changing or moving for a next generation (http://docs.codehaus.org/display/MAVEN/ArchetypeNG) , hopefully the actual archetypes are still working fine.

Friday, February 13, 2009

Combining ApacheCamel+BSF to make JBoss ESB polyglot

Some time ago I published here one of the ways I built for integrating services such as Apache Camel into JBoss ESB.

Hopefully Tom Fennelly (JBoss ESB CoreDev) also published an awesome documentation in how create new Listeners into JBoss via Schedulers, as I had done, in addition showing how do that using Groovy, which in my opinion is much better, safer and easier, I will show you the new implementation here right now.

When do I need new Listener into JBoss ESB?


Many many times I faced situations where some customers have unpredictable scenarios related with integration, that's why I liked Apache Camel since the first moment I had contact with! You can find out a clear and easy programming model(using DSLs), and a very nice set of components for integrating even with some providers not available in JBoss, like JBI(ServiceMix), Esper(CEP/ESP) etc.


Groovy in Action into ESB

Once the events in Camel happens into an specific RouteBuilder object, I just want to make it available as a "Service", so once JBoss ESB is running, the Camel is ready to answer any event.

To make it possible, I just created a classes called ApacheCamelListener, where I must fill some life-cycle methods, in order to ensure that everything will be executed properly in runtime, see the class: ApacheCamelListener.java:



package org.jboss.soa.esb.integration.apache.camel;

import java.io.File;
import java.util.logging.Logger;

import org.apache.bsf.BSFEngine;
import org.apache.bsf.BSFManager;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.listeners.message.ActionProcessingPipeline;
import org.jboss.soa.esb.util.FileUtil;

public class ApacheCamelListener {

private ActionProcessingPipeline pipeline;

protected CamelContext context = new DefaultCamelContext();

protected Logger log;

protected boolean started = false;

public ApacheCamelListener() {
log = Logger.getLogger(ApacheCamelListener.class.getName());
}

public void start(ConfigTree config) throws ConfigurationException {
// Create and initialize the pipeline..
pipeline = new ActionProcessingPipeline(config);
pipeline.initialise();
log.info("Initilizing ApacheCamel into JBoss Esb Server ....");
if (!started) {
CamelContext context = new DefaultCamelContext();

try {

log.info("...Adding Routes");

File scriptsDir = new File((config.getAttribute("scripts-folder")));

File[] scripts = scriptsDir.listFiles();

if (null != scripts && scripts.length>0) {

String theScript = null;

JBossEsbRoute router = null;

BSFManager manager = new BSFManager();

BSFEngine bsfEngine = manager.loadScriptingEngine(config.getAttribute("script-language"));

for (File file : scripts) {

theScript = FileUtil.readTextFile(file);

router = (JBossEsbRoute) bsfEngine.eval(config.getAttribute("script-language"), 0, 0, theScript);

log.info(router.toString());

context.addRoutes(new ScriptingRoute(router));

}

}

} catch (Exception e) {

e.printStackTrace();

}

try {
context.start();
started = true;
log.info("Camel is ready and waiting events");

} catch (Exception e) {

e.printStackTrace();
}
}

}

public void stop() {
try {

started = false;

try {
context.stop();

} catch (Exception e) {

log.info("Error trying close Camel Context: " + e.getMessage());
}

} finally {
if (pipeline != null) {
pipeline.destroy();
}
}
}

}

Time for Innovating : Putting Ruby, Groovy and other scripting language to dispatch messages to existing Services

You can use JBoss jBPM Actions to call deployed Services, based in the service name, service category and the variables, so what I did is basically is allow users via Camel listen many others components and call an existing Service, the following image can describe my idea:


Basically when I configure my ApacheCamelListener, I can configure the "scripts-folder" and "script-language" properties for my listener, these propertis basically works to tell where in the filesystem this listener will looking for "other dinamic listeners", and then you can tell the orign of the event, and when some message/even happens in the provider, it will be forwarded via ServiceInvoker converting a Camel Message to an ESB Message Aware. See the Listener configuration:




Or you can simply see the jboss-esb.xml configuration here:



Now, I can use a Ruby Script to invoke some service from my ESB Server, and using a IRC room to interact with JBoss ESB.


require 'java'
include_class 'org.jboss.soa.esb.integration.apache.camel.JBossEsbRoute'
route = JBossEsbRoute.new
route.from = 'irc:localhost:667#room1'
route.to = 'irc:localhost:667#room2'
route.serviceCategory= 'Transformadores'
route.serviceName = 'TransformaChamadaXMLparaISO'
return route




In Apache Camel, I must pass a org.apache.camel.builder.RouteBuilder, to say how interact with the message arrived in the configured protocol. To do that, I extended this class for a JBossEsbRoute, as you can see in the following code-listing:



package org.jboss.soa.esb.integration.apache.camel;

public class JBossEsbRoute {

private String serviceName;
private String serviceCategory;
private String from;
private String to;


public JBossEsbRoute() {
// TODO Auto-generated constructor stub
}

@Override
public String toString() {
return String.format("This ServiceInvoker will listen events from %s " +
"and will forward to Service %s from category %s and route to %s",
this.from,this.serviceName,this.serviceCategory, this.to);
}

public JBossEsbRoute(String serviceName, String category, String from, String to) {

this.serviceName = serviceName;
this.serviceCategory = category;
this.from = from;
this.to = to;
}


Here is my extension for Camel understands any script written in PHP, ruby or perl etc, and make it integrated with JBoss ESB:



package org.jboss.soa.esb.integration.apache.camel;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class ScriptingRoute extends org.apache.camel.builder.RouteBuilder {

protected JBossEsbRoute route;

public ScriptingRoute() {
// TODO Auto-generated constructor stub
}

public ScriptingRoute(JBossEsbRoute r) {

this.route = r;

}


@Override
public void configure() throws Exception {

from(route.getFrom()).process(
new Processor() {
public void process(Exchange e) {

Object message = e.getIn().getBody();

System.out.println("#########" +
e.getContext().getExchangeConverter().convertTo(String.class, e));


System.out.println("Received event: " + message);


}
}).to(route.getTo());


}



The Ruby Script, basically creates a new Instance of JBossEsbRoute, which I can use to register a new Event Listener as well as a Invoker for an existing Services hosted into JBoss ESB. The following code-listing will allow you figure out how it is done:




String theScript = null;

JBossEsbRoute router = null;

BSFManager manager = new BSFManager();

BSFEngine bsfEngine = manager.loadScriptingEngine(config.getAttribute("script-language"));

for (File file : scripts) {

theScript = FileUtil.readTextFile(file);

router = (JBossEsbRoute) bsfEngine.eval(config.getAttribute("script-language"), 0, 0, theScript);

log.info(router.toString());

context.addRoutes(new ScriptingRoute(router));

}

}


Now, any language supported by Bean Scripting Framework can be used to invoke services into JBoss ESB, using Apache Camel for Events notifying and even forwarding after get processed into JBoss ESB pipelines.

I will be updating the sources and publishing in GitHub, if you are interested in that idea, reach me via email into edgarsilva (using) gmail.com.

Hope you enjoy!

ps- JBoss Esb 4.5 with Embedded Console is really great!

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: