5/15/10

Extend ServiceMix Management features using Spring - Part 3

In the previous posts (Extend ServiceMix Management features using Spring - Part 1 and Part 2) I presented how to use spring to gain control over endpoint lifecycle and configuration via jmx. You might wonder till now "what happens to those custom changes if I have to redeploy the assembly, restart servicemix or even worse restart the server?". The short answer is that these changes are lost. The long answer is in this blog post, which explaings how to persist those changes and how to make the endpoint reload them each time it starts.


Part III: Modifying, Persisting and Loading Custom Configuration Automatically
In order to persist and auto load custom configuration upon endpoint start-up all we need is:
For persisting
  • A way to serialize the configuration in xml (jaxb2).
  • A way to persist the configuration (jpa/hibernate).
For auto loading
  • A way to intercept endpoint start and activate methods (spring aop).
  • A way to apply that configuration to the endpoint (beanutils).
The basic idea is that for each endpoint, the custom configuration can be serialized to xml and persisted and with the use of aop interceptors reloaded to the endpoint each time it starts up.

Step 1:Configuring persistence
For persisting configuration I am going to use JPA/Hibernate and MySQL.
I want to keep things as simple as possible, so I will create a table that will only contains 2 fields
  1. ID, the id of the endpoint which will be the primary key.
  2. CONFIGURATION, a text field that will hold the configuration in xml format.
This could look like this

The endpoint id can be retrieved by calling endpoint.getKey(). The configuration is the XML representation of the configuration (more details later).

The persistence unit, the entity and the data access object are things that we want to be reusable so they better be in a separate jar. I will call this management-support.

Let's start creating the new jar by adding the entity.

Now we can create the persistence unit. Note that in this example I am adding all the database connection information inside persistence.xml leaving pooling to hibernate. It would be better if I created a datasource, but for the shake of simplicity I will not.


Now its time to create a very simple dao for the EndpointConfiguration entity.


Step 2:Configuring Configuration Serialization
For each endpoint type that we want its configuration to be serialized and persistence I am going to create a pojo that contains all the properties that are managed. The pojo will be annotated with Jaxb annotations so that we can easily serialize it to xml. Before serialization takes place the pojo needs to be set the values of the current configuration. For this purpose I am going to use BeanUtils (spring beanutils). Now we can update our endpoint manager and add 2 methods (save & load of configuration) and the ConfigurationDao that was presented above.


The new endpoint manager will expose to the jmx the saveConfiguration and loadConfiguration managed operation.

Step 3:Configuring Endpoint Lifecycle Interception
In this section I will show how to intercept the lifecycle methods of the endpoint using spring-aop. Spring aop will be configured using cglib proxies. The goal is to intercept start and activate methods call the method load configuration on the endpoint manager and then proceed with the execution. So the interceptor needs to be aware of the endpoint that intercepts(determined by the pointcut definition) and the endpoint manager(will be injected to the bean that will play the role of the Aspect). So the interceptor will look like this



Note that we are intercepting both start and activate methods. This is because in some endpoints in order to refresh their configuration needs to be restarted while other need to be reactivated.
Step 4:Putting the pieces together
Now, its time to put all the pieces together. I am going to create a new jar the management support and add to it a generic endpoint manager(the base class for all entpoint managers), the endpoint configuration entity, the configuration dao and the persistance unit. The example project(wsdl-first) will be modified so that the HttpEndpointManager extends the generic endpoint manager and the http-su xbean.xml configures persistence and aop as explained above.

The generic EndpointManager
The POJO that represents HttpEndpoint configuration
The updated HttpEndpointManager

And finally the xbean.xml for the http service unit
The final configuration might seem a bit bloated. It can become a lot tidier by using xbean features, however this goes far beyound the scope of this post.

Preparing the container
For this example to run we need to add a few jars to servicemix

  • hibernate-entitymanager
  • hibernate-annotations
  • aspectjrt
  • spring-orm
  • the dependencies of the above
You can download the complete example here which will contains all the dependencies under wsdl-first/lib/optional.

Final words
I hope that you find it useful. Personally, I've been using it for quite some time now and I am very happy with it. Using this you can even alter the xslt of an xslt-endpoint using the jmx console without having to recompile, redeploy or restart your assmebly.

Extend ServiceMix Management features using Spring - Part 2

In the previous post (Extend ServiceMix Management features using Spring - Part 1) I demonstrated a very simple technique that allows you to expose endpoint lifecycle operations via jmx. Now I am going to take it one step further and expose the endpoint configuration via jmx.

If you haven't done already please catch up by reading Part 1.

Part II: Modifying the configuration of a live endpoint.

I am going to use the wsdl-first servicemix sample as modified in the previous post and expose the property locationURI of the HttpEndpoint to jmx using Spring's @ManagedAttribute annotation.

Step 1
Open the HttpEndpointManager and delegate the getter and setter of HttpEndpoints locationURI property.

Step 2
Annotate both methods with @ManagedAttribute

Now the HttpEndpointManager will look like this

Enjoy
Once the assembly gets deployed from the jmx console the locationURI property is exposed.
Note that once the new property is applied, the endpoint needs to be reactivated (call deactivate and activate from jmx as shown in the previous post).


As you can see in the picture I used jmx and changed the location uri from PersonService to NewPersonService, without editing, recompiling or redeploying the service assembly.

This approach is really simple and quite useful. Its biggest advantage is that even a person that has no knowledge of ServiceMix can alter the configuration. Moreover it simplifies the monitoring procedure of production environments.

The full source code of this example can be found here.

In the Part 3 I will demonstrate how these changes in the configuration can be persisted and how we can intercept endpoints lifecycle so that we have those changes loaded each time the endpoint starts.


5/13/10

Extend ServiceMix Management features using Spring - Part 1

Prologue
This is the first from a series of posts that demonstrate how to extend ServiceMix management using Spring's jmx and aop features. The version of SerivceMix that is going to be used will be 3.3.3-SNAPSHOT but I've been using this technique since 3.3 and it will probably can be applied to 4.x.

Problem
One of the most common problems I had with servicemix was that even the most simple changes in the configuration (e.g. changing the name of the destination in a jms endpoint)  required editing the xbean.xml of the service unit and redeployment. Moreover this affected the rest of the service units contained in the service assemblies, which would be restarted too.

An other common problem was that I could not start, stop and restart a single service unit. That was a major problem since I often needed to be able to stop sending messages, while being able to accept messages in the bus. The only option I had was to split our service units in multiple service units (e.g. inbound service unit and outbound service unit).

Solution
This series of blog post will demonstrate how we used spring in order to:

  1. Obtain service unit lifecycle management via jmx.
  2. Expose endpoint and marshaler configuration via jmx.
  3. Perform configuration changes on live production environements.
  4. Persisting these changes to database.
  5. Loading endpoint custom configuration from database.
Part I: Starting and Stoping Endpoints
Although all ServiceMix endpoint have start and stop methods these methods are not expose neither to jmx nor to the web console.
A very simple but usefull way to expose this methods to jmx is to use spring's jmx auto exporting capabilities.

Example:
As an example I will use wsdl-first project from servicemix samples in order to expose the lifecycle methods of the http endpoint to jmx. To do so I will delegate its lifecycle methods (start,stop) to a spring bean that is annotated with the @ManagedResource annotation and I will modify the xbean.xml of the http service unit so that it automatically exports to jmx beans annotated as @ManagedResources.

Step 1
The first step is to add spring as a provided dependency inside the http service unit.
Step 2
Create the class that will be exported to jmx by spring. I will name the class HttpEndpointManager. This class will be annotated as @ManagedResource, will have a property of type HttpEndpoint and will delegate to HttpEndpoints the lifecycle methods (activate,deactivate,start,stop). This methods will be exposed to jmx by being annotated as @ManagedOperation.
Step 3
Edit the xbean.xml of the http service unit and add the spring beans that will take care of automatically exporting the HttpEndpointManager to jmx.

Enjoy
You can now open the JConsole and use the HttpEndpointManager MBean to start/stop the HttpEndpoint without having to start/stop the whole service assembly.


Notes
Managing the lifecycle of endpoints in a simple assembly like the wsdl-first servicemix sample has no added value(since you can stop the service assembly). However this sample was chosen, since most servicemix users are pretty familiar with it. In more complex assemblies this trick is a savior(cause you can stop a single endpoint, while having the rest of the endpoints running). Moreover, this is the base for even more usefull tricks that will be presented in the parts that follow.

The full source code of this example can be found here.

In the second part of the series, I will demonstrate how you can extend this trick in order to perform configuration modification via jmx.