Showing posts with label Learning. Show all posts
Showing posts with label Learning. Show all posts

Wednesday, January 7, 2015

CXF - Feature vs Interceptor

When working with CXF you'll often see that the configuration of a certain capability can be done either via adding a feature or by adding a number of interceptors. In this post we'll briefly explain how the two are related to each other.

CXF Interceptor

Interceptors are the fundamental processing unit inside CXF. For example when a service is invoked, an InterceptorChain (an ordered list of interceptors) is created and invoked. Each interceptor gets a chance to do what they want with the incoming message. This can include reading it, transforming it, processing headers, validating the message, etc. Interceptors can be configured on the interceptor chains of CXF clients, CXF servers or the CXF bus.

When for example configuring logging of all messages on the CXF bus, we need to created the respective LoggingInInterceptor and LoggingOutInterceptor interceptors and add them to the different interceptor chains (InInterceptors, OutInterceptors, OutFaultInterceptors and InFaultInterceptors) which are in turn added to the CXF bus as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

<cxf:bus>
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outFaultInterceptors>
</cxf:bus>

</beans>

CXF Feature

A feature in CXF is a way of adding capabilities to a CXF Client, CXF Server or CXF Bus. In other words features provide a simple way to perform or configure a series of related tasks. These tasks can be things like adding a number of interceptors to a chain, configuring properties, setting up resources, etc.

For example, CXF ships with a LoggingFeature which does exactly the same as the configuration from the previous section. The feature encapsulates the creation of the different logging interceptors and then subsequently adding them to all the interceptor chains.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

<bean id="loggingFeature" class="org.apache.cxf.feature.LoggingFeature" />

<cxf:bus>
<cxf:features>
<ref bean="loggingFeature" />
</cxf:features>
</cxf:bus>

</beans>

Conclusion

If you need full control when enabling a certain CXF functionality then use interceptors. For example when you only want to log error messages, only configure the logging interceptors on the fault chains.

If you need the standard CXF functionality then use the corresponding feature. For example when you want to log all messages, then configure the logging feature as the notation will be shorter/simpler.

Monday, January 13, 2014

JMS - Message Structure Overview

The main goal of a JMS application is to produce and consume messages that can then be used by other software applications. This post details the basic structure of a JMS message which consists out of three parts: headers, properties and body. For a complete overview please check the Java Message Service Concepts chapter of The Java EE 6 Tutorial.


The JMS API defines the standard form of a JMS message, which should be portable across all JMS providers. The picture below illustrates the high level structure of a JMS message.
jms message structure

JMS Message Headers

The JMS message header part, contains a number of predefined fields that must be present in every JMS message. Most of the values in the header are set by the JMS provider (which overrides any client-set values) when the message is put on a JMS destination. The values are used by both clients and providers to identify and route messages. The table below lists the JMS message header fields, indicates how their values are set and describes the content of each header field.

Header FieldSet ByDescription
JMSDestinationsend or publish methodReturns a Destination object (a Topic or a Queue, or their temporary version) describing where the message was directed.
JMSDeliveryModesend or publish methodCan be DeliveryMode.NON_PERSISTENT or DeliveryMode.PERSISTENT; only persistent messages guarantee delivery in case of a crash of the brokers that transport it.
JMSExpirationsend or publish methodReturns a timestamp indicating the expiration time of the message; it can be 0 on a message without a defined expiration.
JMSPrioritysend or publish methodReturns a 0-9 integer value (higher is better) defining the priority for delivery. It is only a best-effort value.
JMSMessageIDsend or publish methodContains a generated ID for identifying a message, unique at least for the current broker. All generated IDs start with the prefix 'ID:', but you can override it with the corresponding setter.
JMSTimestampsend or publish methodReturns a long indicating the time of sending.
JMSCorrelationIDClientCan link a message with another, usually one that has been sent previously (typically used for a request/response scenario). For example, a reply can carry the ID of the original request message.
JMSReplyToClientIs a Destination object where replies should be sent, it can be null.
JMSTypeClientDefines a field for provider-specific or application-specific message types.
JMSRedeliveredJMS providerReturns a boolean indicating if the message is being delivered again after a delivery which was not acknowledge.

JMS Message Properties

You can create and set properties for JMS messages if you need values in addition to those provided by the header fields. Properties are optional and stored as standard Java name/value pairs. Property fields are most often used for message selection and filtering.

There are three kinds of message properties:
  1. Application-related properties: A Java application can assign application-related properties, which are set before the message is delivered.
  2. Provider-related properties: Every JMS provider can define proprietary properties that can be set either by the client or automatically by the provider. Provider-related properties are prefixed with 'JMS_' followed by the vendor name and the specific property name; for example: JMS_IBM_MsgType or JMS_SonicMQ_XQ.isMultipart
  3. Standard properties: These standardized properties are set by the JMS provider (if supported) when a message is sent. Standard property names start with 'JMSX'; for example: JMSXUserid or JMSXDeliveryCount.

JMS Message Body

The message body contains the main information that is being exchanged by the JMS message. The JMS API defines five message body formats, also called message types, which allow you to send and receive data in a number of forms. JMS specifies only the interface and does not specify the implementation. This approach allows for vendor-specific implementation and transportation of messages while using a common interface.

Message TypeBody Contains
TextMessageA java.lang.String object (for example, the contents of an XML file).
MapMessageA set of name-value pairs, with names as String objects and values as primitive types in the Java programming language. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
BytesMessageA stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format.
StreamMessageA stream of primitive values in the Java programming language, filled and read sequentially.
ObjectMessageA Serializable object in the Java programming language.
Some JMS vendor implementations have added additional non-standard messages types; for example SonicMQ provides a MultipartMessage message type.
The JMS API provides methods for creating messages of each type and for filling in their contents. For example, to create and send a TextMessage, you might use the following statements:
TextMessage message = session.createTextMessage();
message.setText(msg_text); // msg_text is a String
producer.send(message);

At the consuming end, a message arrives as a generic Message object and must be cast to the appropriate message type. You can use one or more getter methods to extract the message contents. The following code fragment uses the getText() method:
Message m = consumer.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}


This concludes the overview of the JMS message structure. If you found this post helpful or have any questions or remarks, please leave a comment.