Tuesday, September 22, 2009

EJB 3.0 and JAX-WS Web Services

I was in a discussion with a number of my colleagues yesterday and the topic came up of using EJB 3.0 with JAX-WS web services. Essentially, they weren't sure if the @EJB annotation (which injected a link to an EJB 3.0 bean) could be used with JAX-WS endpoints. The question comes up since they only though injection worked on servlets (but this wasn't true). This is something that we think will be a typical usage scenario in that users can invoke existing services downstream on an EJB 3.0 bean. These scenarios may not necessarily be exposing EJB 3.0 beans as web services but merely using an EJB as part of your business logic to obtain/determine information needing to use or share back to a customer.


The general scenario looks a little something like the following image below:

The code to develop it is very straight forward. It's basically starting out with an EJB 3.0 bean like the code below:

import javax.ejb.Stateless;

@Stateless
public class SampleBean implements SampleBeanLocal {
public SampleBean() {}

public String echo(String s) {
return s;
}
}


with a simple local interface...

import javax.ejb.Local;

@Local
public interface SampleBeanLocal {
public String echo (String s);
}


it becomes easy to then inject a reference into a JAX-WS bean in order to get this to work... The code is also pretty trivial...

import javax.ejb.EJB;
import sample.ejb.SampleBeanLocal;

@javax.jws.WebService
public class SampleService{
@EJB(mappedName = "sample.ejb.SampleBeanLocal")
private SampleBeanLocal sample;

public String echo(String arg0) {
return sample.echo(arg0);
}
}


and that's about it. This is supported in IBM WebSphere Application Server v7.0. Let us know if you have any questions.

Monday, September 21, 2009

Asserting an Identity from JAX-RPC Web Services to WebSphere

I've received similar questions from multiple customers all about asserting identity on Web Services requests within JAX-RPC. Therefore, let me talk a bit about how this can be done with the support in WebSphere today.

The JAX-RPC web services security implementation has two phases of processing a security token embedded in the WS-Security header.
  1. Verify the validity of the security token.
    This is handled by the Token Consumer and/or JAAS Login Module configured in the deployment descriptor and binding.
  2. Verify the identity of the security token exist in the configured user registry and then create the WebSphere credentials.
    This is enabled via the Caller and it is optional.
In some business use cases, you may want to assert the identity based on trust and do not necessary want to add the identity to the configured user registry. Here is how you can do this (since 6.1.0.19).

Phase 1

The user must provide a custom implementation of a Token Consumer. Here is a developerWorks article with step by step instructions.

Phase 2

The user must override the default JAAS Login Configuration.

The default JAAS Login Configuration used by the Caller to create WebSphere Principal and Credential is “system.DEFAULT”. This JAAS Login Configuration is used by many other parts of the system. It is best to create a new JAAS Login Configuration with the same content of “system.DEFAULT” and ensure your custom JAAS Login Module is the first in the list, and then specify the Caller to use the new JAAS Login Configuration. The property to specify a different JAAS Login Configuration for the Caller (see figure below):


Name: com.ibm.wsspi.wssecurity.Caller.assertionLoginConfig

Value: name of the JAAS Login Configuration



Please follow the WebSphere Attribute Assertion framework in your custom JAAS Login Module implementations to assert the identity. The information is available here and here.

I hope you find this information useful.

Friday, September 18, 2009

Web Services Performance Tidbits

My team was recently working with a customer on their web services application and we wanted to document a few things we learned during the engagement.

Network bottlenecks

In our IBM labs, when we performance test web services, we set up a set of multi-threaded clients pounding a separate server system until the CPU utilization on the server system becomes saturated (that way - we can see where the time is spent processing). Working with the customer, they could only stress their system to a small portion of the CPU processing limit.

In the end, we discovered that the network was only a 100MB network and totally inadequate to handle the type of loads used in the test - whereas, in our IBM labs, we run on 1GB Ethernet. Using the size of the messages, we computed what the maximum achievable throughput would be on a 100MB network and these matched almost exactly to what was being reported for the customer. This showed us that the network was the bottleneck in the environment and the Application Servers are not being stressed at all - only the network connection.

One way to get around the network bottleneck in an interoperable way would be to use GZIP compression to compress the data (since the network is the bottleneck). See here and here for more information about enabling GZIP compression for Web Services.

Transaction Isolation Level

Another interesting point that we learned was that different Application Server vendors use different transaction isolation levels on the JDBC connection to the database. WebSphere, by default, uses Repeatable Read as a default isolation level which initially made our performance slower. This default was made to protect customers data. Another vendor used a default of Read Committed isolation level which offers higher throughput but more risk. The choice of which isolation level to use is up to the customer but in a comparison, this setting should be consistent to get apples-to-apples measurements.

Tuning

WebSphere does provide many parameters that can be tuned to increase performance. Some of the important ones for web services are JVM heap size and Web container thread pools. A white paper was recently published by our performance team that shows the impact of adjusting some of these. See WAS Perf Tuning for more info


We hope this information helps others as they try to build performant web service applications.