Petals-SE-POJO 2.5.0+

Version 1 by Christophe DENEUX
on May 23, 2017 16:46.

compared with
Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (22)

View Page History
* if a {{public setComponentContext(ComponentContext context)}} setter method is defined, the component set its {{ComponentContext}} instance with this method at the initialization of the Service Unit.
* if a {{public setDeliveryChannel(DeliveryChannel channel)}} setter method is defined, the component set its {{DeliveryChannel}} instance with this method at the initialization of the Service Unit.
* if a {{public setJBIListener(AbstractJBIListener jbiListener)}} setter method is defined, the component set its {{JBIListener}} instance with this method at the initialization of the Service Unit.
* if a {{public setLogger(Logger logger)}} setter method is defined, the component set its {{Logger instance}} with this method at the initialization of the Service Unit.
* if a {{public void init()}} method is defined, the component invoke it at the initialization of the Service Unit.
* a {{public boolean onExchange(Exchange exchange, AbstractJBIListener jbiLIstener)}} MUST be provided.
* an {{public boolean onAsyncExchange(Exchange exchange, AsyncContext asyncContext)}} CAN be provided, optionally.
* a {{public boolean onAsyncExchange(Exchange subExchange, AsyncContext asyncContext, AbstractJBIListener jbiListener)}} CAN be provided, optionally.
* a {{public boolean onExpiredAsyncJBIMessage(Exchange subExchange, AsyncContext asyncContext, AbstractJBIListener jbiListener)}} CAN be provided, optionally.
* all methods can throw exceptions.
* FaultException are is used to represent business faults (as declared in the WSDL contract): the XML content of the Fault is passed to the constructor of the exception. exception,
* only one instance of the POJO class is instanciated by the component, so the POJO must be thread-safe state-less and thread-safe,
* to prevent memory leak, using of the singleton pattern is to prohibit.

When building such a Service Unit using Maven, the classes {{ComponentContext}} and {{DeliveryChannel}} are provided by the dependency {{petals-jbi}}, {{AbstractJBIListener}} and {{AsyncContext}} by {{petals-cdk-core}}, and {{Exchange}} by {{petals-cdk-api}}. These dependencies must be defined using the scope {{provided}} as they are provided by the container.

public class SamplePojoService {
AbstractJBIListener jbiListener;
Logger logger;
ComponentContext ctx;

public void setJBIListener(AbstractJBIListener jbiListener) {
this.jbiListener = jbiListener;
}
public void setComponentContext(ComponentContext ctx) {
this.ctx = ctx;
}

public boolean onExchange(Exchange exchange, AbstractJBIListener jbiListener)
throws MessagingException {
[...]
{code}

The method {{onExchange(Exchange exchange, AbstractJBIListener jbiListener)}} is invoked when an exchange is received from the component that is addressed to the current POJO endpoint.
The POJO must process the service in that method.
The POJO can invoke any 'sub-service' during its processing by synchronous invocations using the {{jbiListener}} instance.
h3. Process a service in the asynchronous way


A sample class following the above rules for processing service in the asynchronous way:
{code:java}

public class SamplePojoService {
AbstractJBIListener jbiListener;
Logger logger;
ComponentContext ctx;

public void setJBIListener(AbstractJBIListener jbiListener) {
this.jbiListener = jbiListener;
}
public void setComponentContext(ComponentContext ctx) {
this.ctx = ctx;
}

public boolean onExchange(Exchange exchange, AbstractJBIListener jbiListener)
throws MessagingException {
[...]
}

public boolean onAsyncExchange(Exchange subExchange, AsyncContext asyncContext, AbstractJBIListener jbiListener)
throws MessagingException {
[...]
}

public void onExpiredAsyncJBIMessage(Exchange subExchange, AsyncContext asyncContext, AbstractJBIListener jbiListener)
throws MessagingException {
[...Handle here the subExchange timeout...]
Processing a service in asynchronous way is the best approach when targeting performance, but it's more tedious to develop, and demands an average level in Petals development.
Basically, all is in the data that permit to correlate asynchronous sent exchange and their asynchronous response.
The original exchange is the received by the component and the process of the service start in the {{onExchange(Exchange exchange, AbstractJBIListener jbiListener)}} method.
The method create an asynchronous context, to set the data.
The method can create any 'sub-exchange' and send then asynchronously, with the asynchronous context as parameter.
Then the {{onExchange(Exchange exchange, AbstractJBIListener jbiListener)}} returns {{false}}, as the response or the acknowledgment of the original exchange is not yet ready to be sent back.
Any asynchronous response from the 'sub-exchange' comes back in the {{onAsyncExchange(Exchange subExchange, AsyncContext asyncContext, AbstractJBIListener jbiListener)}} method. During the process of this method, the 'sub-exchange' must be handled according to the MEP, and the returns {{true}} of the method let the CDK send the 'sub-exchange' to the partner.
Once all 'sub-exchanges' are received, the 'original' exchange can be retrieve from the asynchronous context and the response or acknowledgement send back explicitly.
If a 'sub-service' do not response at time, the {{onExpiredAsyncJBIMessage(...)}} method will be invoked by the CDK. You must handle the timeout of the 'sub-exchange' in this method.
Note that once a {{sendAsync(...)}} has expired, the POJO does not have the ownership of the exchange anymore (because it was sent but never came back) and can't access anything else than the exchangeId and the exchange status! The {{AsyncContext}}, which can be subclassed when needed, is there to store needed information in these situations.



h2. Service Configuration

{table-plus}



{center}{*}Configuration of a Service Unit to provide a service (POJO)*{center}
|| Parameter || Description || Default || Required ||