Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

ServiceMix

...

Bean

...

The

...

ServiceMix

...

Bean

...

component

...

provides

...

integration

...

with

...

beans

...

(POJOs)

...

with

...

the

...

JBI

...

bus

...

to

...

make

...

it

...

easy

...

to

...

use

...

POJOs

...

to

...

process

...

JBI

...

message

...

exchanges.

...

Like

...

in

...

an

...

Message

...

Driven

...

Bean

...

in

...

J2EE

...

a

...

POJO

...

will

...

receive

...

a

...

message

...

from

...

the

...

NMR

...

and

...

process

...

it

...

in

...

any

...

way

...

it

...

likes.

...

Unlike

...

in

...

a

...

JMS

...

component

...

where

...

the

...

coding

...

is

...

already

...

done

...

the

...

Bean

...

component

...

gives

...

the

...

developer

...

the

...

freedom

...

to

...

create

...

any

...

type

...

of

...

message

...

handling

...

but

...

it

...

must

...

be

...

hand

...

coded

...

all

...

the

...

way.

POJOs

There are several kind of POJOs you can deploy to servicemix-bean.

MessageExchangeListener

The first kind of POJOs you can deploy implement the MessageExchagneListener interface. In such a case, servicemix-bean acts as a replacement of the lightweight container component. This level offers the most control on the exchange received and sent. This is usually used with the injected DeliveryChannel to send back the exchanges, or if the POJOs needs to act as a consumer (i.e. creating and sending exchanges to other services).

These POJOs are low-level POJOs: you need to understand the JBI Api and Message Exchange Patterns to correctly handle incoming exchanges.

Note that at this point (v 3.1), there is no base class that you can inherit to speed you in this process of implementing a POJO to handle JBI exchanges, but hopefully it will come in the future.

Section
Column

This example on the right shows the most simple bean. When it receives an exchange, it will print it to the console and set the status to DONE before sending the exchange back.
This bean can not handle InOut exchanges, as it does not set any response (an exception would be thrown in such a case).

Column
Code Block
langjava
titleTrace example

import org.apache.servicemix.MessageExchangeListener;

import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;

public class ListenerBean implements MessageExchangeListener {

    @Resource
    private DeliveryChannel channel;

    public void onMessageExchange(MessageExchange exchange) throws MessagingException {
        System.out.println("Received exchange: " + exchange);
        exchange.setStatus(ExchangeStatus.DONE);
        channel.send(exchange);
    }

}
Section
Column

This example will handle an InOut exchange and will send back the input as the response.
Note that this example would fail if receiving an InOnly exchange, as setting a response on an InOnly exchange is not a legal operation.

Column
Code Block
langjava
titleEcho example

import org.apache.servicemix.MessageExchangeListener;
import org.apache.servicemix.jbi.util.MessageUtil;

import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;

public class ListenerBean implements MessageExchangeListener {

    @Resource
    private DeliveryChannel channel;

    public void onMessageExchange(MessageExchange exchange) throws MessagingException {
        if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
            MessageUtil.transferInToOut(exchange, exchange);
            channel.send(
h2. POJOs There are several kind of POJOs you can deploy to {{servicemix-bean}}. h3. {{MessageExchangeListener}} The first kind of POJOs you can deploy implement the [{{MessageExchagneListener}}|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/core/servicemix-core/apidocs/org/apache/servicemix/MessageExchangeListener.html] interface. In such a case, {{servicemix-bean}} acts as a replacement of the [lightweight container|servicemix-lwcontainer] component. This level offers the most control on the exchange received and sent. This is usually used with the injected {{DeliveryChannel}} to send back the exchanges, or if the POJOs needs to act as a consumer (i.e. creating and sending exchanges to other services). These POJOs are low-level POJOs: you need to understand the JBI Api and Message Exchange Patterns to correctly handle incoming exchanges. Note that at this point (v 3.1), there is no base class that you can inherit to speed you in this process of implementing a POJO to handle JBI exchanges, but hopefully it will come in the future. {section} {column} This example on the right shows the most simple bean. When it receives an exchange, it will print it to the console and set the status to DONE before sending the exchange back. This bean can not handle InOut exchanges, as it does not set any response (an exception would be thrown in such a case). {column} {column} {code:lang=java|title=Trace example} import org.apache.servicemix.MessageExchangeListener; import javax.annotation.Resource; import javax.jbi.messaging.DeliveryChannel; import javax.jbi.messaging.ExchangeStatus; import javax.jbi.messaging.MessageExchange; import javax.jbi.messaging.MessagingException; public class ListenerBean implements MessageExchangeListener { @Resource private DeliveryChannel channel; public void onMessageExchange(MessageExchange exchange) throws MessagingException { System.out.println("Received exchange: " +
exchange);
        
exchange.setStatus(ExchangeStatus.DONE);
}
    }

}

Disclaimer

As of 3.1 to 3.1.2 the ServiceMix Bean component will not handle asynchronous messages correctly because the final send of the message marked as DONE back to the NMR will be handled as a consumer message and that fails because there is no corresponding provider message. The only workaround right now is to use send the messages synchronously.

Deployment

Currently (v 3.1), servicemix-bean supports two different deployment models. The first one uses an xbean.xml configuration file where one can configure the different endpoints / beans that will be used. The other one only works with a static configuration file (servicemix.xml) and can not be used with standard JBI packaging but allows automatic detection of the beans to expose.

xbean.xml

Code Block
xml
xml

<beans xmlns:bean="http://servicemix.apache.org/bean/1.0">

  <bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>

  <bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>

</beans>

Attention: The Bean Endpoint schema allows to set a Bean or a Bean Name. The Bean will create a single instance of the POJO per endpoint whereas the Bean Name will create an instance per request (message exchange).

Static configuration

When used in a static configuration, beans can be automatically discovered amongst spring configured beans:

Code Block
langxml

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"    channel.send(exchange);
    }

}
{code}
{column}
{section}

{section}
{column}
This example will handle an InOut exchange and will send back the input as the response.
Note that this example would fail if receiving an InOnly exchange, as setting a response on an InOnly exchange is not a legal operation.
{column}
{column}
{code:lang=java|title=Echo example}
import org.apache.servicemix.MessageExchangeListener;
import org.apache.servicemix.jbi.util.MessageUtil;

import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;

public class ListenerBean implements MessageExchangeListener {

    @Resource
    private DeliveryChannel channel;

    public void onMessageExchange(MessageExchange exchange) throws MessagingException {
        if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
       xmlns:test="urn:test">

  <sm:container   MessageUtil.transferInToOut(exchange, exchange);
id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        channel.send(exchange);<sm:component>
        }
  <bean:component/>
        </sm:component>
      </sm:activationSpec>
    </sm:activationSpecs>
  </sm:container>

  <bean id="consumerBean" class="org.apache.servicemix.bean.beans.ConsumerBean"/>
  <bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>
  <bean id="annotatedBean" class="org.apache.servicemix.bean.beans.AnnotatedBean"/>
  <bean id="plainBean" class="org.apache.servicemix.bean.beans.PlainBean"/>

</beans>

Such beans can be accessed by resolving a URI:

Code Block
langjava

DocumentFragment epr = URIResolver.createWSAEPR("bean:annotatedBean");
ServiceEndpoint se = client.getContext().resolveEndpointReference(epr);
exchange.setEndpoint(se);

Beans can also be discovered by searching within defined packages:

Code Block
langxml

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"
       xmlns:test="urn:test">

  <sm:container id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        <sm:component>
          <bean:component searchPackages="org.apache.servicemix.bean.beans"/>
        </sm:component>
      </sm:activationSpec>
    </sm:activationSpecs>
  </sm:container>

</beans>

In such a case, beans must have the @Endpoint annotation.

Of course, you can use the endpoint xml element to configure your POJOs:

Code Block
langxml

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"
       xmlns:test="urn:test">

  <sm:container id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        <sm:component>
          <bean:component>
            <bean:endpoints>
              <bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>
            </bean:endpoints>}

}
{code}
{column}
{section}

h3. Disclaimer

As of 3.1 to 3.1.2 the ServiceMix Bean component will not handle asynchronous messages correctly because the final send of the message marked as DONE back to the NMR will be handled as a consumer message and that fails because there is no corresponding provider message. The only workaround right now is to use send the messages synchronously.

h2. Deployment

Currently (v 3.1), servicemix-bean supports two different deployment models.  The first one uses an xbean.xml configuration file where one can configure the different endpoints / beans that will be used.  The other one only works with a static configuration file (servicemix.xml) and can not be used with standard JBI packaging but allows automatic detection of the beans to expose.

h3. {{xbean.xml}}

{code:xml}
<beans xmlns:bean="http://servicemix.apache.org/bean/1.0">

  <bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>

  <bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>

</beans>
{code}

*Attention*: The Bean Endpoint schema allows to set a Bean or a Bean Name. The Bean will create a *single* instance of the POJO per endpoint whereas the Bean Name will create an instance per request (message exchange).

h3. Static configuration

When used in a static configuration, beans can be automatically discovered amongst spring configured beans:

{code:lang=xml}
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"
       xmlns:test="urn:test">

  <sm:container id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        <sm:component>
          <bean:component/>  </bean:component>
        </sm:component>
      </sm:activationSpec>
    </sm:activationSpecs>
  </sm:container>

  <bean id="consumerBean" class="org.apache.servicemix.bean.beans.ConsumerBean"/>
  <bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>
  <bean id="annotatedBean" class="org.apache.servicemix.bean.beans.AnnotatedBean"/>
  <bean id="plainBean" class="org.apache.servicemix.bean.beans.PlainBean"/>

</beans>
{code}

Such beans can be accessed by resolving a URI:

{code:lang=java}
DocumentFragment epr = URIResolver.createWSAEPR("bean:annotatedBean");
ServiceEndpoint se = client.getContext().resolveEndpointReference(epr);
exchange.setEndpoint(se);
{code}

Beans can also be discovered by searching within defined packages:

{code:lang=xml}
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"
       xmlns:test="urn:test">

  <sm:container id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        <sm:component>
          <bean:component searchPackages="org.apache.servicemix.bean.beans"/>
        </sm:component>
      </sm:activationSpec>
    </sm:activationSpecs>
  </sm:container>

</beans>
{code}

In such a case, beans must have the {{@Endpoint}} annotation.

Of course, you can use the {{endpoint}} xml element to configure your POJOs:

{code:lang=xml}
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:bean="http://servicemix.apache.org/bean/1.0"
       xmlns:test="urn:test">

  <sm:container id="jbi" embedded="true" createMBeanServer="false">
    <sm:activationSpecs>
      <sm:activationSpec>
        <sm:component>
          <bean:component>
            <bean:endpoints>
              <bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>
            </bean:endpoints>
          </bean:component>
        </sm:component>
      </sm:activationSpec>
    </sm:activationSpecs>
  </sm:container>

  <bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>

</beans>
{code}

*Note*: Please make sure that the namespace specified at the top _xmlns:test_ does match to the namespace used in the endpoint's service _test:service_. When calling the service by the service name then you need to add the namespace in order to find the service like *_{urn:test}service_*.

h2. MessageExchange dispatching

If the POJO deployed implements the {{org.apache.servicemix.MessageExchangeListener}}, every message received for this POJO will be dispatched to the {{onMessageExchange}} method.

In other cases, exchanges in a provider role will be dispatched according to the {{MethodInvocationStrategy}} configured on the endpoint.  The default one try to find the method according to the operation name defined on the exchange.  If there is only a single method acting as an operation, it will always be used.

h2. Annotations

The {{servicemix-bean}} component can accept different kind of POJOs.  These POJOs may be annotated to customize their behavior.  All the following annotations belong to the {{org.apache.servicemix.bean}} package.

|| Annotation || Target || Description ||
| [Callback|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Callback.html] | Method | |
| [Content|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Content.html] | Parameter | |
| [Correlation|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Correlation.html] | Type | |
| [Endpoint|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Endpoint.html] | Type | This annotation is mandatory if the bean is automatically searched from a list of packages. |
| [ExchangeTarget|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/ExchangeTarget.html] | Field | |
| [Operation|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Operation.html] | Method | |
| [Property|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Property.html] | Parameter | |
| [XPath|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/XPath.html] | Parameter | |

In addition, standard annotations can be used:

|| Annotation || Target || Description ||
| [Resource|http://java.sun.com/javase/6/docs/api/javax/annotation/Resource.html] | Field | The Resource annotation marks a resource that is needed by the application.  Currently, this annotation is only supported on fields of type {{ComponentContext}} and {{DeliveryChannel}}. The component will inject the specified resource when the POJO is instantiated. |
| [PostConstruct|http://java.sun.com/javase/6/docs/api/javax/annotation/PostConstruct.html] | Method | The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. |
| [PreDestroy|http://java.sun.com/javase/6/docs/api/javax/annotation/PreDestroy.html] | Method | The PreDestroy annotation is used on methods as a callback notification to signal that the instance is in the process of being removed by the container. |

The following interfaces are part of this API:

|| Interface || Description ||
| [MessageExchangeListener|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/core/servicemix-core/apidocs/org/apache/servicemix/MessageExchangeListener.html] | When the POJO implements this interface, *all* exchanges will be dispatched to the {{onMessageExchange}} method. |
| [Destination|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/apidocs/org/apache/servicemix/bean/Destination.html] | This interface can be used to define a property on the bean, annotated with the {{@ExchangeTarget}} annotation.  This is a very simple API to send exchanges from a POJO.  More complex use cases can use an injected {{DeliveryChannel}} directly or to create a ServiceMix [client|Client API]. |

h2. Examples

* [AnnotatedBean|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/xref-test/org/apache/servicemix/bean/beans/AnnotatedBean.html]
* [AutoDeployedBean|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/xref-test/org/apache/servicemix/bean/beans/AutoDeployedBean.html]
* [ConsumerBean|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/xref-test/org/apache/servicemix/bean/beans/ConsumerBean.html]
* [ListenerBean|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/xref-test/org/apache/servicemix/bean/beans/ListenerBean.html]
* [PlainBean|http://incubator.apache.org/servicemix/dist/servicemix-3.1-incubating/site/deployables/serviceengines/servicemix-bean/xref-test/org/apache/servicemix/bean/beans/PlainBean.html]

h2. URI 

You can use a handy URI to refer to beans using the Spring names of beans.

{code}
bean:someName
{code}

The above would refer to the bean named _someName_ in the Spring ApplicationContext which is used to boot up the bean 
</beans>

Note: Please make sure that the namespace specified at the top xmlns:test does match to the namespace used in the endpoint's service test:service. When calling the service by the service name then you need to add the namespace in order to find the service like {urn:test}service.

MessageExchange dispatching

If the POJO deployed implements the org.apache.servicemix.MessageExchangeListener, every message received for this POJO will be dispatched to the onMessageExchange method.

In other cases, exchanges in a provider role will be dispatched according to the MethodInvocationStrategy configured on the endpoint. The default one try to find the method according to the operation name defined on the exchange. If there is only a single method acting as an operation, it will always be used.

Annotations

The servicemix-bean component can accept different kind of POJOs. These POJOs may be annotated to customize their behavior. All the following annotations belong to the org.apache.servicemix.bean package.

Annotation

Target

Description

Callback

Method

 

Content

Parameter

 

Correlation

Type

 

Endpoint

Type

This annotation is mandatory if the bean is automatically searched from a list of packages.

ExchangeTarget

Field

 

Operation

Method

 

Property

Parameter

 

XPath

Parameter

 

In addition, standard annotations can be used:

Annotation

Target

Description

Resource

Field

The Resource annotation marks a resource that is needed by the application. Currently, this annotation is only supported on fields of type ComponentContext and DeliveryChannel. The component will inject the specified resource when the POJO is instantiated.

PostConstruct

Method

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.

PreDestroy

Method

The PreDestroy annotation is used on methods as a callback notification to signal that the instance is in the process of being removed by the container.

The following interfaces are part of this API:

Interface

Description

MessageExchangeListener

When the POJO implements this interface, all exchanges will be dispatched to the onMessageExchange method.

Destination

This interface can be used to define a property on the bean, annotated with the @ExchangeTarget annotation. This is a very simple API to send exchanges from a POJO. More complex use cases can use an injected DeliveryChannel directly or to create a ServiceMix client.

Examples

URI

You can use a handy URI to refer to beans using the Spring names of beans.

Code Block

bean:someName

The above would refer to the bean named someName in the Spring ApplicationContext which is used to boot up the bean component.