Saturday, July 7, 2012

Spring Integration - Session 1 - Hello World

The "Hello World" of Spring Integration - consider a simple program to print "Hello World" to the console using Spring Integration and in the process visit a few Enterprise Integration Patterns Concepts

Before jumping into the program itself, a quick review of messaging concepts will be helpful - Messaging is an Integration style where two independent applications communicate with each other through an intermediary - the intermediary is referred to as the "Messaging System". 

Enterprise Integration Patterns describes the common Integration related issues with Messaging based application Integration and their recommended solutions.

For eg. Consider one of the Enterprise Integration Patterns - The Messaging Channel, to quote from the Entprise Integration Patterns Book:

The problem "Messaging Channel" is trying to solve is:

An enterprise has two separate applications that need to communicate, preferably by using Messaging.
How does one application communicate with another using messaging?

The solution is:
Connect the applications using a Message Channel, where one application writes information to the channel and the other one reads that information from the channel. 

All the other Enterprise Integration Patterns are described along the same lines.

The reason to quickly visit Enterprise Integration Patterns is to set the context - Spring Integration aligns very closely with the Enterprise Integration Patterns and is the "Messaging system" that was mentioned earlier.

So now to see the Hello World using Spring Integration:

First a small junit:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("helloworld.xml")
public class HelloWorldTest {
 
 @Autowired
 @Qualifier("messageChannel")
 MessageChannel messageChannel;

 @Test
 public void testHelloWorld() {
  Message<String> helloWorld = new GenericMessage<String>("Hello World");
  messageChannel.send(helloWorld);
 }
}

Here a MessageChannel is being wired into the test, the first application (here the Junit), sends a Message(in this case a string "Hello World") to the Message Channel, something reads the message from the "Message Channel" and writes the message to the system out.

Now, let us see the remaining part of how "something" picks up a message from the Message Channel and writes to the system out:
<?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:int="http://www.springframework.org/schema/integration"
 xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
 xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd
  http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-2.2.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <int:channel id="messageChannel"></int:channel>
 
 <int-stream:stdout-channel-adapter channel="messageChannel" append-newline="true"/>
</beans>

The above is a Spring Integration flow being described using Spring Custom namespaces, here the Integration Namespace. A "Message Channel", imaginatively called the "messageChannel" is created, a "Hello World" "Message" is placed into the "Messsage Channel", from which a "Channel Adapter" gets the message and prints it to the standard out.

This is a small program, but it uses three Enterprise Integration Patterns - the Message ("Hello World", which is the packet of information being sent to the messaging system, the "Message Channel" which was introduced earlier and the new one, the Channel Adapter, here an Outbound Channel Adapter which connects the messaging system to the application(in this case the system out). It further shows how Spring Integration aligns very closely with the Enterprise Integration Patterns terminology with its Spring custom namespace.

This simple program introduces Spring Integration, I will be introducing Spring Integration in more detail using a few more samples in the next few sessions.

References:
1. Spring Integration Reference: http://static.springsource.org/spring-integration/reference/htmlsingle/
2. Enterprise Integration Patterns: http://www.eaipatterns.com/index.html
3. Visio templates for EIP : http://www.eaipatterns.com/downloads.html

8 comments:

  1. Please include your import statements or provide the sample code as an attachment.

    ReplyDelete
  2. Include the following dependencies in pom.xml;


    org.springframework.integration
    spring-integration-stream
    ${spring.integration.version}


    org.springframework
    spring-test
    ${spring.version}


    where junit.version and spring.version are
    4.10
    3.0.7.RELEASE

    ReplyDelete
  3. Include the following dependencies in pom.xml;


    org.springframework.integration
    spring-integration-stream
    ${spring.integration.version}


    org.springframework
    spring-test
    ${spring.version}


    where junit.version and spring.version are
    4.10
    3.0.7.RELEASE

    ReplyDelete
  4. Include the following dependencies in Maven's pom.xml


    org.springframework.integration
    spring-integration-stream
    ${spring.integration.version}


    org.springframework
    spring-test
    ${spring.version}


    where the properties spring.integration.version, spring.version are


    2.1.2.RELEASE
    4.10
    3.0.7.RELEASE

    ReplyDelete
  5. dear , I encounter an error below
    The matching wildcard is strict, but no declaration can be found for element 'int-stream:stdout-channel-adapter'.

    I found that if I add "" to the config file , then this error will appear , would you please give any suggestion ?

    ReplyDelete
    Replies
    1. wow,I found the reason now , as I haven't inculde the dependency "spring-integration-stream" , sorry for the careless ,

      Delete
  6. Thanks for this post!

    ReplyDelete
  7. Thanks for this post.

    helloworld.xml header update:
    <?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:int="http://www.springframework.org/schema/integration"
    xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration
    http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/stream
    http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">

    ...
    </beans>

    POM.xml update:
    Latest version of spring integration (2.2.3.RELEASE) and latest version of spring test (3.2.3.RELEASE) are incompatible.Prefer to use [2.2.3.RELEASE] with [3.2.3.RELEASE]

    java.lang.IncompatibleClassChangeError: class org.springframework.core.type.classreading.ClassMetadataReadingVisitor has interface org.springframework.asm.ClassVisitor as super class


    <dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-stream</artifactId>
    <version>2.2.3.RELEASE</version>
    </dependency>

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>3.1.3.RELEASE</version>
    <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
    </dependency>

    ReplyDelete