View Source

{info}A *Core Service* defines a technical service which is needed in the DSB kernel to run. It can be a service registry, a transport layer, a binding manager,...{info}
The DSB provides simple ways to expose core services as Web services without any extra configuration:

# By using JAXWS @Webservice annotation
# By using DSB @WebServicre annotation

The procedures are detailled below. 

h1. JAXWS WebService

The only things which are needed are :

# Add JAX-WS annotations (javax.xml.ws.WebService) to core services or generate your service from a WSDL generation tool (Apache CXF is a good choice).
# Adding the core service to the right fractal composite
# There is no 3

To illustrate this feature, we provide a sample to expose a simple TestService service as Web service.

h2. Create your interface
{code:language=java|title=TestService interface}package org.petalslink.dsb.ws.api;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface TestService {

@WebMethod
void test();

}{code}
In this sample, we start from a JAXWS annotated Java interface. This is the only thing to check in this step.

h2. Create your service

Creating your service means implement the interface we just defined in the previous step. Now we have to create a Fractal component which implement the JAXWS annotated TestService interface.
{code:language=java|title=Fractal Component}package org.petalslink.dsb.kernel.ws;

import org.objectweb.fractal.fraclet.annotation.annotations.FractalComponent;
import org.objectweb.fractal.fraclet.annotation.annotations.Interface;
import org.objectweb.fractal.fraclet.annotation.annotations.LifeCycle;
import org.objectweb.fractal.fraclet.annotation.annotations.Monolog;
import org.objectweb.fractal.fraclet.annotation.annotations.Provides;
import org.objectweb.fractal.fraclet.annotation.annotations.type.LifeCycleType;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.petals.util.LoggingUtil;
import org.petalslink.dsb.ws.api.TestService;

@FractalComponent
@Provides(interfaces = { @Interface(name = "service", signature = TestService.class) })
public class TestServiceImpl implements TestService {

@Monolog(name = "logger")
private Logger logger;

private LoggingUtil log;

@LifeCycle(on = LifeCycleType.START)
protected void start() {
this.log = new LoggingUtil(this.logger);
this.log.debug("Starting...");
}

@LifeCycle(on = LifeCycleType.STOP)
protected void stop() {
this.log.debug("Stopping...");
}

/**
* {@inheritDoc}
*/
public void test() {
System.out.println("This is a test!");
}

}{code}
* As a Fractal component, you MUST check that you put all the Fractal annotations (@FractalComponent, @Provides, @LifeCycle)
* This component MUST implements the TestService interface


h2. Add service to the architecture

Once the Fractal component has been created, you have to add it to the component architecture provided by the DSB. For now, it is only possible at configuration time by adding the component at the right place. By default, the _Tools.fractal_ definition file located in _trunk/research/commons/dsb/distributions/dsb-distribution/src/main/resources_ (or in your own distribution) contains a WebServiceManagerImpl (org.petalslink.dsb.kernel.tools.ws.WebServiceManagerImpl) component which will detect JAXWS annotated components defined in the _Tools.fractal_ composite and which will expose them automatically at startup on the management port (the same Petals ESB uses).

Adding your component is just instanciating it in _Tools.fractal_ like this:
{code:language=xml|title=Component definition} <component definition="org.petalslink.dsb.kernel.ws.TestServiceImpl" name="TestServiceImpl"/>{code}

That's all\! Your TestService is now exposed by the DSB at startup and is available at :&nbsp;[http://localhost:7600/petals/ws/TestService] (where TestService is the Java interface name ie the one with the @WebService&nbsp;annotation).

h1. DSB WebService

There are some cases which are not compatible with the previously described approach. For some reason, JAXWS annotated classes may produce a wrong result. In order to directly be able to work with Web services payload, the DSB provide a simple way to expose a bean as Web service as detailed below.

h2. Create your service

Your service MUST implement the org.petalslink.dsb.soap.api.Service interface or extends the org.petalslink.dsb.soap.AbstractService&nbsp;class like for example
{code:language=java}package org.petalslink.dsb.notification.service;

import javax.xml.namespace.QName;

import org.petalslink.dsb.soap.AbstractService;
import org.petalslink.dsb.soap.api.ServiceException;
import org.petalslink.dsb.soap.api.SimpleExchange;
import org.w3c.dom.Document;

import com.ebmwebsourcing.wsstar.basenotification.datatypes.api.utils.WsnbException;
import com.ebmwebsourcing.wsstar.resourceproperties.datatypes.api.abstraction.UpdateResourceProperties;
import com.ebmwebsourcing.wsstar.resourceproperties.datatypes.api.abstraction.UpdateResourcePropertiesResponse;
import com.ebmwebsourcing.wsstar.resourceproperties.datatypes.api.refinedabstraction.RefinedWsrfrpFactory;
import com.ebmwebsourcing.wsstar.resourceproperties.datatypes.api.utils.WsrfrpException;
import com.ebmwebsourcing.wsstar.wsnb.services.INotificationProducerRP;
import com.ebmwebsourcing.wsstar.wsrfbf.services.faults.AbsWSStarFault;

/**
* @author chamerling
*
*/
public class NotificationProducerRPService extends AbstractService {

private INotificationProducerRP producerRP;

/**
* @param interfaceName
* @param serviceName
* @param endpointName
* @param wsdl
* @param url
*/
public NotificationProducerRPService(QName interfaceName, QName serviceName,
QName endpointName, String wsdl, String url, INotificationProducerRP producerRP) {
super(interfaceName, serviceName, endpointName, wsdl, url);
if (producerRP == null) {
throw new IllegalArgumentException("Producer is null!");
}
this.producerRP = producerRP;
}

/*
* (non-Javadoc)
*
* @see
* org.petalslink.dsb.soap.AbstractService#doInvoke(org.petalslink.dsb.soap
* .api.SimpleExchange)
*/
@Override
protected void doInvoke(SimpleExchange exchange) throws ServiceException {
System.out.println("NotificationRP producer");
System.out.println("org.petalslink.dsb.notification.service.NotificationProducerRPService");

if (exchange == null || exchange.getIn() == null) {
throw new ServiceException("Incoming message is null...");
}
QName operation = exchange.getOperation();
if (operation == null) {
throw new ServiceException("Incoming operation is null...");
}

if ("GetResourceProperty".equals(operation.getLocalPart())) {
try {
QName qname = RefinedWsrfrpFactory.getInstance().getWsrfrpReader()
.readGetResourceProperty(exchange.getIn());
com.ebmwebsourcing.wsstar.resourceproperties.datatypes.api.abstraction.GetResourcePropertyResponse res = this.producerRP
.getResourceProperty(qname);
Document docResp = RefinedWsrfrpFactory.getInstance().getWsrfrpWriter()
.writeGetResourcePropertyResponseAsDOM(res);
exchange.setOut(docResp);
} catch (WsnbException e) {
e.printStackTrace();
throw new ServiceException(e);
} catch (AbsWSStarFault e) {
e.printStackTrace();
throw new ServiceException(e);
} catch (WsrfrpException e) {
throw new ServiceException(e);
}
} else if ("UpdateResourceProperties".equals(operation.getLocalPart())) {
try {
UpdateResourceProperties updateResourceProperties = RefinedWsrfrpFactory
.getInstance().getWsrfrpReader()
.readUpdateResourceProperties(exchange.getIn());
UpdateResourcePropertiesResponse res = this.producerRP
.updateResourceProperties(updateResourceProperties);
Document docResp = RefinedWsrfrpFactory.getInstance().getWsrfrpWriter()
.writeUpdateResourcePropertiesResponseAsDOM(res);
exchange.setOut(docResp);
} catch (WsnbException e) {
throw new ServiceException(e);
} catch (AbsWSStarFault e) {
throw new ServiceException(e);
} catch (WsrfrpException e) {
throw new ServiceException(e);
}
} else {
throw new ServiceException("Unknown operation '" + operation + "'");
}
}
}{code}
As you can see, you have the possibility to get operation from the incoming message, process things and set the response with the exchange.setOut(Document) method if needed. The DSB will be in charge of receiving the initial message, transforming it and then calling your service. Once the method is complete, it will send back the message to the client.

Once your service is implemented, you have to wrap it into a DSB component as defined below:
{code:language=java}package org.petalslink.dsb.kernel.notification.service;

import javax.xml.namespace.QName;

import org.objectweb.fractal.fraclet.annotation.annotations.FractalComponent;
import org.objectweb.fractal.fraclet.annotation.annotations.Interface;
import org.objectweb.fractal.fraclet.annotation.annotations.LifeCycle;
import org.objectweb.fractal.fraclet.annotation.annotations.Monolog;
import org.objectweb.fractal.fraclet.annotation.annotations.Provides;
import org.objectweb.fractal.fraclet.annotation.annotations.Requires;
import org.objectweb.fractal.fraclet.annotation.annotations.type.LifeCycleType;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.petals.util.LoggingUtil;
import org.petalslink.dsb.annotations.LifeCycleListener;
import org.petalslink.dsb.annotations.service.WebService;
import org.petalslink.dsb.kernel.api.DSBConfigurationService;
import org.petalslink.dsb.soap.api.Service;
import org.petalslink.dsb.soap.api.ServiceException;
import org.petalslink.dsb.soap.api.SimpleExchange;

import com.ebmwebsourcing.wsstar.wsnb.services.INotificationProducer;

/**
* @author chamerling
*
*/
@WebService
@FractalComponent
@Provides(interfaces = { @Interface(name = "service", signature = Service.class) })
public class NotificationProducerService implements Service {

private static final String WSDL = "WS-NotificationProducer.wsdl";

private static final String NS = "http://docs.oasis-open.org/wsn/bw-2";

private static final QName INTERFACE = new QName(NS, "NotificationProducer");

private static final QName ENDPOINT = new QName(NS, "NotificationProducerPort");

private static final QName SERVICE = new QName(NS, "NotificationProducerService");

private static final String SERVICE_NAME = "NotificationProducer";

@Requires(name = "notification-producer", signature = INotificationProducer.class)
protected INotificationProducer producer;

@Requires(name = "configuration", signature = DSBConfigurationService.class)
protected DSBConfigurationService configuration;

@Monolog(name = "logger")
private Logger logger;

private LoggingUtil log;

private org.petalslink.dsb.notification.service.NotificationProducerService delegate;

@LifeCycle(on = LifeCycleType.START)
protected void start() {
this.log = new LoggingUtil(this.logger);
}

@LifeCycle(on = LifeCycleType.STOP)
protected void stop() {
}

@LifeCycleListener
public void init() {
this.delegate = new org.petalslink.dsb.notification.service.NotificationProducerService(
INTERFACE, SERVICE, ENDPOINT, WSDL, buildURL(), producer);
}

public org.petalslink.dsb.notification.service.NotificationProducerService getDelegate() {
return delegate;
}

/**
* @return
*/
private String buildURL() {
return configuration.getWSKernelBaseURL() + SERVICE_NAME;
}

/*
* (non-Javadoc)
*
* @see org.petalslink.dsb.soap.api.Service#getWSDLURL()
*/
public String getWSDLURL() {
return getDelegate().getWSDLURL();
}

/*
* (non-Javadoc)
*
* @see org.petalslink.dsb.soap.api.Service#getURL()
*/
public String getURL() {
return getDelegate().getURL();
}

/*
* (non-Javadoc)
*
* @see org.petalslink.dsb.soap.api.Service#getEndpoint()
*/
public QName getEndpoint() {
return getDelegate().getEndpoint();
}

/*
* (non-Javadoc)
*
* @see org.petalslink.dsb.soap.api.Service#getInterface()
*/
public QName getInterface() {
return getDelegate().getInterface();
}

/*
* (non-Javadoc)
*
* @see org.petalslink.dsb.soap.api.Service#getService()
*/
public QName getService() {
return getDelegate().getService();
}

/*
* (non-Javadoc)
*
* @see
* org.petalslink.dsb.soap.api.Service#invoke(org.petalslink.dsb.soap.api
* .SimpleExchange)
*/
public void invoke(SimpleExchange exchange) throws ServiceException {
this.log.debug("Invoking Notification Producer Service");
getDelegate().invoke(exchange);
}

}{code}
It is important to note:

* You have to give the WSDL location (local resource in the classpath), endpoint, interface and service.
* Your DSB component MUST be annotated with the&nbsp;org.petalslink.dsb.annotations.service.WebService annotation. If not, the service will not be exposed as Web service by the DSB.

h2. Add service to the architecture

As specified above, you have to annotate the service with the&nbsp;org.petalslink.dsb.annotations.service.WebService annotation. With the help of this annotation, the DSB will be able to detect this class and expose it automatically. This is only true if you have instantiated the DSB component with the fractal stuff as described in the JAXWS section.