Friday, February 8, 2008

How do I quickly get a list of web services in a given server?

Sometimes you deploy a .war file to oc4j and are just not be able to find the new web service. This could be because of a typo or just something "special" in the server configuration. It would be really useful to be able to see a list of all the services exposed by the server. In 10.1.3 you could drill down using EM; but that was not always available. (For example when using the cut down server embedded into JDeveloper)

In the 11 branch we have added a few features to make this easier. For a start the connections browser in JDeveloper will show you a list of published web services for each connection it has, including the embedded server:

If you are not using JDeveloper you can access the list of web services in the WSIL format simply by appending "inspection.wsil" to the root of the your servers web url. For example "http://localhost:8988/inspection.wsil". You can then just plug this into your WSIL browser of choice or just view using an ordinary web browser.

Tuesday, February 5, 2008

Paper Accepted for JavaOne 2008: "Dealing with Asynchronicity in Java™ Technology-Based Web Services"

If all goes well I will be presenting along side my colleague, Manoj Kumar who works on the server side, on this topic at JavaOne this year in a technical Session. Been a few years since I was last presenting there so happy to be accepted again.

Thursday, January 24, 2008

orablogs is dead, long live orablogs

The truth is that if you leave something on the internet long enough someone will take a copy of it. This also has a complete copy of my blog that was previously hosted on orablogs.

Shame all this stuff will fall out of the google index though.....

Monday, January 14, 2008

JDK 6u4 contains JAX-B/WS 2.1

Worth knowing that latest JDK 6 contains a later version of the web service APIs, so you no longer have to play around with endorsed libraries to replace the bundled versions. At least until the next version of JAX-WS is released....

Thursday, January 3, 2008

Client / Proxy for an Asynchronous Web Service using JDeveloper 11 TP 3

In my previous post I looked at a proposal to make it easier to implement asynchronous web services. There still remains the task of generating a suitable client to work with this service. Generally this will take the form of a proxy to invoke the "initialization" port type and a deployed web service that implements the "response"/"callback" port type. In general you would expect the async client to be deployed to a EE container to be properly managed.

Previously we would have made you generate the proxy and response port type manually; but the "Web Service Proxy" wizard in JDeveloper will now offer to generate the response service for you. In TP3 it will recognize any WSDL that contains a more than one port types that are related using a partnerLinkType as possibly an asynchronous service. (See here for an example) Once recognize the wizard give you give you the option to specify the package to generate the response service to:

You can of course un-tick the box and not generate a callback service if you want to. If you continue with the async case you will get both a skeleton client class and a skeleton service implementation is generated at the same time:

Not that in both the client we are generating boilerplate code to manage the WS-Addressing headers used to correlate the two different messages. This code is using the "AddressingHelper" class which is an oracle specific class; but note that it makes working with the headers so much easier. I will look into providing a non-oracle specific code example at some point when I get a few minutes together.

Unfortunately it appears that the web.xml and the correct deployment descriptors are not generated in the build that went out as TP3 but those are relatively easy to fix by hand or using the quick fixes in the code editor.

Declarative Asynchronous Web Service Proposal

I have recently spent quite a bit of time pondering asynchronous web services. By this I mean in the simplest case a service where the response is returned on a separate connection and not the API level asynchronicity that was added in JAX-WS. It is entirely possible to implement this kind of service using the APIs provided by JAX-WS but it is not as fun or easy as it could be.

With my colleague Manoj Kumar, who to be fair does all the hard core server side bits, we have been thinking about have to make this process far less complicated for the developer by using declarative annotations. In particular we wanted to make sure that any process handling is entirely dealt with by the container. Unfortunately the implementation for this didn't make its way into the most recent TP3 release of JDeveloper 11; but the associated UI and annotations are in there. Of course we cannot promise that this feature will ever make it into a future product; but we would welcome your feedback on our thoughts so far.

Currently this proposal uses oracle specific annotations; but we have been working on them with a mind to ensuring that perhaps one day this could become part of the JAX-WS standard. This seems to be a reasonably useful scenario and therefore worthwhile including in the standard.

Lets look at a simple hello world example so you can have an idea of what I am talking about:

@WebService
@AsyncWebService
public class Hello
{
   public String sayHello(String name)
   {
      return "Hello " + name;
   }
}

So when this is deployed the generated WSDL will look rather different from the case without the @AsyncWebService. There will be two port types elements rather than the single would you would normally expect. The first will be the "Hello" port type which has one operation that takes the name as a parameter but doesn't have a return value. The second port type will take a name something like "HelloResponse" and will again have one operation, called perhaps "sayHelloResponse", which with have the return value as its parameter. (Note we haven't nailed down the name mapping rules yet hence I am being a little bit vague)

There will be of course bindings for each port type; but only the "Hello" port type will be surfaced as a port on a service as the server will only implement the initiation part of the process. The response port type will of course need to be implemented and published by the client.

So the resultant WSDL will look something like this the following. Notice that there is a partnerLinkType at the end of the WSDL. This is useful as it makes it much easier for tools to associate the two parts of the service. (Particularly when interacting with BPEL processes)

<?xml version="1.0" encoding="UTF-8" ?>
<definitions
     name="HelloService"
     targetNamespace="http://model/"
     xmlns="http://schemas.xmlsoap.org/wsdl/"
     xmlns:tns="http://model/"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
     xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    >
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://model/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:tns="http://model/">
            <xsd:complexType name="sayHello">
                <xsd:sequence>
                    <xsd:element name="arg0" type="xsd:string"/>
                </xsd:sequence>
            </xsd:complexType>
            <xsd:element name="sayHello" type="tns:sayHello"/>
            <xsd:complexType name="response">
                <xsd:sequence>
                    <xsd:element name="arg0" type="xsd:string"/>
                </xsd:sequence>
            </xsd:complexType>
            <xsd:element name="response" type="tns:response"/>
        </schema>
    </types>

    <message name="sayHelloInput">
        <part name="parameters" element="tns:sayHello"/>
    </message>
    <message name="responseInput">
        <part name="parameters" element="tns:response"/>
    </message>    

    <portType name="Hello">
        <operation name="sayHello">
            <input message="tns:sayHelloInput" xmlns:ns1="http://www.w3.org/2006/05/addressing/wsdl"
                 ns1:Action=""/>
        </operation>
    </portType>
    <portType name="HelloResponse">
        <operation name="sayHelloResponse">
            <input message="tns:responseInput" xmlns:ns1="http://www.w3.org/2006/05/addressing/wsdl"
                 ns1:Action=""/>
        </operation>
    </portType>
    
    <binding name="HelloSoap" type="tns:Hello">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="sayHello">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
            </input>
        </operation>
    </binding>
    

    <binding name="HelloResponseSoap" type="tns:HelloResponse">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="sayHelloResponse">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
            </input>
        </operation>
    </binding>
    
    
    <service name="Hello">
        <port name="HelloPort" binding="tns:HelloSoap">
            <soap:address location="http://localhost:8988/Application1-Model-context-root/mathsserviceport"/>
        </port>
    </service>
    
    
    <partnerLinkType name="HelloService"
                     xmlns="http://schemas.xmlsoap.org/ws/2003/05/partner-link/">
        <role name="In">
            <portType name="tns:Hello"/>
        </role>
        <role name="Out">
            <portType name="tns:HelloResponse"/>
        </role>
    </partnerLinkType>
    
</definitions>

So how is this implemented under the covers? In order to allow the initial call to Hello.sayHello() to return immediately we need to defer the processing of the call to the web service to another process / thread. Starting a native java thread is an obvious no-no when running in a managed JEE container but there are a number of alternatives that do work better in the EE world.

The implementation that we have been working on publishes the request onto a JMS queue. This request is then "consumed" by a message driven bean at some later time. The MDB is then responsible for calling the business logic and generating a suitable response message and sending it to the client. This is all transparent to the user as they only need to declare that the service is asynchronous. There might be specific features for a given implementation, for example you might want to specify a more secure and reliable queue that the default one we provide, but the most basic case would just work. In our implementation we provide a "@AsynchronousWebServiceQueue" annotation that allows the developer to specify the JNDI name of the JMS queue or connection factory.

Lets take a look at a sequence diagram show the full life cycle of a particular invocation. The client publishes the callback service first of all. It then invokes the initiation service and provides correlation and reply-to information in the form of WS-Addressing headers. This then causes a message to be posted on to JMS queue which is than consumed by a MDB. The MDB goes on to call the business logic in the normal way. When the process is finished the MDB uses the information stored in the WS-Addressing "Reply-To" header to post a response to the correct location.

Of course one message in and one message out is a rather simplistic example. For example you might want to update the client with some kind of progress update during a process. In our proposal you can do this using using a separate callback interface.

@WebService
@AsyncWebService
public class InsuranceClient
{
   @CallbackRef
   InsuranceCallback callback;


   public Result processClaim(Claim claim)
   {
      callback.updateStatus("Stared Processing");

      // Do something

      callback.updateStatus("Done something");

      // Some something else

      callback.updateStatus("Finished Processing");

      // Finally return

      return result;
   }


   @WebService
   public interface InsuranceCallback
   {
      public void updateStatus(String status);
   }
}

In this case the generated WSDL with have a response port type that will contain both the "processClaimReponse" and "updateStatus" operations. The callback field will be injected with the correct service instance based on the contents of the WS-Addressing headers.

You can take this example one step further and make the business logic method return void. In this case the implementor is wholly responsible for managing the callbacks. This can be useful in the case where the response depends on the output of the process.

@WebService
@AsyncWebService
public class InsuranceClient
{
   @CallbackRef
   InsuranceCallback callback;


   public void processClaim(Claim claim)
   {
      // Process claim

      if (success)
      {
         callback.claimRejected(...);
      }
      else
      {
         callback.claimAccepted(...);
      }
   }


   @WebService
   public interface InsuranceCallback
   {
      public void claimAccepted(...);
      public void claimRejected(...);
   }
}

As you can see this simple annotation model can cover a variety of different interaction models. There are some important areas that we are still working on though: in particular how we handle WS-* policies on the response/callback messages and how we deal with faults are still works in progress. We also have a range of annotation for controlling the response port type and operations names but I have left them out here for reasons of clarity but can be easily found using the property inspector on the code in JDeveloper.

Finally it is worth noting that BEA has a similar design in there WebLogic product. From what I understand though it appears that there implementation only provides the callback injection and doesn't appear to offer the same process management as in our proposal. This might be due to a misunderstanding from myself of there documentation. I do personally think that hiding the process details is the most powerful aspect of our proposal.

I would be interested to hear about other implementations and feedback on this proposal.

Friday, December 14, 2007

Dealing With Promotion, Or How To Change Which Web Service Gets Called Without Altering The Code

On of the difficulties of working with web services is how to deal with external dependencies as you promote code from development to QA to production. Take this JAX-WS code below as an example. Here was have a SMS service from VoodoPhone that makes use of an external translation service from Noodle.com. (Names has been changed to protect the innocent)

The problem comes from that fact that whilst using @WebServiceRef make everything really quite tidy is that the location of the WSDL, and therefore the service endpoint, is hard coded in the annotations and constants on the TranslatorService class. This makes it harder to replace the translation service with an internal or "mock" implementation during development time. You probably wouldn't want to rely on an external server for your internal regression tests for example.

Previously in JAX-RPC it was relatively obvious that you could create the proxy class and then change the endpoint. Indeed in the JAX-WS SE case you can do the same but it requires you to write code to externalize the wsdl location and this is not very JEE. Another way around the problem is to regenerate the proxy for each target system; but this is a pain and it probably takes you away from the pleasant land of the IDE into the wilds of ant tasks and complex build scripts.

I turns out that in the EE case, when using @WebServiceRef, that each injection point can be modified at deployment time with a new WSDL location. This is all done using JNDI behind the scenes; but it is suitably abstracted away from the developer.

In the next screen grab you can see the JSR-88 "Deployment Plan" dialog that you will see when you try to deploy using JDeveloper 11. (Normal disclaimers as regards to this not being production software) As you can see it has picked up the the fact that there is an injection point as part of the deployment process. There is no "service-ref" entry in my web.xml but the project the deployment process has worked out that one might be needed.

As you can see you can load and save deployment plans so you can have different configurations depending on whether you are doing development or even promoting to a production system.

You can of course do this by just editing the web.xml file yourself to alter the enviroment. The JNDI name is the name of the class and the name of the field with a slash between then. This is the "com.voodophone.SMSService/translationService" node in the tree on the left of the panel. There is no reason why you cannot type this yourself into web.xml as required or add in later using the deployment tool of your choice.

<web-app>
  ...
  <service-ref>
    <service-ref-name>com.voodophone.SMSService/translationService</service-ref-namae>
    <wsdl-file>http://localhost:8099/mockTranslation</wsdl-file>
  </service-ref>
  ...
</web-app>

The main thing to take away from this is that whilst a lot of the new annotation stuff appears to work like magic, underneath there is a JNDI assistant doing all of the dirty work. You might not have to use JNDI directly but understanding how it works under the covers allows you to leverage the indirection in some really quite powerful ways. Just remember to make sure that the different WSDL define the same interface.....

Update: Sadly the deployment plan is broken in this specific area in JDeveloper TP3, hopefully it should be working in the next release. Or you will find similar features in other tools/servers that support JSR-88.