Book Image

Instant Apache ServiceMix How-to

By : Henryk Konsek
Book Image

Instant Apache ServiceMix How-to

By: Henryk Konsek

Overview of this book

<p>Creating reliable integration solution can be easy if you choose the right tools for the job. Apache Camel and ServiceMix are the leading integration technologies dedicated to dealing with the complexity of the messaging solutions. Learn how to efficiently integrate multiple systems with bleeding edge open source Apache software.</p> <p>"Instant Apache ServiceMix How-to" is a practical, hands-on guide that provides you with a number of clear, step-by-step exercises that will help you take advantage of the real power that is behind the leading Apache integration stack.</p> <p>This book guides the reader in how to install ServiceMix and how to get it up and running. It will take you through a number of practical recipes – starting with the basic commands of Apache Karaf container and ending with the deployment of JMS and web service solutions.</p>
Table of Contents (7 chapters)

Exposing a code-first web service (Must know)


In the previous recipe, you learned how to expose a web service starting from the WSDL file. This recipe will guide you through the process of exposing a POJO instance as the web service with a WSDL contract automatically generated for you.

Getting ready

ServiceMix uses Apache CXF as an engine of its web service stack. In this recipe, we will create a Mavenized ServiceMix module, exposing Java code as a SOAP-based web service via the CXF endpoint. In order to generate such a module, we will use the Maven Archetype mechanism.

As you can see, Maven is an essential tool to complete this task, so make sure that you have this useful utility properly installed in your system. We will also assume that your ServiceMix instance is already installed and running.

How to do it...

  1. Generate a new CXF code-first project using the Maven archetype.

  2. Create the JAX-WS compatible class.

  3. Build the module with the mvn install command.

  4. Deploy the generated artifact (target/cxfcode-first-example-1.0-SNAPSHOT.jar) to the SERVICEMIX_HOME/deploy directory.

How it works...

We will start the development of our code-first web service module by generating a new Apache CXF code-first project from the Maven Archetype (http:/maven.apache.org/archetype/maven-archetype-plugin). The following Maven command can be used to generate a new module from the archetype named org.apache.servicemix.tooling:servicemix-cxf-code-first-osgi-bundle:

mvn archetype:generate -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-cxf-code-first-osgi-bundle -DgroupId=com.packtpub.servicemix -DartifactId=cxf-code-first-example-Dversion=1.0-SNAPSHOT

The generated project will contain the bootstrap configuration of the OSGI-based ServiceMix module with the Spring configuration, as well as the simple Person web service written in JAX-WS:

package com.packtpub.servicemix;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebParam.Mode;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
@WebService
@XmlSeeAlso({com.packtpub.servicemix.types.ObjectFactory.class})
public interface Person {

    @RequestWrapper(localName = "GetPerson", className = "com.packtpub.servicemix.types.GetPerson")

    @ResponseWrapper(localName = "GetPersonResponse", className = "com.packtpub.servicemix.types.GetPersonResponse")
    @WebMethod(operationName = "GetPerson")
    public void getPerson(
        @WebParam(mode = WebParam.Mode.INOUT, name = "personId")
        javax.xml.ws.Holder<java.lang.String> personId,
        @WebParam(mode = WebParam.Mode.OUT, name = "ssn")
        javax.xml.ws.Holder<java.lang.String> ssn,
        @WebParam(mode = WebParam.Mode.OUT, name = "name")
        javax.xml.ws.Holder<java.lang.String> name
    ) throws UnknownPersonFault;

}

Maven Archetype also generates the stub implementation of the Person service. The implementation class is responsible for handling the actual business logic of the service:

package com.packtpub.servicemix;

import javax.jws.WebService;
import javax.xml.ws.Holder;
import com.packtpub.servicemix.types.GetPerson;
import com.packtpub.servicemix.types.GetPersonResponse;
@WebService(serviceName = "PersonService", endpointInterface = "com.packtpub.servicemix.Person")
public class PersonImpl implements Person {

    public void getPerson(Holder<String> personId, Holder<String> ssn, Holder<String> name)
        throws UnknownPersonFault
    {
        if (personId.value == null || personId.value.length() == 0) {
            com.packtpub.servicemix.types.UnknownPersonFault fault 
= new com.packtpub.servicemix.types.UnknownPersonFault();
            fault.setPersonId(personId.value);
            throw new UnknownPersonFault(null,fault);
        }
        name.value = "Guillaume";
        ssn.value = "000-000-0000";
    }

}

We will not delve into the details of the JAX-WS annotations here. If you are interested in a good tutorial about JAX-WS web services, I recommend you read the excellent book from O'Reilly Publishing, called Java Web Services: Up and Running, authored by Martin Kalin.

The Person service is exposed via the CXF JAX-WS endpoint in the bean.xml file:

    <jaxws:endpoint id="HTTPEndpoint"

        implementor="com.packtpub.servicemix.PersonImpl"

        address="/PersonServiceCF"/>

When you deploy the generated CXF module to ServiceMix, it starts a new Spring context defined in the beans.xml file. In particular, the CXF endpoint is started and exposes the PersonImpl instance to the outside world via the /cxf/PersonServiceCF URL. If you add the ?WSDL parameter at the end of the service URL (http://localhost:8181/cxf/PersonServiceCF?WSDL), you will see the WSDL file generated by the CXF stack.

To validate that your CXF module has been successfully deployed to ServiceMix, open the URL mentioned above in the browser (as demonstrated in the following screenshot):

If you want to expose a new code-first service via ServiceMix and CXF, all you need to do is to create a new JAX-WS-compatible service and register it in cxf-code-first-example/src/main/resources/META-INF/spring/beans.xml as the JAX-WS endpoint.

There's more...

Code-first is probably the most popular approach to web services development. If you are interested in the code-first approach with JAX-WS, you might also be interested in the tips presented here.

JAX-WS versus JAX-RPC

When exploring the Java web service stack, you may encounter the JAX-RPC acronym. JAX-RPC is the ancestor of JAX-WS. It is the old web service stack from the J2EE 4 specifications. Java EE 5 introduced a new, annotation-based web service specification called JAX-WS. In general, you can think of JAX-RPC as a legacy technology that is not used in new projects.

Learn more about CXF

The CXF endpoint configuration generated by Maven Archetype is a very basic one. If you want to learn more about CXF usage and configuration, please refer to the documentation on the project site at http://cxf.apache.org/docs/index.html. Keep in mind that CXF is a web services Swiss army knife, so it is good to learn more about the features it provides.