One more JBI component : SOAP Proxy

I just developped a new JBI component for Petals ESB. This component, named ‘petals-bc-soapproxy’ is based on the work I did on the standard SOAP binding component and provide an easy way to proxify SOAP based Web services with Petals ESB.

This component, based on Apache Axis2, uses a small part of WS-Addressing to provide the proxy feature. ‘Small part’ means that for now, by using Axis2, I need to bypass the mustUnderstand attribute of the WS-Addressing elements. Why? Because I need to use the WSA:To element to specify the Web service I want to finally invoke and I need to set the mustUnderstand attribute to false to bypass one implementation detail on Axis2 which is not ‘friendly’ with my own implementation. Why (again)?… By setting some mustUnderstand attribute to true in the SOAP message header, it means that the SOAP engine (ie Axis2) must understand the header during message processing. A mustUnderstand attribute set to true in the WS-Addressing header means that the SOAP engine must handle the WS-Addressing information and here I do not want to. If I set this attribute to true, I need to add the Axis2 addressing module, which will handle the WS-Addressing header, and will put all the addressing information in the Axis2 message context. I can do that and get the information from this context for for some reason it does not work like I expect… Maybe an Axis2 update will fix this…Need some time to investigate, and for now time is not my friend… So, here is how it work :

1. The SOAP client sends the SOAP message to the Petals SOAP Proxy (by default this service is exposed at http://localhost:8085/petals/services/SOAPProxyWebService). The SOAP message header contains the WS-Addressing information which will be used to reach the final Web service. A SOAP message sample is for example :


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsap="http://wsapi.petals.dsb.soa4all.eu/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Action>http://wsapi.petals.dsb.soa4all.eu/HelloService/sayHello</wsa:Action>
<wsa:To>http://localhost:7600/petals/ws/HelloService</wsa:To>
</soapenv:Header>
<soapenv:Body>
<wsap:sayHello>
<!--Optional:-->
<arg0>Say hello!</arg0>
</wsap:sayHello>
</soapenv:Body>
</soapenv:Envelope>

where http://localhost:7600/petals/ws/HelloService is the final Web service I want to invoke.

2. The SOAP message is handled by the SOAP proxy component, transformed as JBI message and sent to the right JBI endpoint.

3. The JBI endpoint gets the WS-Addressing information from the JBI message, the SOAP message from the JBI message payload and send all of this stuff to the final Web service. Invokcation response is sent back to the initial consumer through the ESB.

A simple schema of what happens with three ESB nodes is given in the figure below :

So, the main question is why using such a proxy and why not invoking the service directly? There are many answers to these questions and since I already said that the time is a missing resource, it will be probably part of a future article…

The first version of the component is available on the OW2 SVN repository under my sandbox (have a look to http://websvn.ow2.org/listing.php?repname=petals&path=%2Fsandbox%2Fchamerling%2Fproxy%2Fpetals-bc-soap%2F#path_sandbox_chamerling_proxy_petals-bc-soap_)

Note : Using SOAPUI for WS-Addressing testing works fine (even if I had some exchanges with SOAPUI guy (http://twitter.com/olensmar) on Twitter…)… Sorry to have doubts on SOAPUI!

Adding Routing modules in Petals ESB

Petals ESB is based on a highly modular architecture built using software components based on the Fractal component model.

In a previous article about WSDM monitoring (http://chamerling.wordpress.com/2009/11/04/petals-esb-live-monitoring-with-wsdm-and-gwt/), I was speaking about adding routing modules to the ESB router to intercept messages and to notify the monitoring system that messages are transmitted and received between service consumers and providers.

In the current article, I am going to show you how you can add modules to the routing layer of the service bus. In short, the routing layer is the component which select the right endpoint(s) to send the current message to. The routing layer has been decomposed into routing modules which are all called when a message is sent or received.

There are two types of routing modules the SenderModule (org.ow2.petals.jbi.messaging.routing.module.SenderModule) and the ReceiverModule (org.ow2.petals.jbi.messaging.routing.module.ReceiverModule) which both have right names ;) . All the sender modules will be called on message emission, the receiver ones will be called at message reception… Here are the Java APIs :

org.ow2.petals.jbi.messaging.routing.module.SenderModule


package org.ow2.petals.jbi.messaging.routing.module;

import java.util.Map;
import org.ow2.petals.jbi.component.context.ComponentContext;
import org.ow2.petals.jbi.messaging.endpoint.ServiceEndpoint;
import org.ow2.petals.jbi.messaging.exchange.MessageExchange;
import org.ow2.petals.jbi.messaging.routing.RoutingException;
import org.ow2.petals.transport.util.TransportSendContext;

public interface SenderModule {

void electEndpoints(final Map<ServiceEndpoint, TransportSendContext> electedEndpoints,

final ComponentContext sourceComponentContext, final MessageExchange exchange)

throws RoutingException;

}

org.ow2.petals.jbi.messaging.routing.module.ReceieverModule


package org.ow2.petals.jbi.messaging.routing.module;

import org.ow2.petals.jbi.component.context.ComponentContext;
import org.ow2.petals.jbi.messaging.exchange.MessageExchange;
import org.ow2.petals.jbi.messaging.routing.RoutingException;

public interface ReceiverModule {

boolean receiveExchange(final MessageExchange exchange,

final ComponentContext sourceComponentContext) throws RoutingException;

}

Implementing and adding modules to the Petals ESB router steps

1. Step one : Create your routing module by implementing the Sender and/or Receiver module interface(s) like, for example, just logging exchange information and date :


package com.googlecode.chamerling.blog.petals.router;

import java.util.Date;

import java.util.Map;

import org.objectweb.fractal.fraclet.annotation.annotations.FractalComponent;

import org.objectweb.fractal.fraclet.annotation.annotations.Interface;

import org.objectweb.fractal.fraclet.annotation.annotations.LifeCycle;

import org.objectweb.fractal.fraclet.annotation.annotations.Monolog;

import org.objectweb.fractal.fraclet.annotation.annotations.Provides;

import org.objectweb.fractal.fraclet.annotation.annotations.type.LifeCycleType;

import org.objectweb.util.monolog.api.Logger;

import org.ow2.petals.jbi.component.context.ComponentContext;

import org.ow2.petals.jbi.messaging.endpoint.ServiceEndpoint;

import org.ow2.petals.jbi.messaging.exchange.MessageExchange;

import org.ow2.petals.jbi.messaging.routing.RoutingException;

import org.ow2.petals.jbi.messaging.routing.module.ReceiverModule;

import org.ow2.petals.jbi.messaging.routing.module.SenderModule;

import org.ow2.petals.transport.util.TransportSendContext;

import org.ow2.petals.util.LoggingUtil;

@FractalComponent

@Provides(interfaces = {

@Interface(name = "logSender", signature = SenderModule.class),

@Interface(name = "logReceiver", signature = ReceiverModule.class) })

public class LogModule implements SenderModule, ReceiverModule {

@Monolog(name = "logger")

private Logger logger;

private LoggingUtil log;

/**

* {@inheritDoc}

*/

public void electEndpoints(

Map<ServiceEndpoint, TransportSendContext> electedEndpoints,

ComponentContext sourceComponentContext, MessageExchange exchange)

throws RoutingException {

this.log.info(LogModule.class.getCanonicalName()

+ " router module is sending a message exchange with ID = "

+ exchange.getExchangeId() + " at " + new Date());

for (ServiceEndpoint endpoint : electedEndpoints.keySet()) {

this.log.info("Selected endpoint : " + endpoint.getEndpointName());

}

// Do what you want...

}

/**

* {@inheritDoc}

*/

public boolean receiveExchange(MessageExchange exchange,

ComponentContext sourceComponentContext) throws RoutingException {

this.log.info(LogModule.class.getCanonicalName()

+ " router module is receiving a message exchange with ID = "

+ exchange.getExchangeId() + " at " + new Date());

// Do what you want...

return false;

}

@LifeCycle(on = LifeCycleType.START)

protected void start() {

this.log = new LoggingUtil(this.logger);

this.log.debug("Starting...");

}

@LifeCycle(on = LifeCycleType.STOP)

protected void stop() {

this.log.debug("Stopping...");

}

}

Note that the Fractal annotations are mandatory!

2. Add the modules to the Fractal descriptor files. The modules MUST be added to the JBI-Messaging.fractal configuration file (located in the src/main/resources of your favorite Petals ESB distribution) :

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

<!DOCTYPE definition PUBLIC "-//ow2.objectweb//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/fractal/adl/xml/standard.dtd">

<definition extends="JBI-MessagingType" name="JBI-Messaging">

<component definition="org.ow2.petals.jbi.messaging.registry.DistributedEndpointRegistryImpl" name="EndpointRegistryImpl"/>

<component definition="org.ow2.petals.jbi.messaging.routing.RouterServiceImpl" name="RouterServiceImpl"/>

<component definition="org.ow2.petals.jbi.messaging.routing.module.TransportResolverModule" name="TransportResolverModule"/>

<component definition="org.ow2.petals.jbi.messaging.routing.module.EndpointResolverModule" name="EndpointResolverModule"/>

<component definition="org.ow2.petals.jbi.messaging.control.JMXExchangeCheckerClientImpl" name="ExchangeCheckerClientImpl"/>

<!-- My logging module -->
<component definition="com.googlecode.chamerling.blog.petals.router.LogModule" name="LogModuleImpl"/>

<!-- Expose -->

<binding client="this.router" server="MonitoringModuleImpl.service"/>

<binding client="this.transportlistener" server="RouterServiceImpl.transportlistener"/>

<binding client="this.endpoint" server="EndpointRegistryImpl.service"/>

<binding client="this.exchangechecker" server="ExchangeCheckerClientImpl.service"/>

<binding client="this.storage" server="MonitoringStorageServiceImpl.service"/>

<binding client="MonitoringModuleImpl.router" server="RouterServiceImpl.service"/>

<binding client="MonitoringModuleImpl.storageService" server="MonitoringStorageServiceImpl.service"/>

<binding client="EndpointRegistryImpl.configuration" server="this.configuration"/>

<binding client="EndpointRegistryImpl.topology" server="this.topology"/>

<!-- Add logging module to router -->

<binding client="RouterServiceImpl.sendermodule-3" server="LogModuleImpl.logSender"/>

<binding client="RouterServiceImpl.receivermodule-1" server="LogModuleImpl.logReceiver"/>

<!-- router -->

<binding client="RouterServiceImpl.transporter-local" server="this.transporter-local"/>

<binding client="RouterServiceImpl.transporter-tcp" server="this.transporter-tcp"/>

<!--the order of collection of bindings is alphabetically inversed -->

<binding client="RouterServiceImpl.sendermodule-2" server="EndpointResolverModule.service"/>

<binding client="RouterServiceImpl.sendermodule-1" server="TransportResolverModule.service"/>

<binding client="EndpointResolverModule.configuration" server="this.configuration"/>

<binding client="EndpointResolverModule.topology" server="this.topology"/>

<binding client="EndpointResolverModule.endpoint" server="EndpointRegistryImpl.service"/>

<binding client="EndpointResolverModule.checker" server="ExchangeCheckerClientImpl.service"/>

<binding client="TransportResolverModule.configuration" server="this.configuration"/>

<binding client="ExchangeCheckerClientImpl.jmx" server="this.jmx"/>
</definition>

Important things here are :

1. Instantiate the component with line

<component definition="com.googlecode.chamerling.blog.petals.router.LogModule" name="LogModuleImpl"/>

2. Adding the module to sender and receiver modules list :


<binding client="RouterServiceImpl.sendermodule-3" server="LogModuleImpl.logSender"/>

<binding client="RouterServiceImpl.receivermodule-1" server="LogModuleImpl.logReceiver"/>

Note that the lists are alphabetically inversed (The logger module “sendermodule-3″ will be called before the sendermodule-2 and the sendermodule-1 modules).

Here we are, the module will be called at each message emission/reception. Note that this is a basic usage of routing modules, you can do many things with these modules like real time monitoring, security check, authentication, endpoint filtering, content based routing, etc etc etc

Karting Session PetalsLink

Rien de technique dans cet article, juste un grand merci à Gaël et Bertrand pour la session Karting d’entreprise d’hier après midi

SOA4All dans la newsletter Petals #2

Une entrée en Français pour une fois…
Une section dans la nouvelle newsletter de Petals est dédiée au projet sur lequel je travaille depuis plusieurs mois : SOA4All.


La principale contribution de Petals Link concerne évidemment l’infrastructure de service au cœur de l’architecture. Basée sur Petals ESB, elle doit concilier des exigences parfois contradictoires : très haute distribution des services, qualité de service, monitoring mais également facilité d’utilisation et de déploiement ainsi qu’une grande modularité.

La dernière revue s’est déroulée en octobre dernier dans les locaux de la Commission européenne. Cette revue de mi-projet (Mois 18) était spécifiquement dédiée à la démonstration de prototypes visant à valider les principaux concepts techniques de la plate-forme.

Nous avons fait la démonstration avec succès du module « Federated Distributed Service Bus » que nous étudions et développons conjointement avec l’INRIA (Institut National de Recherche en Informatique et Automatique).

Ce composant joue le rôle essentiel d’infrastructure de service très largement distribuée. Basé sur une architecture de type fédérée, il permet de rassembler des groupes de services utilisant des middlewares hétérogènes et obéissant à des règles de gestions propres.

L’article complet est disponible ici.

Petals Master 1.0 is out

Petals Master v1.0, the first official version of the Petals governance tool has been finally released on OW2 today. Here is the quick release note from the Team :

Petals Master 1.0, includes a lot of improvements for users, as well as optimisations, and nice new features :

  • Categorize your services, endpoints and enterprises with UDDI based categories or add your own categorization value sets
  • Community capabilities : Share ratings, tags and comments on registered services and endpoints with all users
  • Share additional information about services by uploading related documents. Supported related document types are: DOC, PDF, XML, HTML, XLS, PPT, TXT, RTF, ODT, ODS, ODP
  • Identify your Enterprises with UDDI based identification system (Thomas Register, Dun and Bradstreet (DUNS)), or add your own identification system)
  • Search registered entities with a UDDI V2/V3 compliant Inquiry WS API
  • Do all what you can do with Petals Master UI with the Petals Master specific WS API
  • SLA Management is disabled, but will be back soon, with lots of improvements: SLA enforcement, service contract creation and management based on information collected on execution environments
  • Integration with new Petals ESB v3.0 Camelia edition: Govern services and endpoints deployed in Petals ESB by just providing Petals ESB specific WS address and click “synchronize”. That’s all !

As mentioned, this tool is integrated with Petals ESB v3.x, so now you can govern services from your Entreprise Service Bus.
There are also several new tools which are connected to Petals ESB, I think that more news will come soon…

Petals ESB TIP : Setting logging level per JBI component

Just a quick tip to say that you can define the logger level for each JBI component you deploy into Petals ESB by setting things in the conf/loggers.properties of your favorite Petals distribution. If the component name is petals-bc-restproxy (the component I am currently developping), just define the log level like this :

logger.Petals.Container.Components.petals-bc-restproxy.level DEBUG
logger.Petals.Container.Components.petals-bc-restprox.handler.0 petalsConsole
logger.Petals.Container.Components.petals-bc-restprox.handler.1 petalsFile

The only DEBUG logs which will be displayed will be the petals-bc-restproxy ones.
Good to remember!

Petals ESB v3.0 is out

Petals ESB v3.0 is finally out (two years after the v2.0 release), there are many changes in this version but here are the main ones :

Petals ESB 3.0, includes a lot of improvements for users, as well as optimisations, and nice new features :
- Dynamic configuration, and hot-deployment of new nodes
- Redesigned webconsole for administration, and deleted statistics monitoring (based on OW2-OpenSUIT)
- SCA support: SCA engine (OW2-FraSCAti), and SCA designer (Eclipse)
- BPEL support: BPEL engine, and BPEL designer (Eclipse), with validation (based on a new BPEL engine!)
- WS Notification and WS-BorkeredNotification support (EDA)
- more and more things…

Integration with new Petals Camelia softwares :
- Petals Studio: Complete Eclipse development environment, for Petals ESB
- Petals Master: SOA Governance (OW2-Dragon)
- Petals View: Business flow monitoring based on Petals EDA feature (based on OW2-OpenSUIT)

We gave this release a name : Camelia.

Fractal Component Inheritance Limitations

Here is the problem I had this afternoon and I said really bad things on Fractal and Spoon (if we had a Fractal Box cf  http://wp.me/pcSx0-3U we will be able to have liters of beer to drink tonight…).
Here is the compilation stack trace :
[WARNING] FractalComponentProcessor >>  No value found for property ‘generatorClass’ in processor org.objectweb.fractal.fraclet.annotation.processor.FractalComponentProcessor
[INFO] ————————————————————————
[ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO] fail to execute

… which is really helpful…

After spending too much time on searching why, the cause was ’simply’ because my Fractal component (java class) was extending another Fractal component (java class). Not sure that it is a component problem or a component import/requirement one but when one component inherits one other it does not compile at all.

Good to know!

 

Update on november 13:

Sometimes things are strange… It seems that this bug has been fixed some months ago (according to the Fractal bug tracker…) but I have it when I try to extend a component which has already been processed by spoon… ie In the same project all works fine… The problem occurs when I have a fractal based project which depends on another one…

Pro/Cons PEtALS ESB Game

Here is the new game at PEtALS Link: If you say bad things on PEtALS ESB you MUST put money into the box. If you say good things, you can take a candy…
Some says bad things just to in order to buy some beers with the money…

 

The PEtALS Box

The PEtALS Box

and we soon be able to have many beers!

 

Money vs Candies

Money vs Candies

 

 

PEtALS ESB Live Monitoring with WSDM and GWT

In one of my previous posts (Adding Registry Listener in PEtALS), I spoke about adding a registry listener in PEtALS ESB. In the current article, I want to introduce how I used this feature to implement a live monitoring Web application.

Here are the different modules which are used in this Live Monitoring Tool :

  1. PEtALS ESB. The standard behaviour has been customized by adding a registry listener and a routing module (to be detailled below).
  2. Monitoring layer. This layer is an independant process which embeds a WS-Notification engine.
  3. A WS-notification subscriber. This is the module which will receive the notifications from the monitoring layer.
  4. GWT based Web application used to display monitoring data.

PEtALS ESB Extensions

Registry Listener
The role of the registry listener is to register a new monitoring endpoint into the monitoring layer when a new endpoint is available within PEtALS.

Routing Module
Since modules can be added dynamically inside the PEtALS message router, we have created a module which timestamp the messages. Once the message exchange is complete, a message exchange report is sent to the monitoring layer.

Monitoring Layer

The monitoring is in charge of creating monitoring endpoints through a management API. Once a monitoring endpoint is created, it is also exposed as a Web service. This newly created Web service exposes a WS-notification subscribe operation.
Another role of the monitoring layer is to receive raw reports from the PEtALS ESB, to process the report in order to generate a WSDM payload which will be send to subscribers.

WS-Notification subscriber

The subscriber subscribes, receives and stores notifications from the Monitoring layer. That’s all for that module ;o)

GWT Based Web application

The GWT Web application uses comet in order to display live service response time. The data used to display response time is the one received and stored into the database and of course the server part of the Web application have access to this database.

As a result, we have a really nice live Web application (live means that the chart gives real time result and is updated automatically when messages are exchanged within PEtALS Service Bus). Here are some screenshots :

Live Response Time

Live Response Time

SLA

SLA Violation

Next Page »


Me

Twitter

RSS My Photo (and more) blog

Flickr Photos

Maouh!!!

Futur grimpeur

A dada

La pomme

More Photos

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

More