The CDK provides some utility methods to work with WSDL interfaces.
A utility class related to WSDL is listed in the next chapter.
However, there are some features this utility class does not yet provide.
Indeed, the CDK cannot ensure that the called operation is in the service interface, or that the input message is valid with respect to the operation schema.
Therefore, working with WSDLs in component implementations is managed by hand.
In particular, the following elements are not performed by default by the CDK:
* The exchange's called operation is defined in the WSDL.
* The exchange's in message content is valid with respect to the operation XML schema.
* The exchange returned by your component respects the operation XML schema (messages and faults).
h2. Utility methods within the CDK
The CDK offers several utility methods, available in org.ow2.petals.component.framework.util.
Here is a partial list of these CDK utility classes:
* org.ow2.petals.component.framework.util.ClassLoaderUtil
* org.ow2.petals.component.framework.util.FileNamePatternUtil
* org.ow2.petals.component.framework.util.IDGenerator
* org.ow2.petals.component.framework.util.NormalizedMessageUtil
* org.ow2.petals.component.framework.util.SourceUtilImpl
* org.ow2.petals.component.framework.util.StringHelper
* org.ow2.petals.component.framework.util.UtilFactory
* org.ow2.petals.component.framework.util.WSDLUtilImpl
* org.ow2.petals.component.framework.util.XMLUtil
You can refer to the Java doc of these classes for more details.
h1. JBI listeners, the CDK and Exception handling
h2. The problematic
The exception handling in *JBI listeners* is a little bit specific, compared to other classes.
This section explains how to determine the exceptions to process in your component, and those the CDK can handle itself.
A JBI listener receives an exchange, processes, completes and returns it. Always.
The content of the returned exchange depends on the Message Exchange Pattern (MEP).
The exception handling depends on the used MEP.
h2. An example
Let's take the example of the *InOnly* MEP. With this MEP, you can only set a status on the exchange.
If the reception results in an exception, then an error should be set on the returned exchange.
You can do that in two ways:
* If the qualified name of the exception starts with *java.*, *org.w3c.* or *org.xml.*, you can directly use {code:lang=java}exchange.setError( yourException );{code}
* Otherwise, you must create a *MessagingException* and copy the stack trace of the caught exception.
This is achieved with:
{code:lang=xml}
MessagingException msgException = new MessagingException( ExceptionUtil.getExtendedMessage( yourException ));
exchange.setError( msgException );
{code}
\\
This difference in the exception handling is true for all the MEPs with the *Error* status.
For *faults*, things are different. A fault must be defined in the WSDL of the service-unit.
It can be set from the caught exception using {code:lang=java}exchange.setFault( yourException );{code}
h2. Concretely
Eventually, to ease this thin handling, you should avoid to catch every exception, that is to say avoid:
{code:lang=java}
try {
// Process the received exchange
...
} catch( Exception e ) {
// Log or something
...
}
{code}
\\
Instead, process each possible exception separately:
{code:lang=java}
try {
// Process the received exchange
...
} catch( TransformerException e ) {
// Log or something
...
} catch( MessagingException e ) {
// Log or something
...
} catch( IOException e ) {
// Log or something
...
}
{code}
\\
What would happen if a *NullPointerException* is thrown during the processing?
Well, that's simple. The CDK will catch it and make the appropriate move.
If you wanted to catch every exception, you should test its name and take the appropriate decision then.
But it is already done in the CDK. Why would you reinvent the wheel?
h2. Summary
{tip}
If an exception handler updates the exchange, you must be careful to the exception type.
If the handler does not modify the exchange, do what you want in it.
{tip}
{tip}
If the exception handler sets an error on the exchange, it must act differently in function of the exception name.
*java.*, *org.w3c.* and *org.xml.* exceptions can directly be set on the exchange as errors.
Other exceptions must be transformed in a MessagingException that will be set as an error on the exchange.
{tip}
h1. Using logs correctly in components
Components have access to a logger (java.util.logging.Logger) which is initially configured by the CDK.
This logger can be got by using the method AbstractComponent#getLogger().
In the different component classes, such as the message listeners or the service-unit manager, you can access the component and its logger.
However, you have to be careful about the way you log things.
\\
For the moment, logs mix both messages and exceptions that occur in the component.
Unfortunately, it is not possible to proceed differently for the moment.
This should be changed in future versions of the CDK.
Logs format can also be configured, but it is not easy.
A potential good practice to make your log more readable would be to append the name of your component as a prefix to the first message.
The timestamp is logged by default.
Here are some good-practices to respect when you use logs in your component.
\\
{tip}
*Log guideline 1*
Make your message have less than 80 characters per line.
{tip}
Logs may be displayed in a shell.
Therefore, this limitation of 80 characters should be respected as much as possible.
*Line 1:* a message of less than 80 characters.
*Following lines (optional):* a stack trace.
\\
{tip}
*Log guideline 2*
Check the log level before logging (This is highly recommended when logging contains expressions and time consuming things such as XML serialization\!\!\!).
{tip}
This will increase performances by avoiding useless or undesired logs.
Example:
{code:lang=java}
Logger log = getLogger();
if( log.isLoggable( Level.INFO ))
log.info( "your log message" );
Logger log = getLogger();
if( log.isLoggable( Level.DEBUG ))
log.debug( "your log message" );
{code}
\\