ServiceMix JSR-181

ServiceMix JSR(181 component is a JBI Service Engine exposing (annotated) POJO as services on the JBI Bus.
It uses xfire internally to perform service invocations and xml marshaling.

Features:

  • no annotations
  • jsr181 annotations
  • commons-attributes annotations
  • aegis binding
  • jaxb2 binding
  • xmlbeans binding
  • wsdl auto generation
  • MTOM / attachments support

Maven Archetype

You can create a JSR-181 Service Unit using the servicemix-jsr181-service-unit Maven archetype:

mvn archetype:create \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-jsr181-service-unit \ -DarchetypeVersion=2010.01 \ -DgroupId=your.group.id \ -DartifactId=your.artifact.id \ -Dversion=your-version

Once you've customized the service unit, simply install the SU:

mvn install

Remember that to be deployable in ServiceMix, the ServiceUnit has to be embedded in a Service Assembly: only the Service Assembly zip file can be deployed in ServiceMix.
To add your SU in a SA, you need to define it in the dependency sets:

<dependency> <groupId>your.group.id</groupId> <artifactId>your.artifact.id</artifactId> <version>your-version</version> </dependency>

Endpoint Configuration

A JSR-181 endpoint only takes an annotated POJO in the pojoClass attribute:

xml <beans xmlns:jsr181="http://servicemix.apache.org/jsr181/1.0"> <jsr181:endpoint pojoClass="your.package.ServicePojo" /> </beans>

A few other examples:

{snippet:id=embedded|lang=xml|url=servicemix/components/engines/servicemix-jsr181/trunk/src/test/resources/good2/xbean.xml} {snippet:id=reference|lang=xml|url=servicemix/components/engines/servicemix-jsr181/trunk/src/test/resources/good2/xbean.xml} {snippet:id=byclass|lang=xml|url=servicemix/components/engines/servicemix-jsr181/trunk/src/test/resources/good2/xbean.xml} Endpoint AttributessolidbgColor='lighblue'

Name

Type

Description

Required

annotations

String

The annotations used to configure the service. Can be "none", "java5", "jsr181", "commons". If not specified, the annotations type will be discovered by looking at the class.

no

endpoint

String

JBI Endpoint name

no (will be auto-generated if not specified)

interfaceName

QName

Interface QName implemented by the JBI endpoint

no (will be auto-generated if not specified)

mtomEnabled

boolean

Enable MTOM / attachment support

no (defaults to false)

pojo

Object

the instanciated POJO to service requests

one of pojo or pojoClass

pojoClass

String

the class name of the POJO to service requests

one of pojo or pojoClass

service

QName

JBI Service name

no (will be auto-generated if not specified)

serviceInterface

String

the class name of the interface to expose as a service

no

typeMapping

String

Can be "default", "xmlbeans", "jaxb2". Defaults to "default" (Aegis) if no annotations used, else defaults to "jaxb2"

no

wsdlResource

Spring resource

if set, the wsdl will be retrieved from the given Spring resource

no

style

String

The SOAP style to use (document, wrapped, rpc)

no (defaults to "wrapped")

validationEnabled

boolean

Specifies if the payload should automatically be validated. This feature only works for JAXB 2.0 payloads.

no

Accessing the JBI bus

The prefered way to access the JBI bus is by retrieving a ComponentContext implementation.
The spring BeanFactory has a parent factory which contains a bean named "context" that you can refer to.

xml <jsr181:endpoint ...> <jsr181:pojo> <bean class="xxx"> <property name="context" ref="context" /> </bean> </jsr181:pojo> </jsr181:endpoint>

If you want to send a request to another service from your POJO, you can add the following method on your POJO:

java private javax.jbi.component.ComponentContext context; public void setContext(javax.jbi.component.ComponentContext context) { this.context = context; }

You will be able to use the provided DeliveryChannel to send requests.

Note that only sendSync is allowed for active JBI exchanges (but you have to use send for DONE or ERROR status exchanges).

You can also use the client api:

java public void myMethod() { ServiceMixClient client = new ServiceMixClientFacade(this.context); QName service = new QName("http://servicemix.org/cheese/", "receiver"); EndpointResolver resolver = client.createResolverForService(service); client.send(resolver, null, null, "<hello>world</hello>"); }

Proxies

You can create java proxies for JBI endpoints, provided that they expose a WSDL.

The basic configuration is the following:

{snippet:id=proxy|lang=xml|url=servicemix/components/engines/servicemix-jsr181/trunk/src/test/resources/org/apache/servicemix/jsr181/spring.xml}

You can use it from one of you client bean, or from inside another component, and call the JBI endpoint as a plain Java object.

From a jsr181 Service Unit, it could be used as following:

{snippet:id=proxy|lang=xml|url=servicemix/components/engines/servicemix-jsr181/trunk/src/test/resources/proxy/xbean.xml} java private Echo echo; public void setEcho(Echo echo) { this.echo = echo; } public void myMethod() { String result = echo.echo("world"); ... }

EJBs

Using spring EJB proxies, you can easily expose an existing EJB on the JBI bus.

xml <jsr181:endpoint annotations="none" service="my:ejb" endpoint="ejb" serviceInterface="foo.bar.Hello"> <jsr181:pojo> <bean class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"> <property name="jndiName" value="my/jndi/path"/> <property name="businessInterface" value="foo.bar.Hello"/> <property name="jndiTemplate" ref="jndiTemplate"/> </bean> </jsr181:pojo> </jsr181:endpoint>

MTOM support

MTOM is a way to handle large amounts of binary data in your services. Unlike attachments, the XML infoset stays the same. MTOM just "optimizes" any base64Binary data you have in your messages. When MTOM is turned on, this base64 data gets sent as a binary attachment saving time and space.

MTOM support can be turned on using:

xml <jsr181:endpoint mtomEnabled="true" ... />

MTOM is supported for the following classes:

  • DataSource
  • DataHandler
  • byte[]

If you have a bean with the following method:

java public String echo(String msg, DataHandler binary) { ... }

you will be able to call it using the following requests:

xml <echo xmlns:xop='http://www.w3.org/2004/08/xop/include'> <msg>hello world</msg> <binary> <xop:Include href='binary'/> </binary> </echo>

provided that the JBI message contains an attachment named "binary".

Accessing the JBI exchange

Some times, while processing the incoming request, you need to access the underlying JBI exchange.
It can be done using the following code snippet:

java public String echo(String msg, DataHandler binary) { ... MessageExchange exchange = org.apache.servicemix.jsr181.JBIContext.getMessageExchange(); ... }
  • No labels