SOA/BI Planet - English
After I recently got a grails app to work with spring-security, REST, and cache I wanted to try my luck and create a Google App Engine application using grails. Unfortunately, I think it's still pretty early as I ran into several issues early on. However, I see enormous potential once these issues get resolved.

I am using grails v1.1.1, app-engine plugin v0.8.5, with gorm-jpa v0.5. The first issue I ran into was deploying when using grails app-engine deploy. It failed to work subsequent times after I got the WAR initially deployed using /app-sdk/bin/appcfg.sh. It complained about not supplying an email address. Turns out there is a bug related to ant that should get fixed soon. The work around was simple enough; just hit Enter before typing in your email address.

Secondly, I was disappointed to find out that the spring-security (acegi) plugin wasn't compatible in GAE. Based on the compile errors I received locally, it appears spring-security depends on hibernate which is not an option in GAE (you either get JDO or JPA). I chose JPA because according to the documentation, JDO doesn't support any of the GORM dynamic finders methods where as JPA supports most of them. I guess now that I think about it, I'm not suprised acegi didn't work in GAE; just disappointed.

I found a minor issue I submitted concerning the default delete action in generated controllers. Seems the gorm-jpa plugin doesn't wrap the delete method around a [Domain].withTransaction closure which apparently is required (see the save action).

Finally, I was unable to get content negotiation working using the withFormat concept I described here. It worked locally running grails app-engine run, but threw an exception in GAE:

Caused by: java.security.AccessControlException: access denied java.lang.RuntimePermission getClassLoader

My guess is it's related to the Security issues they report on the FAQ:
"The current preview release of the Google AppEngine SDK has a bug that doesn't allow it to run Groovy code when the full permissions restrictions are used. This will be fixed in the next release, but in the meantime the development environment runs without emulating the permissions restrictions of the actual AppEngine environment."
Overall, I enjoyed the easy commands it provides to build, run, and deploy to GAE. The deploy was suprisingly pretty quick. I was able to view the exceptions in GAE easily. I was just prevented from making any real progress. If you want to see what I did get done, which was not much, check it out here http://james-lorenzen.appspot.com
Unfortunately, security and performance are often postponed early in the development process and are surpassed for new functionality. Reasonable justification usually includes cost and time. A few of the real issues I think are difficulty and lack of experience. I have to admit I am no security or performance expert, and implementing both early on would be time consuming and difficult. I've always heard security done after the fact is never as good if it's done in the beginning. So I wanted to share my experience using the spring-security (acegi) plugin in grails. Not only did I learn a lot about security, but also how to add support for REST Services and integrate Ajax clients using Extjs, how to enable caching, and inspect the performance of my app using Spring Insight that comes with the Springsource tc server developer edition.

Table of Contents

Spring-Security (Acegi)


Building authentication and authorization into your app in the beginning can be difficult, but with the spring-security plugin and grails it's super easy. There are other security plugins for grails, but I decided on spring-security/acegi since our team has contemplated using it on our project several times and it seems to have a pretty good history. This isn't a how to guide on using the security plugin, the documentation is pretty good. However, I do want to share some unexpected things I ran into and how I arrived at some of my conclusions.

When applying the security capabilities, I applied Test-Driven Development (TDD) to test my assumptions and changes. After I installed the plugin, I got started right away creating Users, Roles, and Requestmaps in Bootstrap. Requestmap is the domain model mapping roles to URIs. I prefered this method initially because I wanted to persist this information to the database. First I wanted to lock down the ability to delete a model I called Event. Here is a sample Bootstrap to accomplish it:

In this first test I created an admin role, mapped the admin role to /event/delete, and then added a new user to the admin role. This worked as expected but had a pretty big security hole (see Unexpected observations using spring-security plugin). The issue was unauthorized users were still able to delete events using the edit form. Underneath, grails submits to the index action and the controller handles directing the request to the delete action in the controller bypassing the security created by my Requestmap. I could hide the Delete button on the edit page, but malicous users could still expliot this hole.

So instead of using Requestmap, I annotated my controller actions. This method can properly handle the use case above and deny unauthorized access to the delete action.
I also learned that users have to be associated with a Role, otherwise they are unable to log in (see post). This seemed rather annoying since I was expecting to use the predefined roles: IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED, and IS_AUTHENTICATED_ANONYMOUSLY without having to associate all my users with roles. Two suggestions by Burt where to extend a Base model class that supported a default Role for all Users, or extend the GrailsDaoImpl class to remove the role requirement for users.

In summary, it seems best to annotation your controllers instead of using Requestmap and keep in mind that by default all users need to be associated with a role to login into your application.

REST Support for Extjs Ajax clients


Now that I have portions of my app locked down, I wanted to see how this effected Rich Internet Applications (RIAs) such as those that use Extjs. I wanted to answer 2 basic questions:
  1. How can javascript clients remove admin functions like Delete buttons?
  2. How could I modify my controller to support multiple clients that need HTML, JSON, or XML?
To test these questions, I downloaded and installed extjs into my grails app and created a simple grid based on the array-grid example in extjs. As part of this test I wanted to add a Delete button to the bottom toolbar, so that I could later enable or disable based on the users role.

I'm not super proud of how I contrived the roles and used them in javascript, but below is how I did it (If you were doing this for real, I'd make this a point of focus to come up with a better solution like creating a service that returned this information as JSON that could be called by an Ajax client).

Since there is no real easy way to get access to the users roles in a gsp, I set a bean in the controller that is used in the gsp. So in EventController I added the following grid action:
Then in a new grid.gsp I added the following:

Ext.onReady(function() {
var roles = new Ext.util.MixedCollection();
<% authorities?.each { %>
roles.add("<%=it.authority%>");
<% } %>
});
Then when I build the grid, I could eanble or disable the Delete button by doing:

roles.contains("ROLE_ADMIN")
That's pretty much how I disabled certain gui items that are restricted based on role. Again not very pretty, but effective.

Next, I wanted to populate my grid with real data from my controller. Fortunately for developers, grails excels in this area using convention over configuration using the withFormat content negiotation with URI Extensions. All I had to do was modify the controllers list action to support more than HTML responses:

def list = {
params.max = Math.min( params.max ? params.max.toInteger() : 10, 100)
def events = Event.list(params)
withFormat {
html { [eventInstanceList: events, eventInstanceTotal: Event.count()] }
xml { render events as XML }
json { render( [list: events] as JSON ) }
}
}
Here I easily add support for XML and JSON clients while also continuing to support clients who want HTML. One thing to note, is I like naming arrays in JSON; that is why you see the render([list: events]) syntax. Without that, the JSON response looks like this
{[{"class":"Event".....
instead of my preferred way
{"list":[{"class":"Event".....
Now all the client needs to do is request the URI /event/list.json or /event/list.xml.

Here is my complete javascript that includes the example JsonStore and Grid definitions.

Spring Insight and Caching


Next, I really wanted to try out the Spring Insight capability that is now included in the Springsource tc server developers edition. This would let you see into how grails and hibernate are operating on your behalf per request. For many web applications, there are typically 2 bottlenecks that degrade performance: 1) number of trips from the client to server 2) number of trips to the database. Using the Spring Insight tool, developers can see what SQL is being executed and how long it took.

To get started with Spring Insight I followed their Getting Started Guide. Once I had Insight running (http://localhost:8080/insight), I next ran 'grails war' to create a WAR that I could deploy to tomcat (Note: if you do this multiple times, redeploy, you have to be careful with what you do in your apps Bootstrap class. I was doing a lot of inserts that caused my WAR to fail deployment because by default when running 'grails war', grails defaults to the production environment which uses an update file database. So my Bootstrap was trying to add roles and users that already existed and that caused deployment to fail).

The WAR deployed fine and I was up and running watching my apps performance metrics in the Insight dashboard as I moved around in my app. What I noticed first was unexpected multiple JDBC calls when I thought caching was enabled by default in grails.


What I learned was you have to enable caching on a per domain or query basis. So I added the following to my Event domain model

static mapping = {
cache true
}
rebuilt and redeployed the war and was able to see fewer JDBC calls proving that my cached domain was working. I then added a new Event, viewed all events, and saw the extra select call since the cache was purged. Pretty impressive!

Next I wondered if spring-security was caching all the user and role information by default like it advertised. If not that could be a huge performance issue. Spring Insight was also able to prove that it was caching its results.

Overall, I learned a lot about grails, security, REST, extjs, caching, and spring insight and grails was the perfect platform to prototype these concepts in preparation for real production use.

Yesterday, we released new versions of two of the products in our GlassFish Portfolio, delivering on what we announced a few weeks ago at Oracle Open World.

The first is GlassFish Enterprise Server 2.1.1.  This is a minor release but includes some important bug fixes and updates to several component packages including JSF, Grizzly, Jersey, and  OpenMQ.  More details are on the community wiki.

Building upon GlassFish Enterprise Server 2.1.1 is GlassFish Communications Server v2.  Built in open-source in the Sailfin community, this product provides a robust Java EE and Session Initiation Protocol (SIP) convergence platform and in this release adds SIP session replication, Diameter support, and more.  Eduardo has a nice summary in The Aquarium.

You may download GlassFish Enterprise Server 2.1.1 or GlassFish Communications Server v2 so give them a try.  If you want more info or are interested in getting commercial support, added features, and more, contact us or try our online chat with someone that can help you.

As I mentioned last week, we were able to get a number of talks on Java EE 6 at Oracle Open World and the Oracle Develop conference going on as I write this in San Francisco.  In looking for folks thoughts and reactions to what they saw, I came across a blog entry by Cay Horstmann that I thought hit on a bunch of the key points we were hoping to share there so deserved a mention.

A few quotes from his blog:

"I cannot overemphasize how much simpler EE6 is than just about any web programming model I know. All of the bad parts of the old EJB are gone. No XML. No crazy packaging of WARs and JARs inside EARs. Annotate your beans and persistent objects, and let the container worry about the database, transactions, clustering, and so on."

"Similarly, if you haven't given GlassFish v3 a try, you are in for a very pleasant surprise. It is fast. Startup is not just faster than JBoss, but faster than Tomcat! Hot deployment works great, there is a nice admin UI and a scriptable command line interface, and the Eclipse and Netbeans integrations are first-rate. I can't see myself going back to Tomcat—there just would be no point."

If you want to learn more, visit glassfish.org and download GlassFish v3 Preview which will give you early access to these new capabilities Cay mentions.

Develop and use "aspects" to believe how Fuji made it easier for you! You can start right here with your own "echo" aspect development.

In Fuji Milestone 9 (M9), aspects became simpler and dynamic. Its a breeze to develop and use aspects.

From M9 onwards, you can also have aspects that are integral to your integration application, by scoping those aspects with the components of that application and taking advantage of that application's life cycle. Moreover, you can also develop "type"d aspects in that application itself by simple POJOs and then inject corresponding aspects.

A Java Developer develops an interceptor that can behave by its own set of properties. The interceptor can be "type"d , by which aspects can be injected to the Fuji runtime. The typed interceptor is an innovative design concept that cleared many obstacles to make aspects more appealing.

An aspects user can inject aspects to the fuji runtime by Fuji CLI (Command Line Interface), Integration Application, aspects archetypes and your own applications. He can also control the behavior of the aspects by changing the aspects property values through Fuji CLI.

Here, I explain developing an echo typed aspect, creating echo aspects and changing their behavior. Your "echo" aspect simply echoes your message at your desired message exchange point.

Do have the latest Fuji environment  and take the ride on.

Echo Aspect Development

Step1: Create a project in Netbeans using interceptor archetype.

In Netbeans choose, File -> New Project

In the dialog choose, Maven in categories and then select Maven Project in projects. Click Next -> for next dialog.

Choose Fuji Interceptor Archetype in the Maven Archetypes. Ensure the description says "Version: 1.0-M9-SNAPSHOT" . Click Next -> for next dialog.

Type EchoAspect at Project Name. You can change other values of your choice or leave as is. Click Finish

 Step 2: Chose FujiInterceptor.java for editing

In Netbeans, In Projects window, select Interceptor - EchoAspect (jar)

Expand Source Packages by clicking "+" sign next to the entry

Expand com.mycompany.EchoAspect by clicking "+" sign next to the entry

Select FujiInterceptor.java by double clicking on the entry

Step 3: Write Java code for "echo" functionality.

i. Define echoProperty variable in FujiInterceptor class as

private String echoProperty = "This is my default echo";

ii. Make the messageExchangeInterceptor function as "echo" aspect by having just the type property of the aspect as "echo".

@Intercept(type="echo")
public boolean messageExchangeInterceptor(MessageExchange exchange) {

Note: You can also leave the default priority and status annotated properties to inject an functioning aspect to Fuji.

iii. Print the value of echoProperty variable for echoing in the messageExchangeInterceptor.

System.out.println("From EchoAspect:" + echoProperty);

At the end of these changes, the messageExchangeInterceptor function looks like

    @Intercept(type="echo")
    public boolean messageExchangeInterceptor(MessageExchange exchange) {
        //TODO: add message exchange interceptor processing code here.
        NormalizedMessage msg = exchange.getMessage("in");
        // msg.setProperty("Fuji1", "Value1");
        System.out.println("From EchoAspect:" + echoProperty);
        return true;
    }

Step 4: Add dynamic behavior for the echo aspect  

You can make your aspect behave by your own set of  properties. These properties can be dynamically changed by Fuji CLI. And, the setConfiguration will be called whenever properties got set by the user.

 To have a dynamic echo aspect, add the following code to setConfiguration function in that same FujiInterceptor.java class

if(properties.containsKey("echoProperty")){
         echoProperty = properties.getProperty("echoProperty");
 }
The setConfiguration function looks like..

     /**
     * This method is invoked by the runtime when the interceptors
     * configuration is created/updated.
     *
     * @param interceptorName - name of the interceptor that this configuration applies to
     * @param properties - updated configuration properties
     */
     public void setConfiguration(String interceptorName, Properties properties)
     {
         // TODO: handle the configuration change notification
         // System.out.println("Configuration for interceptor "
         //   + interceptorName + " is  " + properties.toString());
         if(properties.containsKey("echoProperty")){
            echoProperty = properties.getProperty("echoProperty");
         }
     }

Step 5: Build and deploy Echo Aspect project

In Netbeans, Projects window, Select Interceptor - EchoAspect(jar) entry.

Right click on mouse and select Build. In the output window, observe the BUILD SUCCESSFUL message.

Make sure that your Fuji runtime is running.

Right click on mouse and select Deploy...

In the output window, Fuji Server tab, you can see message similar to

-> -> Apache Derby Network Server - 10.4.1.3 - (648739) started and ready to accept connections on port 1600 at 2009-10-08 19:07:27.922 GMT
Deploying D:\Netbeans\Aspects\EchoAspect\target\app.jar
 Installing bundle= file:/D:/Netbeans/Aspects/EchoAspect/target/app.jar
Deploy Results: 70

You can verify the deployment by Fuji CLI's list-configurations command, which should list com.mycompany.EchoAspect.FujiInterceptor.messageExchangeInterceptor.
-> fuji list-configurations

Configuration Names
-------------------
com.mycompany.EchoAspect.FujiInterceptor.messageExchangeInterceptor
org.glassfish.openesb.aspects.policy.PolicyImpl.execute
org.glassfish.openesb.aspects.log.LogImpl.execute
Command list-configurations executed successfully.

Thats it! You have already developed and deployed  "echo" typed aspect. And, Its time for injection of aspects.

Echo Aspect Injection

Aspects can be injected to Fuji runtime by CLI (Command Line Interface), by Integration Application or by your own application. Additionally, out-of-the-box aspects, like Log and Policy, can be injected by their maven archetype projects.

The "type" of your interceptor is instrumental for creation and injection of dynamic aspects to the Fuji runtime. 

Echo Aspect Injection by CLI command : create-aspect

The create-aspect command injects an aspect to the Fuji runtime. All interceptor scoping parameters, the "type" parameter and and aspect specific commands can be provided as part of the command. For example,

 -> fuji create-aspect type=echo name=echo-1 status=Active echoProperty="I am echoing from echo-1 aspect injected at Fuji CLI"
Created Aspect: echo-1

Command create-aspect executed successfully.
->

The above command injects "echo-1" aspect. The interceptor scope, status=Active, will trigger execution of this aspect, at every message exchange point of all the active messages. As per the logic of echo, for all active messages, we see the message,

->From EchoAspect:I am echoing from echo-1 aspect injected at Fuji CLI

delete-aspect command can be used to delete an aspect by its name.

Integration Applications

Aspects can also be injected to Fuji runtime by integration  applications. The life cycle of such aspects are tied to the application that contained them. Means, aspects are created when that application is installed and are deleted when that application uninstalled.

To inject aspects, go to aspects folder under Other Sources folder of any integration application of Milestone 9 and higher. Right click on that aspects folder and add property files. Each property file under this aspects folder, represents one aspect.

Have a properties file similar to the following to inject a echo-2 aspect ..

type=echo
name=echo-2
status=Active
echoProperty=This echo-2 aspect is created in the integration application.

Build and deploy your application and notice availability of echo-2 by Fuji CLI command, list-configurations.

You can have as many aspects as you want. You can also organize your aspects in sub-directories.

Your own applications

You can also inject aspects from your own applications! What all you need to do is package all your aspect properties files under META-INF/aspects folder in your deployment jar.

Deploy your application. JBI Framework bundle keeps track of bundles for META-INF/aspects folders and will inject aspects from the property files beneath it.

Dynamic Aspects

By now, you have already experienced how simple its easy  to develop your own aspects and various means of injecting aspects to the Fuji runtime.

And these aspects are dynamic. You can switch the injection point by changing the interceptor specific properties. And you can control the behavior of the aspect by changing your aspect specific properties.

Fuji CLI provides set-configuration command to change the properties of your "name"d aspect by its name.

For example, if you want to inject echo-1 at an endpoint, say, file1-endpoint, the command looks like

-> fuji set-configuration --name=echo-1 endpoint=file1-endpoint

from now onwards, the echo-1 aspect echoes only for the messages delivered to or originated from file1-endpont.

And to change the echo message for your echo-1,

-> fuji set-configuration --name=echo-1 echoProperty="Echo message is changed by set-configuration CLI"

Your setConfiguration method of the corresponding aspect's instance is identified and called by JBI framework!

Conclusion

As an java aspect developer, you just concentrate developing aspect's behavior method and handle the configuration method. And Fuji backs you up with dealing aspects injection, interception and dynamic behavior of your aspects.

Fuji is evolving at fast pace for more support and functionality.

Stay tuned for more advancements and start developing your aspects. And yes, its open source and contribute back.

When selling GlassFish ESB to partners, we (Sun) have to provide our partners with all the material allowing them a quick ramp-up on our technology.  That's the main reason why my group (Sales Engineers, Northern Europe) created a 3 days GlassFish ESB technical workshop.

My contribution to this workshop is a one hour module about WS-Security and GlassFish ESB (and OpenESB).  The idea is to demonstrate how easy it is to setup a WS-Security enabled channel between a web service provider and a web service client.

Specifically, the screencast tutorial shows how to establish mutual certificate authentication between an EJB based web service and a JBI service assembly, acting as web service client, in this case, a BPEL module.

The module is now released online, booth as PDF slides and as a screencast tutorial.

To learn more about WS-Security, I recommend this reading.

Enjoy ! 

In this document I explore the effects of selected web services security policies on SOAP message exchange in the GlassFish ESB v2.1.

This is a work-in-progress document, now at rev 0.3.

To provide early access I intend to release revisions of this document as significant new sections become available.

Rev 0.1: Content
•    Assumptions and Notes
•    Person Service XML Schema and WSDL Interface
•    Common XML Project
•    PersonSvc BPEL Module
•    PersonCli BPEL Module
•    JBI-based Person Service – Plain End-to-End
•    JBI-based Person Service – SSL with Server-side Authentication

Rev 0.2: Additional Content
•    JBI-based Person Service – SSL with Mutual Authentication (broken)
•    EJB-based Person Service – No security
•    EJB-based Person Service – SSL with Server-side Authentication

Rev 0.3: Additional Content
•    EJB-based Person Service – SSL with Mutual Authentication
•    JBI-based Person Service - Exploring WS-Addressing


More in CH05_WSSecurityExploration_r0.3.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.3.2.pdf/details

The original blog entry is located at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_1_ejb
I make this material available to help others work with the software, not to help others make money by syndicating my blog. This material can only be reproduced on Sun Microsystems sites. Other sites that reproduce this blog entry do so without permission and contrary to my intent.

Oracle Open World comes around every fall and while Sun has been a sponsor in the past, for the first time, at least in my recent memory, we will have sessions for Sun software, specifically around Java, and more specifically for my interests around Java EE.  And not only are we at Open World but we are at the smaller Oracle Develop event being run at the same time.

At Open World, the Java EE specific sessions are:

  • S312765 - Java Platform, Enterprise Edition: The Foundation and Future of Your Enterprise - Tom Kincaid - Monday 4pm-5pm Marriott Salon 4
  • S312767 - Easy Database Access from Java with Java Persistence API 2.0 - Linda DeMichiel - Wednesday 10:15am-11:15am Marriott Nob Hill AB

And at Oracle Develop they are:

  • S312810 - Java Persistence API 2.0: The Latest News - Linda DeMichiel - Sunday 10:30am-11:30am Hilton Golden Gate 8
  • S312811 - Developing RESTful Web Services with the Java API for RESTful Web Services - Marc Hadley - Sunday 11:45am-12:45pm Hilton Golden Gate 8
  • S312812 - Enterprise JavaBeans 3.1 Technology Overview - Ken Saks - Sunday 1:15pm-2:15pm Hilton Golden Gate 8
  • S312807 - Java Platform, Enterprise Edition 6 and GlassFish Application Server V3 - Roberto and Jerome - Monday 4pm-5pm Hilton Golden Gate 8
  • S312808 - A Complete Tour of the JavaServer Faces 2.0 Platform - Jim Driscoll (and Andy Schwartz from Oracle) - Monday 5:30pm-6:30pm Hilton Golden Gate 8
We will also have a Java EE pod at both Open World and Develop.  If you are attending either or both events, stop by and say hi and have a look at some of the great stuff that Java EE 6 is delivering in the areas of rightsizing, extensibility, and developer productivity.
Java CAPS 5.1.3

With Java CAPS 5.1.3 the default Java JMX agent is not active by default. You can follow the steps in this entry to enable the agent. If you cannot and don't want to modify the domain.xml configuration you can still connect to the Java CAPS built-in JMX agent. The protocol to access the JMX agent is based on the Sun Application Server 8 protocol because Java CAPS 5.1 was built around 2005, see here

The Java library that contains this custom protocol is contained in the "Deployment Command-Line Client". You can get it from your repository from the "Downloads" tab.

Get the deploycli.jar. As I am working with Groovy, I drop it in the groovy/lib folder. The following snippet shows how to connect to the JMX server:
def connectJCAPS513() {
	def url = 'service:jmx:s1ashttp://localhost:18000'
	def env = [
		"USER":"Administrator", 
		"PASSWORD":"STC",
		"jmx.remote.protocol.provider.pkgs":"com.sun.enterprise.admin.jmx.remote.protocol",
		"com.sun.enterprise.as.http.auth":"BASIC"
	]
	return getServer(url,env);
}
Java CAPS 6

Java CAPS 6 load the default Java JMX agent automatically. This is show in the server.log, for example:
[#|2009-09-08T18:32:11.078+0200|INFO|sun-appserver9.1|javax.enterprise.system.tools.admin|_ThreadID=14;_ThreadName=Thread-16;service:jmx:rmi:///jndi/rmi://elerognon:8686/jmxrmi;|ADM1504: Here is the JMXServiceURL for the Standard JMXConnectorServer: [service:jmx:rmi:///jndi/rmi://elerognon:8686/jmxrmi].  This is where the remote administrative clients should connect using the standard JMX connectors|#] 


So the url is easy to get. The JMX agent is protected by a password corresponding to the "admin" user. The following Groovy snippet shows how to connect:
def connectJCAPS6() {
	def url = 'service:jmx:rmi:///jndi/rmi://localhost:8686/jmxrmi'
	def env = [(JMXConnector.CREDENTIALS): (String[])["admin", "adminadmin"]]
	return getServer(url,env);
}
Conclusion

Whichever method or release is used to obtain the JMX server connection the JMX API is the same for Repository based projects. Therefore the scripts presented here run the same whichever method is used to get the JMX connection.

 What is Fuji simple service api?



The simple service provides the capability to invoke/interact with JAVA code outside of  JBI, Simple Service API provides a bridge between code that is hosted outside of a JBI component and service endpoints available on the NMR. The interface below shows what a user need to do in-order to use simple service api while provisioning an osgi service. for details see Fuji Simple Service API




/**
 * This interface represents a simple service provisioning contract with the
 * JBI runtime environment.  The invoke method is called when a message
 * exchange is addressed to this service instance.  Classes implementing this
 * interface must be registered in the OSGi service registry in order to be
 * available to consumers in the JBI runtime environment.  Further, the
 * service registration must contain a property called "org.glassfish.openesb.serviceName" which
 * contains the name of the service being offered.  Optionally, a property
 * called "org.glassfish.openesb.endpointName" can also be specified.
 * 
 */
public interface ServiceProvider { 
    ServiceMessage invoke(ServiceMessage message) throws Exception;
}


This blog shows how to integrate Fuji simple service api with spring/springDM  application, We will create a springDM application which instantiates the above provider Implementation , based on spring-config and spring-osgi-config files . In the diagram below the service provider is part of the spring application and the application context is created by the springDM module




Create a new springDM module, The Spring-OSGi project supplies a maven archetype that will create a SpringDM bundle project , example




 mvn archetype:create   -DarchetypeGroupId=org.springframework.osgi  
-DarchetypeArtifactId=spring-osgi-bundle-archetype 
-DarchetypeVersion=1.1.0  
-DgroupId=org.foo 
-DartifactId=org.foo.springdm.fuji
-Dversion=1.0

The structure of the project will look as below


 spring DM project



Change the pom , add dependency of the Fuji api



 go the src root of the application and add the following dependency to the springDM module pom




<dependency>
   <groupId>open-esb.fuji</groupId>
   <artifactId>api</artifactId>
   <version>1.0-M9-SNAPSHOT</version>
</dependency>



Write the POJO which implements ServiceProvider , note this POJO is part of the spring application, and can access any bean or the spring applicationContext, In the above diagram  org.foo.MyProvider.java , represents the POJO which implements the ServiceProvider Interface. here is a sample code




package org.foo;


import org.glassfish.openesb.api.service.ServiceMessage;
import org.glassfish.openesb.api.service.ServiceMessageFactory;
import org.glassfish.openesb.api.service.ServiceProvider;



public class MyProvider implements  ServiceProvider {
   
    ServiceMessageFactory msgFactory_;
   
    public ServiceMessage invoke(ServiceMessage message) throws Exception {
        // Print out the content of the message
        String payload = (String)message.getPayload();
        System.out.println(payload);
       
        // One way exchange, so there's no need to return anything
        return null;
    }


    public void setMessageFactory(ServiceMessageFactory factory) {
        msgFactory_ = factory;
    }
   
    public void setAnotherBean (AnotherBeanI bean){
     //make use the bean
    }


}  


Define the spring beans in the spring config file bundle-context.xml 




<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
       <bean name="anotherBean" class="org.foo.AnotherBeanImpl" />
       <bean name="fujiService" class="org.foo.MyProvider">
         <property name="anotherBean" ref="anotherBean"/>
       </bean>
      
</beans> 


Let us define the beans to be exported as OSGI service, Once the bean MyProvider is exported as osgi service,  any JBI component will be able to access this bean by sending a normalized Message see simple service api for more details 




<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/osgi"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> 


 <service id="fujiServiceOsgi" ref="fujiService"
  interface="org.glassfish.openesb.api.service.ServiceProvider">


  <service-properties>
   <beans:entry key="org.glassfish.openesb.serviceName" value="abcService" />
   <beans:entry key="org.glassfish.openesb.endpointName" value="endpoint1" />
  </service-properties>
 </service>


</beans:beans>




Based on the osgi service with the ServiceProvider Interface, an jbi  internal interpoint is activated, The activation of the endpoint is based on the osgi service properties as specified in the bean service definition shown above



  • org.glassfish.openesb.serviceName is used for the service name of the activated endpoint

  • org.glassfish.openesb.endpointName is used for the endpoint name of the activated endpoint


Install the springDM bundles into Fuji-Felix



In order to use springDM application one has to install all the required spring DM osgi bundles, see the set of osgi bundles which needs to installed and started, more details



Build and deploy the application




Go to the project folder and execute
  mvn clean build
In the felix console type install and start the springDM bundle just created
  install file:/...path_to_springDM_bundle..........org.foo.springdm.fuji-1.0.jar 


Invoking JBI-Endpoint from a spring application 



This would require a springDM application to import an osgi service registered by the Fuji/jbi runtime. Note the current Fuji implementation while activating an jbi endpoint , register an osgi service based on the endpoint properties, The endpoint properties are once again based on service name and the endpoint name, Assuming and endpoint had been activated by a JBI component with service-name = xyzService and endpoint-name=xyzEndpoint , how such a endpoint can be accessed from an spring application. In the diagram below the service consumer is part of the spring application .



 


 1. Import the osgi services, using the spring-osgi-config file, note the filter




<reference id="jbiService"
  interface="org.glassfish.openesb.api.service.ServiceConsumer"
  filter="(org.glassfish.openesb.serviceName=xyzService)"  />


2. Use dependency injection to set the service reference into a bean




<bean id="someBean" class="org.foo.BeanWithJbiServiceReference" lazy-init="false">
  <property name="serviceReference" ref="jbiService" />
  <property name="service" ref="jbiService" />
</bean>


3. Define the bean and Invoke




package org.foo;
import org.glassfish.openesb.api.service.ServiceConsumer;
import org.glassfish.openesb.api.service.ServiceMessage;
import org.osgi.framework.ServiceReference;


public class BeanWithJbiServiceReference {
  private ServiceReference serviceReference;
  private ServiceConsumer service
  public void setServiceReference(ServiceReference serviceReference) {
   this.serviceReference = serviceReference;
  } 
  public void setService(ServiceConsumer service) {
   this.service = service;
  } 
  public void invokeJBIService(Object payload) throws Exception{
   ServiceMessage message = service.getServiceMessageFactory().createMessage();
   message.setPayload(payload);  
   service.invoke(message);
  } 
}
 



Future Direction Idea is to provide capabilty which will let any spring bean or osgi service to be accessed seamlessly, based on service properties or configuration, Also Fuji going forward will provide native support for spring beans . Read On   

Check out new OpenSSO SDN article :

Enabling Web Service Security With OpenSSO WSS Agent

With the Oracle acquisition looming on the horizon, and the uncertainty that comes with it, it feels like many organizations within Sun are bringing projects in a state in which they can be transitioned in a clean way. Transitioned meaning adopted or abandoned.

I also find myself doing this: for instance I'm trying to put the finishing touches on JMSJCA, and trying to put Hulp in a state where other people can use it, etc.

Maybe it was in that light that a few days ago, I got a certificate from the SEED organization within Sun. SEED is a mentoring program within Sun in which I had the good fortune to participate. I also was a SEED mentor. Or perhaps I should let the speak for itself.

image

Two years ago I wrote a blog entry about Nested Diagnostics Contexts in GlassFish. The approach was based on custom Logger objects. Now, two years later when running GlassFish on AIX, an issue with that turned up: a deadlock. Digging into it, there are two lessons I'd like to share: one about deadlocks, and the other one about workarounds.

Deadlock in the JDK

At the time of my writing the NDC facility, calling addLogger() and getLogger() from different threads may cause a deadlock in the JDK classes. Why is this?

This is how the code in the Sun JDK was:

public class Logger {
...
    public static synchronized Logger getLogger(String name) {
	LogManager manager = LogManager.getLogManager();
	Logger result = manager.getLogger(name);
	if (result == null) {
	    result = new Logger(name, null);
	    manager.addLogger(result);
	    result = manager.getLogger(name);
	}
	return result;
    }
}
public class LogManager {
...
    public synchronized boolean addLogger(Logger logger) {
...
        Logger plogger = Logger.getLogger(pname);
    }
...
}

There is a problem if there are two threads calling these two methods. Say Thread 1 calls Logger.getLogger() in its application code, e.g.

public void doSomething() {
  Logger.getLogger("com.stc.test").info("doSomething!");
}

Now let's consider another thread Thread 2 tries to register a custom logger using addLogger(), e.g.

LogManager.getLogManager().addLogger(new Logger() {
...
});

There are two locks that come into the picture: one is the lock on Logger.class, and the other one on LogManager.getLogManager(). Thread 1 simply calls Logger.getLogger() which first locks Logger.class, and while having this lock, will call LogManager.addLogger(). This call will get a lock on LogManager.getLogManager(). This will try to lock Logger.class again, which is no problem because it already had the lock on that. Now consider Thread 2: it will first lock LogManager.getLogManager() through its call to addLogger(), and while having this lock, it will try to lock Logger.class through its call to Logger.getLogger().

So Thread 1 will lock first A and then B, while Thread 2 will first lock B and then A. A classical deadlock situation.

This is clearly a bug in the JDK. With the knowledge of this bug, as the developer of the custom logger, we can use a simple workaround for this problem. Before calling addLogger(), first lock Logger.class. By doing that, we can guarantee that the locks are called in the same order: first Logger.class and then LogManager.getLogManager().

This bug was actually reported by a customer, see bug report, and was fixed in 6u11 and 5.0u18. The LogManager now no longer calls Logger.getLogger(), so there's no locking of Logger.class anymore.

Deadlock in GlassFish

GlassFish installs its own LogManager, and there's some locking going on there too. It has an internal lock which it locks in addLogger():

    public boolean addLogger(Logger logger) {
...
    super.addLogger(logger);
...
    synchronized (_unInitializedLoggers) {
...
        doInitializeLogger(logger);
    }
}

And this calls Logger.getLogger() again.

    protected void doInitializeLogger(Logger logger) {
...
    Logger newLogger =
        Logger.getLogger(logger.getName(), 
            getLoggerResourceBundleName(logger.getName()));
...
    }

As a developer of the custom logger, we can still use the same fix: first lock Logger.class before calling addLogger() so that the locking sequence becomes: Logger.class, transient lock on LogManager.getLogManager() followed by a lock on _unInitializedLoggers, lock on Logger.class().

A fix in GlassFish would simply make addLogger() synchronized. An alternative fix is to make the synchronized block smaller: it should not extend over doInitializeLogger().

Deadlock with the IBM JDK

All was well until this was run on the IBM JDK. As it turns out, Logger.getLogger() doesn't lock Logger.class, it locks LogManager.getLogManager(). Now there is a new deadlock: Thread 1 calls Logger.getLogger() and by doing so, locks LogManager.getLogManager(), and then tries to lock _unInitializedLoggers and later tries to lock LogManager.getLogManager() again. Thread 2 calls addLogger() and by doing so locks first _unInitializedLoggers which later tries to lock LogManager.getLogManager(). The problem is back: the sequence of locking is reversed.

Lessons learned

The first lesson is that of the deadlock itself: one should be extremely careful when locking an object, and then calling into another object, especially if that object is meant to be a baseclass in a public API. Both Logger and LogManager may be overridden, and are clearly very public.

The second lesson is that instead of building workarounds, try to get a fix the original bug. Or at least try to have the original issue addressed while adding a workaround. In my case, I never filed a ticket against the JDK or against GlassFish. I should have known better.

... or not?

At this very moment, GlassFish v2.1.1 is about to be shipped, and we need GlassFish v2.1.1 on AIX for the upcoming CAPS release. A bug fix in GlassFish v2.1.1 is probably not going to get in. So I'm making yet another workaround: don't use a custom logger at all as to avoid the whole addLogger() problem. Instead, use standard Logger objects, but provide a custom filter that manipulates the log record. This will work on both unpatched versions of GlassFish, and also on unpatched versions of the JDK. Still, I hope the GlassFish problem will be fixed.

Deploying apps from GlassfishESB v2.1 to GlassfishESB v3.

There's lots of new functionality being implemented for GlassfishESB v3 as part of the Fuji research project. However a very important consideration is that existing projects that run in the current release (v2.1) will continue to work in the next major release (v3).

This how-to shows how to take a simple BPEL project from GFESBv2.1 and deploy and test it in the latest milestone release of Fuji (M8).

Play Screencast

I had to rush through the screencast very quickly to fit in the 5 minute limit imposed by Jing, so here's a run-down of what is happening

  • Start in the GlassfishESBv2.1 environment
  • I already have a simple service assembly with a HTTP BC and a BPEL SE Service Unit
    • The BPEL SU simply returns "Hello <string>" for whatever string is passed to it
  • Run the unit test to show it working
  • The Fuji runtime does not yet support Application Variables, so I replace the variable with the hardcoded value for the HTTP Port
    • Rebuild the application with the hardcoded value so it can be deployed to the Fuji runtime
  • Stop the GFESBv2.1 server so the Fuji Server can be started and use the same ports.
  • Milestone8 of Fuji requires the latest version of NetBeans, so start up NetBeans 6.7.1
  • The current fuji installer doesn't include BPEL SE, so you'll need to download and install it separately (plus the saxon library it depends on)
  • > curl -O
    http://download.java.net/maven/open-esb/fuji/components/installers/sun-saxon-library/1.0-M8/sun-saxon-library-1.0-M8.jar
    > curl -O
    http://download.java.net/maven/esb/open-esb/fuji/components/installers/sun-bpel-engine/1.0-M8/sun-bpel-engine-1.0-M8.jar
    

  • Start the BPEL SE and HTTP BC components
  • Now install the zip file for our BPEL application Service Assembly.
    • start the application
  • Check the the same URL for the WSDL file to ensure the server is running and the service is available
  • To test the project, I've installed the SOAPUI netbeans plugin.
  • Create a SOAPUI project, point it to the service, and test.
Screencast (again).
In this document I explore the effects of selected web services security policies on SOAP message exchange in the GlassFish ESB v2.1.

This is a work-in-progress document, now at rev 0.2.

To provide early access I intend to release revisions of this document as significant new sections become available.

Revision 0.1: Content
    * Assumptions and Notes
    * Person Service XML Schema and WSDL Interface
    * Common XML Project
    * PersonSvc BPEL Module
    * PersonCli BPEL Modules
    * Person Service – Plain End-to-End
    * Person Service – SSL with Server-side Authentication

Revision 0.2:Added Content
    •    JBI-based Person Service – SSL with Mutual Authentication (broken)
    •    EJB-based Person Service – No security
    •    EJB-based Person Service – SSL with Server-side Authentication


More in CH05_WSSecurityExploration_r0.2.3.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.2.3.pdf/details

As a healthcare enterprise looks after patients, information is gathered about various events that take place. Information about notable events, Admissions and Discharges, for example, is recorded in Hospital Information Systems or Patient Administration Systems. These systems typically broadcast event information in a form of HL7 messages for use by other enterprise systems, for example laboratory or diagnostic imaging. A stream of HL7 messages can be intercepted and processed to derive all sorts of interesting information.

The solution developed in this walkthrough deals with Excessive Length of Stay. Length of stay is defined as the period between patient’s admission to and discharge from the hospital. Statistical average expected length of stay is typically available for different kinds of patients presenting with different kinds of conditions. A significant variation from the average length of stay for specific patients may indicate complications, treatment errors, infections and other kinds of issues that the hospital needs to investigate. Notification of such incidents may help the hospital in addressing these issues and prevent future occurrences.

In this solution the Intelligent Event Processor is used to calculate the continuously updated average length of stay over a period of time and use it to compare against each event’s length of stay. It passes, to the downstream component, all events where the length of stay exceeds the average by 1 ½ times and ignores all others.

In the initial iteration, the solution reads a stream of discharge messages, containing admission date, discharge date, length of stay, and a bunch of other fields from a file and passes them to the IEP process. The IEP process keeps the window on the last 10 seconds worth of records and continuously calculates the average length of stay over all records in that window. As records are added to and removed from the window the average is recalculated. As each record is seen its length of stay is compared to the average length of stay of all records in the window at the time. If the length of stay in the current record is less then or equal to 1 ½ times the average at the same time the record is discarded. If the average is greater the record is ejected to the output and ultimately written to a file of exception records.

In a subsequent iteration the solution is modified to accept messages from a JMS Queue. This modification allows the solution to use the stream of discharge messages produced by the HL7 Processor solution, discussed in “HL7 Processor Demonstration - GlassFish ESB v2.1”, http://blogs.sun.com/javacapsfieldtech/entry/hl7_processor_demonstration_glassfish_esb.

In a further modification the solution is configured to send notification messages to another JMS Queue. Notification messages are processed by a different solution and sent to an email recipient.

The document, "Excessive length of Stay Healthcare IEP Demonstration", can be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/Combinned_Intelligent_Event_Processor_Demonstration_v1.0.pdf/details

The pre-built projects in the "Excessive length of Stay Healthcare IEP Demo Companion Archive" can be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/Healthcare_Demo_Combined_v1.0.zip/details

We've just completed work on the next milestone for OpenESB v3 (Project Fuji), the next-generation SOA integration platform based on OSGi technology. Fuji Milestone 8 is now available on the Downloads page. Watch for some new screencasts that show off our latest features, on this wiki page.

Being able to access the GlassFish JMX server through a firewall is essential when you've got big deployments that are secured by firewalls and want to perform remote monitoring and management. Thanks to Steve Esserey and other helpful persons who pointed me to a solution.

In GlassFish v2.1 patch 02 (I've also tested this on GlassFish v2ur2 patch08 and Glassfish v2.1 patch04 for good measure :) a flag has been introduced  that allow you to bind the port for the JMX server's RMI stub to a known port. (Previously this port was dynamic, which, dare I say; caused a few eyebrows to be raised with firewall admins.)

Add this to the JVM options in your domain.xml file:

<jvm-options>-Dcom.sun.aas.jconsole.server.cbport=18687</jvm-options>

Restart the domain, and pending openings in the firewall for the port given in addition to the port the JMX Agent is listening on (default is 8686) you should now be able to connect to GlassFish behind a firewall using JConsole, VisualVM or Sun GlassFish Performance Monitor

The JMX URL to connect on then becomes: service:jmx:rmi:///jndi/rmi://hostname.domain:8686/jmxrmi

VisualVM accessing GlassFish through a Firewall In  the screenshot above VisualVM is shown accessing GlassFish v2.1p2 (Actually GlassFish v2ur2 p08, but they're the same)

Also note that the port is 18686 in the screenshot above, this is just because i set my port to 18686 in the jmx-connector element in domain.xml to avoid a port conflict with a different GlassFish server on the box

<jmx-connector accept-all="false" address="0.0.0.0" auth-realm-name="adm
in-realm" enabled="true" name="system" port="18686" protocol="rmi_jrmp" security-
enabled="false"/>

Note that the MQ broker entry seen in the left hand pane is the VisualVM-MessageQueue plugin set to be released with OpenMQ 4.4. Here I've connected it to OpenMQ 4.3 which happily also works.

Normally testing this when you're not in control of the firewall takes time, the adjustments to GlassFish are done in a minute or so, but the second thing I learned today is perhaps the most important: Eat lunch with the sysadmins and operations guys every now and then! Thanks to Tommy Operations who had the openings in the firewall configured and propagated in minutes (not months which is usual in large organizations)


Another small exercise for the iep workshop. You can get it here. It's about keeping only the last derived value of a stream, according to the need of the client of the process. Not something complex, and this can be considered to be a building block of the iep modeling. You can also get the wink file how to build the application...

Have fun!


Serge

In this document I explore the effects of selected web services security policies on SOAP message exchange in the GlassFish ESB v2.1.

This is a work-in-progress document.

To provide early access I intend to release revisions of this document as significant new sections become available.

Revision 0.1: Content

  • Assumptions and Notes
  • Person Service XML Schema and WSDL Interface
  • Common XML Project
  • PersonSvc BPEL Module
  • PersonCli BPEL Modules
  • Person Service – Plain End-to-End
  • Person Service – SSL with Server-side Authentication

More in CH05_WSSecurityExploration_r0.1.pdf

This Note walks the reader through development of a GlassFish ESB v2.1based solution that addresses a Healthcare-related business problem. The Note elaborates on the healthcare background necessary to get a notion of what is being done and why, and provides detailed steps required to implement and exercise the solution to the business problem.

We will use the HL7 Binding Component, the File Binding Component, the JMS Binding Component, the SOAP/HTTP Binding Component, the BPEL 2.0 Service Engine, the JavaEE Service Engine, the HL7 Encoder and EJB-based Web Services in a JBI-based solution. 

This note is an update, for GlassFish ESB v2.1, of the original note  "HL7 Processor Demonstration - Java CAPS 6/JBI and OpenESB", to be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/00_HL7_Example_Development_Instructions_Final.pdf/details.

 Updated note is available at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/00_HL7_Example_Development_Instructions_Final_1.1.2.pdf/details

Hi all!

A new example has been added the iep workshop. It's on how to map an exernal DB to a relation update. This way, we can keep the external DB table up to par with the internal state of IEP. Fairly simple to do, but nice to have in your back pocket...

So, to take a look, just click here!

 At the same time, thanks all for taking the time to learn about iep! Over a 1000 downloads for the samples included in the workshop to date!


Serge

image

At JavaOne 2009 I gave a number of presentations. One was "Rethinking the ESB: lessons learned challenging the limitations and pitfalls" which I did with Andi Egloff. JavaOne sessions were not recorded this year, that is not by the JavaOne Organization. But I used an mp3 player to record the sessions I was involved in. I finally processed the audio and uploaded it. I also uploaded a PDF of the presentation:

Most people, when they think of load balancers, think "that's the network guy's problem." But Zeus' ZXTM software-only load balancer is actually designed for application developers.

But why would you bring a load balancer into your process? Simple - by offloading SSL and other tasks, and caching common requests, ZXTM can increase an application's performance by as much as 800%. It also has the means to improve application security by inspecting and scrubbing traffic, and by letting developers establish rules (using the Zeus TrafficScript scripting language) for masking sensitive information and handling suspicious traffic.

In this 12-minute GlassFish Unhooked podcast interview with Zeus product manager Owen Garrett, we cover in more detail the many ways ZXTM improves application performance and security, and offer documentation and free trial info to help you get started with ZXTM.

If you're already convinced that ZXTM will help you, feel free to jump right to our Zeus landing page for a white paper and links to free trial offers.

PS- I did this interview with a mouthful of novocaine. See if you can tell!


I mentioned Amazon.com lowering pricing for EC2 in my links entry today, but having great pricing is only useful if you have something to deploy on EC2.  And a great way to deploy applications is in GlassFish.

Now, anyone can install everything from scratch on their EC2 instance, but Amazon Machine Images (AMIs) are a great way to get a head start with a pre-installed/configured operating system and other software.  As you might expect, for someone wanting to use GlassFish there are several AMIs available.

My quick perusal came across the following GlassFish and related AMIs:

Find out more about GlassFish on EC2 here.

If answer is yes, then OpenSSO has a solution now, that works seamlessly on all containers supporting JAX-WS (which is the base for any Web Service)... including Glassfish, Tomcat, JBoss, WebLogic and WebSphere.

Download new Web Service Security Agents openssowssagents.zip, extract the zip and follow top level README file.
To try out included Web Service Client and Web Service Provider samples, follow samples/README file.

W3C has recently released W3C Candidate Recommendation for soap over jms, http://www.w3.org/TR/soapjms/


The above document specifies how SOAP should bind to a messaging system that supports the Java Message Service. Binding is specified for both SOAP 1.1 and SOAP 1.2.



What does this bring to the table?



  • The primary objective is to ensure interoperability between the implementations of different Web services vendors

  • Also some providers of Web services use intermediary services such as routing gateways; or SOAP/HTTP to SOAP/JMS gateways, they will be interested in the standards

  • Reliable way of delivering soap message



Can interoperabilty be an issue here?


Binding soap to JMS leave the other platforms which are not based on java


Note some of the existing capabilty which some of the vendors offer


I've been asked a number of times about how one can create a template for scripting the Application Configurations a Binding Component supports so I thought I'd whip up a little recipe on it.

The asadmin command create-jbi-application-configuration supports a property file, which makes it easy to externalize the environment specific configuration for a Binding Component for a given environment.

The content of the properties file varies from binding component to binding component.
Getting the names of the supported properties is easy.
here's how:

 

1) Create a sample application configuration on a binding component using the web admin console.I created a simple configuration called testconfig for the sun-ftp-binding component. I created a simple configuration called testconfig for the sun-ftp-binding component.

2) Connect with asadmin to the appserver.

3) In asadmin: show-jbi-application-configuration --component sun-ftp-binding testconfig
This prints out a list of all properties for the testconfig Application Configuration for the FTPBC:

irListStyle = UNIX
EnableCCC = false
Host = localhost
KeyAlias =
KeyPassword = *****
KeyStore =
KeyStorePassword = *****
Password = *****
Port = 22
SecuredType = None
TrustStore =
TrustStorePassword = *****
UseUserDefinedDirListStyle = false
User = anonymous
UserDefinedDirListStyle =
UserDefinedDirListStyleConfig =
configurationName = testconfig


4) Put all these properties in a property file, change the property values and make more files for each environment as needed.
5) To add files with properties to a binding component in asadmin use:
create-jbi-application-configuration --component sun-ftp-binding [path to property file]

This way all of the application configuration properties creation can be scripted. Use a bash, cmd, python or whatever script language you're comfortable with to configure a domain.


Why the delay?

I've had many requests recently to publish this final part of my blog series on using CAPS 6 with Java MQ for HA using MySQL Cluster. I didn't post anything for a while since the GA release of CAPS 6 did not support MQ 4.2 which is required for MySQL Cluster support (using NDB storage).

HA Clusters

HA clusters in Java MQ provide both service and data high availability, and requires the use of a HA relational database. The HA database (e.g. MySQL Cluster) is responsible for providing clustering, failover and recovery of the database servers / nodes and the JavaMQ brokers treat the database as a shared store.

You can read more about HA clusters here.

Key considerations when setting up HA clusters

  • Do I need a master broker?
  • No, there is no need for a master broker in a HA cluster. This also means that there is no single point of failure in a HA cluster configuration.

  • How many brokers and database servers should I run per cluster?
  • The number of brokers in a broker cluster and the number of database servers/nodes in your RDBMS cluster can be scaled independently of each other. There is, typically, a performance overhead associated with scaling the number of brokers and database nodes due to the additional data replication that is required between these nodes. An architect must be able to understand the impact on application performance and reliability of their system if brokers or database nodes fail and the necessary recoery time when they are restored.

  • What is 'split-brain' and how do we solve it?
  • A split-brain condition occurs if brokers/nodes within the same cluster cannot communicate with each other but are still able to process requests from their JMS clients. This is a problem in JMS systems since it is normally important that queue semantics are upheld - i.e. the 'split' cluster must still ensure that there is once only delivery of a queued message to a single client consumer. For Java MQ, this can be achieved in the message store (i.e. HA database). Specifically, if MySQL Cluster is used, a management server (a form of 'quorum') can be used that each database server in the cluster connects to and is deemed to be active only if it can see the management server.

Configuring Java MQ HA clusters for CAPS 6

The Java CAPS configuration for using HA clusters is the same as it is for conventional clusters since there are no additional client-side parameters to configure. It is necessary that the jms-service type is changed to REMOTE mode when running clustered brokers.

  1. Install and configure MySQL Cluster 6.x
  2. MySQL Cluster 6.x is currently supported. The MySQL server needs to be configured to use the NDB storage mechanism for clustered support on at least two hosts with a separate host for the management server 'quorum'. It is possible to install the management server on one of the MySQL server nodes but a separate server is recommended for true redundancy:
    • Host 1: MQ 4.2 or greater, MySQL Server/NDB Storage
    • Host 2: MQ 4.2 or greater, MySQL Server/NDB Storage
    • Host 3: Management Server (can run on host 1 or 2)
    Click here for a good step-by-step guide on how to set up MySQL Cluster on two servers.

  3. Configure MQ HA clustered brokers
  4. If you are already running brokers configured in a conventional cluster, you will firstly need to reset the stores of those brokers by running each broker with the -reset store paramater: imqbrokerd -tty -reset store -name broker1 -port 7677 imqbrokerd -tty -reset store -name broker2 -port 7678 Next stop the brokers and add the following properties to the config.properties file of each broker (e.g. in $IMQ_VARHOME/instances/broker1/props/:
    imq.brokerid=broker1
    imq.cluster.ha=true
    imq.cluster.clusterid=capscl
    imq.persist.store=jdbc
    
    imq.persist.jdbc.dbVendor=mysql
    imq.persist.jdbc.mysql.user=root
    imq.persist.jdbc.mysql.property.url=jdbc:mysql://host1:3306,host2:3306/
    imq.persist.jdbc.mysql.password=mysqlmysql
    imq.persist.jdbc.mysql.tableoption=ENGINE=NDBCLUSTER
    
    NB: The imq.cluster.clusterid property is mandatory and used in the database table name instead of the brokerid.

  5. Add JDBC drivers to each Java MQ installation classpath
  6. Copy MySQL Connector/J JDBC driver to .../imq/lib/ext of your CAPS 6 appserver's installation from where the remote broker will be started.

  7. Create message store tables
  8. Ensure that the MySQL Cluster and NDB nodes are running and then start the brokers and create the required tables from any broker instance with: imqdbmgr create tbl

  9. Deploy your CAPS 6 applications
  10. Finally deploy and start your CAPS 6 applications as detailed in the previous parts. You are now ready to begin testing failover and recovery of your CAPS 6 applications.

Performance Tuning

Be aware that due to the number of server processes that are running (app server, broker, MySQL server, NDB node, management server), there are potential overheads of this approach and, coupled with that, many opportunities for tuning the performance. There are some pointers on the CAPS Grok about changing the JDBC connection pools with JavaMQ and other tuning advice here.

Interceptors are a way to add behavior to a system without directly invoking this behavior in from code. The typical anti-example is that if you would want to log the entry and exit of methods on a class, you could do that of course by adding log statements in each and every method. The downside is that you would have to change each and every method, and that all these methods now have repetitive code in there. With the interceptor approach on the other hand, you could do that by adding an interceptor that is invoked before and after the method is invoked. In the code of the interceptor you would then add the log statement. The advantage is that the existing methods are not changed, that repetitive code is avoided, and that the logging concern is concentrated in one part of the code base rather than spread all over.

I think that this logging example is pretty dumb, but I guess it drives home the message of adding behavior non-invasively, and a separation of concerns. I'll discuss some more interesting examples in a minute.

Interceptors in EE

Interceptors have long been the domain of AOP (Aspect Oriented Programming) packages that add interceptors through byte code manipulation, either at runtime or as a post-compile step. For EE developers, things changed with the advent of EE5 in which interceptors were added to EJBs.

An interceptor can be added to all the methods or individual methods of an EJB by adding an annotation to either the class or to individual methods. In the following example, the NoConcurrency interceptor is invoked when the getUnclaimedAccounts() method is called.

@Interceptors(NoConcurrency.class)
public void getUnclaimedAccounts(String category) {...

The interceptor class is a simple Java class that has to have a method with the following signature:

@AroundInvoke
Object <METHOD>(javax.interceptor.InvocationContext) throws Exception

The interceptor method is called when a client calls an EJB method. The interceptor typically calls InvocationContext.proceed(). This will call into the EJB method (or the next interceptor, should there be one).

Interceptor classes are typically packaged as part of an EAR file: they are part of the application.

Interceptors are referenced in an EJB using the @Interceptors annotation. They can also be referenced from the EJB's deployment descriptor. In either case, the application needs to be modified to specify interceptors.

Another limitation of EJB interceptors is that they only work on EJB methods. When common behavior needs to be added to other interactions, for instance if an EJB invokes something like an outbound resource adapter, a different mechanism must be used.

Interceptors in CAPS

A Java CAPS customer had an interesting case for using interceptors. The customer had hundreds of integration applications that all received and sent JMS messages. If a message cannot be processed, the message is sent to an error handling system using JMSJCA's dead letter queue facility. An operator will monitor the dead letter queue, and may resubmit the message. If a resubmitted message is processed successfully, the error handling system needs to be notified of that fact. One way of adding this behavior would be to add a chunk of code to all MDBs. That would of course lead to a lot of duplicated code. It also leads to mixing this system level behavior with the business logic in the integration applications. This is clearly undesirable.

Because Repository based projects in Java CAPS generate all the MDB code and assembles the applications, it is difficult to make use of EJB interceptors. What is needed is to specify the use of interceptors on a global basis, that is outside of the applications, and preferably for all applications at the same time.

Another requirement is that the customer wanted to add common behavior not just when messages are received, but also when messages were sent from an EJB. Upon sending a message, payload validation should happen. Since EJB interceptors can only be used for EJB methods, this was another reason that EJB interceptors could not be used.

The solution was to add a new feature to JMSJCA to support interceptors.

Interceptors in JMSCA

Interceptors in JMSJCA are invoked not only before / after a message is delivered to the MDB, but also any time a message is sent.

Rather than introducing a new Java interface, which would bring with it the complication of compile time dependencies on JMSJCA jars, the JMSJCA interceptors use the same annotations as in EJB3: any class with a method with the right signature and the @AroundInvoke annotation can serve as an interceptor.

Which classes will JMSJCA consider as interceptors? For this, it uses the service locator mechanism from JDK 6. This is done without introducing dependencies on JDK 6 by the way. With the service locator mechanism, a jar that holds the interceptor should have a special manifest file that lists the class names of the interceptors. The name of this manifest should be META-INF/services/myinterceptor where myinterceptor is the name of the interceptor. This name needs to be specified in the JMSJCA configuration. If no name is specified, the default name jmsjca.interceptor is used. This means that interceptors using the service name jmsjca.interceptor are automatically loaded and invoked if not overridden in the JMSJCA configuration.

With this, it's easy to add interceptors to all applications running in the application server, whenever they send or receive messages through JMSJCA, without having to change any application.

For more information, see http://jmsjca.dev.java.net/ .