Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Creating

...

a

...

Hello

...

World

...

JBI

...

Binding Component

Warning
titleATTENTION!


*This tutorial page is a work in progress and it may contain outdated information or may not work at all.
There are currently no plans to resume work on this tutorial.




Tip
titleShould I Create My Own JBI Components?

NOTE: Before beginning this tutorial, please take the time to read the FAQ entry titled Should I Create My Own JBI Components?. It is very important that you understand the reason for developing a JBI binding component and this FAQ entry will explain this.

This tutorial describes how to create a very simple Hello World style of JBI binding component. This tutorial is as minimalistic as possible so as to focus on key concepts and not drown in details. The Hello World binding component will respond to all requests with the message:

Panel

<hello>Hello World! Message [<original message here>] contains [??] bytes.</hello>

The following sections will walk through the creation, packaging, testing and deployment of the Hello World binding component.

Prerequisites

  • Maven 2.0.7 or higher
    • If you have never used Maven previously the Maven Getting Started Guide explains some valuable concepts surrounding Maven
  • ServiceMix 3.2.1 or higher
  • A broadband internet connection so Maven can automatically download dependencies

A Very Brief Introduction to Java Business Integration

The Java Business Integration (JBI) spec provides a standards-based, service-oriented approach to application integration through the use of an abstract messaging model, without reference to a particular protocol or wire encoding. JBI introduces the concepts of Binding Components (BCs), Service Engines (SEs) to Service Units (SUs) and Service Assemblies (SAs) to define an architecture for vendor-neutral pluggable components. The purpose of this architecture is to provide standards-based interoperability amongst components/services.

JBI components are can be thought of as the smallest applications or services accessible in a service-oriented architecture. Each service has a very specific purpose and therefore a narrow scope and set of functionality. Components come in two flavors: Service Engines (SE) and Binding Components (BC). SUs must be packaged into a SA to be deployed to the JBI container. An SA is a complete application consisting of one or more services. By comparison, this is similar to the way that WAR files must be packaged inside of an EAR file to be deployed to a J2EE container.

See also the page providing information on working with service units

Below are some quick definitions the are dominant throughout the JBI spec:

  • Component Architecture
    • Binding Components - Components that provide or consume services via some sort of communications protocol or other remoting technology
    • Service Engines - Components that supply or consume services locally (within the JBI container)
Note

The difference between binding components (BCs) and service engines (SEs) is definitely subtle and is not denoted by the JBI APIs. In fact, the only real true difference between the two is in the jbi.xml descriptor in the packaging. What it really boils down to is the fact that BCs are used to do integration with a service outside the bus and SEs are services that are deployed to and solely contained within the bus. Hopefully the JBI 2.0 spec will provide more distinction.

  • Component Packaging
    • Service Units - Packaging for an individual service that allows deployment to the JBI container; similar to a WAR file from J2EE
    • Service Assemblies - Packaging for groups of SUs for deployment to the JBI container; similar to an EAR file from J2EE

This tutorial focuses on both component architecture and component packaging. For further information and details on JBI, see the following:

Now let's move on to creating the Maven projects for the Hello World binding component.

Creating a Maven Project For the JBI BC

The focus of this section is on the creation of a JBI binding component. For this task, a Maven archetype will be used to create a Maven project skeleton to house the component. Maven archetypes are templates for Maven projects that jumpstart project creation via the automation of repetitive tasks by following standard conventions. The result of using an archetype to create a Maven project is a directory structure, a Maven POM file and, depending on the archetype being used, sometimes Java objects and JUnit tests.

Below are the steps to follow for creating the directory structure and project. All instructions are laid out to take place on a Unix command-line.

1) Create a directory named hello-world-smx and switch to that directory:

Code Block
 Component

This tutorial describes how to create a very simple Hello World style of JBI binding component. This tutorial is as minimalistic as possible so as to focus on key concepts and not drown in details. The Hello World binding component will respond to all requests with the message: 

{panel}
<hello>Hello World! Message \[<original message here>\] contains \[??\] bytes.</hello>
{panel}

The following sections will walk through the creation, packaging, testing and deployment of the Hello World binding component. 

h2. Prerequisites

* Maven 2.0.4 or higher 
** If you have never used Maven previously the Maven [Getting Started Guide|http://maven.apache.org/guides/getting-started/index.html] explains some valuable concepts surrounding Maven 
* ServiceMix 3.1-incubating-SNAPSHOT or higher 
** See the [ServiceMix downloads|http://servicemix.org/site/download.html] to grab a nightly build as ServiceMix 3.1 has not yet been released
* A broadband internet connection so Maven can automatically download dependencies 

h2. A Very Brief Introduction to Java Business Integration 

The [Java Business Integration (JBI) spec|http://jcp.org/en/jsr/detail?id=208] provides a standards-based, service-oriented approach to application integration through the use of an abstract messaging model, without reference to a particular protocol or wire encoding. JBI introduces the concepts of Binding Components (BCs), Service Engines (SEs) to  Service Units (SUs) and Service Assemblies (SAs) to define an architecture for vendor-neutral pluggable components. The purpose of this architecture is to provide standards-based interoperability amongst components/services. 

JBI components are can be thought of as the _smallest applications_ or _services_ accessible in a service-oriented architecture. Each service has a very specific purpose and therefore a narrow scope and set of functionality. Components come in two flavors: Service Engines (SE) and Binding Components (BC). SUs must be packaged into a SA to be deployed to the JBI container. An SA is a _complete application_ consisting of one or more services. By comparison, this is similar to the way that WAR files must be packaged inside of an EAR file to be deployed to a J2EE container. 

See also the page providing information on [working with service units|http://incubator.apache.org/servicemix/main/working-with-service-units.html]

Below are some quick definitions the are dominant throughout the JBI spec: 

* *Component Architecture*
** *Binding Components* - Components that provide or consume services via some sort of communications protocol or other remoting technology 
** *Service Engines* - Components that supply or consume services locally (within the JBI container) 

{note}
The difference between binding components (BCs) and service engines (SEs) is definitely subtle and is not denoted by the JBI APIs. In fact, the only real true difference between the two is in the {{jbi.xml}} descriptor in the packaging. What it really boils down to is the fact that BCs are used to do integration with a service outside the bus and SEs are services that are deployed to and solely contained within the bus. Hopefully the JBI 2.0 spec will provide more distinction. 
{note}

* *Component Packaging*
** *Service Units* - Packaging for an individual service that allows deployment to the JBI container; similar to a WAR file from J2EE 
** *Service Assemblies* - Packaging for groups of SUs for deployment to the JBI container; similar to an EAR file from J2EE 

This tutorial focuses on both component architecture and component packaging. For further information and details on JBI, see the following: 

* The [JBI spec|http://jcp.org/en/jsr/detail?id=208]
* The [JBI|5. JBI] section of the [User's Guide] 
* The [JBIforSOI|https://open-esb.dev.java.net/public/whitepapers/JBIforSOI.pdf] article 
* The [ServiceMix as an enterprise service bus|http://www.javaworld.com/javaworld/jw-12-2005/jw-1212-esb.html] JavaWorld article 

Now let's move on to creating the Maven projects for the Hello World binding component. 

h2. Creating a Maven Project For the JBI BC 

The focus of this section is on the creation of a JBI binding component. For this task, a [Maven archetype|http://maven.apache.org/guides/introduction/introduction-to-archetypes.html] will be used to create a Maven project skeleton to house the component. Maven archetypes are templates for Maven projects that jumpstart project creation via the automation of repetitive tasks by following standard conventions. The result of using an archetype to create a Maven project is a directory structure, a [Maven POM|http://maven.apache.org/guides/introduction/introduction-to-the-pom.html] file and, depending on the archetype being used, sometimes Java objects and JUnit tests. 

Below are the steps to follow for creating the directory structure and project. All instructions are laid out to take place on a Unix command-line. 

1) Create a directory named {{hello-world-smx}} and switch to that directory: 

{code}
$ mkdir hello-world-smx
$ cd hello-world-smx
{code}

2)

...

Use

...

the

...

servicemix-binding-component

...

Maven

...

archetype

...

to

...

generate

...

a

...

Maven

...

project

...

for

...

the

...

component.

...

To

...

create

...

a

...

SE,

...

execute

...

the

...

following

...

command

...

on

...

the

...

command-line:

Panel

$ mvn

{panel} $ mvn

archetype:create

\


-DarchetypeGroupId=org.apache.servicemix.tooling

\


-DarchetypeArtifactId=servicemix-binding-component

\


-DarchetypeVersion=3.2.1

-incubating-SNAPSHOT \

\
-DgroupId=org.apache.servicemix.samples.helloworld.bc

\


-DartifactId=hello-world-bc

-su {panel} The command above will create a directory named {{

The command above will create a directory named hello-world-bc

...

that

...

houses

...

a

...

Maven

...

project

...

for

...

the

...

JBI

...

service

...

engine

...

being

...

created

...

here.

...

The

...

name

...

of

...

the

...

directory

...

is

...

taken

...

from

...

the

...

artifactId

...

parameter.

...

The

...

first

...

three

...

parameters

...

to

...

the

...

mvn

...

command

...

(-DarchetypeGroupId=org.apache.servicemix.tooling

...

-DarchetypeArtifactId=servicemix-binding-component

...

-DarchetypeVersion=3.2.1

...

)

...

identify

...

which

...

Maven

...

archetype

...

to

...

use

...

for

...

the

...

archetype:create

...

goal,

...

while

...

the

...

last

...

two

...

parameters

...

(-DgroupId=org.apache.servicemix.samples.helloworld.bc

...

-DartifactId=hello-world-bc

...

)

...

uniquely

...

identify

...

the

...

Maven

...

project

...

that

...

is

...

being

...

generated.

...

The

...

groupId

...

is

...

used

...

as

...

the

...

Java

...

package

...

and

...

the

...

artifactId

...

is

...

used

...

as

...

the

...

project

...

name.

...

Therefore,

...

only

...

alphanumeric

...

characters

...

are

...

valid

...

values

...

for

...

the

...

groupId

...

and

...

artifactId

...

parameters.

Tip

The value of the archetypeVersion parameter in the command above (3.2.1) may need to be updated to the current ServiceMix version in order for the command to work correctly. The latest version can always be found in the top level ServiceMix POM in the <version> element.

The output from executing the archetype:create goal is shown below:

No Format
 

{tip} 
The value of the {{archetypeVersion}} parameter in the command above (3.1-incubating-SNAPSHOT) may need to be updated to the current ServiceMix version in order for the command to work correctly. The latest version can always be found [in the top level ServiceMix POM|http://fisheye3.cenqua.com/browse/servicemix/trunk/pom.xml?r=trunk] in the {{<version>}} element. 
{tip}

The output from executing the {{archetype:create}} goal is shown below:

{noformat}
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   A custom project
[INFO]   A custom project
[INFO]   Hello World JBI Component
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building HelloMaven WorldDefault JBI ComponentProject
[INFO]    task-segment: [archetype:create] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] ************************************************************** 
[INFO] Starting Jakarta Velocity v1.4
[INFO] RuntimeInstance initializing.
[INFO] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties
[INFO] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl)
[INFO] Resource Loader Instantiated: org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader
[INFO] ClasspathResourceLoader : initialization starting.
[INFO] ClasspathResourceLoader : initialization complete.
[INFO] ResourceCache : initialized. (class org.apache.velocity.runtime.resource.ResourceCacheImpl)
[INFO] Default ResourceManager initialization complete.
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Include
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
[INFO] Created: 20 parsers.
[INFO] Velocimacro : initialization starting.
[INFO] Velocimacro : adding VMs from VM library template : VM_global_library.vm
[ERROR] ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
[INFO] Velocimacro : error using  VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: 
Unable to find resource 'VM_global_library.vm'
[INFO] Velocimacro :  VM library template macro registration complete.
[INFO] Velocimacro : allowInline = true : VMs can be defined inline in templates
[INFO] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
[INFO] Velocimacro : allowInlineLocal = false : VMs defined inline will be  global in scope if allowed.
[INFO] Velocimacro : initialization complete.
[INFO] Velocity successfully started.
[INFO] [archetype:create]
[INFO] Defaulting package to group ID: org.apache.servicemix.samples.helloworld.bc
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating Archetype: servicemix-binding-component:3.2.1-incubating-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.apache.servicemix.samples.helloworld.bc
[INFO] Parameter: packageName, Value: org.apache.servicemix.samples.helloworld.bc
[INFO] Parameter: basedir, Value: /Users/bsnyder/src/hello-world-smx
[INFO] Parameter: package, Value: org.apache.servicemix.samples.helloworld.bc
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: hello-world-bc-su

[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 6885,column 16] : 
${servicemix-version} is not a valid reference.
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 7390,column 16] : 
${servicemix-version} is not a valid reference.
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 97115,column 18] : 
${xbean-version} is not a valid reference.
[INFO] ********************* End of debug info from resources from generated POM ***********************
[INFO] Archetype created in dir: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23 seconds
[INFO] Finished at: MonTue JanMar 1506 1318:3527:4408 MST 2007
[INFO] Final Memory: 5M4M/10M8M
[INFO] ------------------------------------------------------------------------
{noformat}

Again,

...

Maven

...

creates

...

a

...

directory

...

using

...

the

...

artifactId

...

provided

...

as

...

the

...

directory

...

name.

...

Inside

...

this

...

directory

...

resides

...

the

...

pom.xml

...

and

...

the

...

src

...

directory.

...

If

...

you

...

see

...

the

...

BUILD

...

SUCCESSFUL

...

message,

...

proceed

...

to

...

the

...

next

...

section.

...

Otherwise

...

see

...

the

...

note

...

below

...

about

...

a

...

BUILD

...

ERROR.

Note
titleIn case of a BUILD ERROR: Maven plugin version requirement

The

{note:title=In case of a BUILD ERROR: Maven plugin version requirement} The

maven-archetype-plugin

*

1.0-alpha4

*

or

above

is

required

for

this

tutorial.

When

an

older

version

is

installed,

a

build

error

will

occur.

The

version

of

this

plugin

can

be

checked

by

verifying

the

name

of

the

following

directories:

{code:title=Unix}

Code Block
titleUnix

~/.m2/repository/org/apache/maven/plugins/maven-archetype-plugin 
{code} {code:title=Windows}
Code Block
titleWindows

C:\Documents and Settings\<USERNAME>\.m2\repository\org\apache\maven\plugins\maven-archetype-plugin
{code} In case the only version available of the

In case the only version available of the maven-archetype-plugin

is

an

older

one,

a

minimal

{{

pom.xml

}}

file

will

need

to

be

created

manually

in

the

{{

hello-world-bc

-su}}

directory.

Below

is

a

simple

POM

to

use

for

this

purpose:

{code:title=Minimal

Code Block
titleMinimal pom.xml
}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.apache.servicemix.samples.helloworld</groupId>
  <artifactId>hello-world-
bc-su<
bc</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-archetype-plugin</artifactId>
          <version>1.0-alpha-4</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Compiling the Project

Since we just created this project, we should first compile it just to make sure nothing is wrong with what the archetype generated. To compile, package and test the project, execute the following command from the command-line:

Code Block
{code}
{note}

h2. Compiling the Project 

Since we just created this project, we should first compile it just to make sure nothing is wrong with what the archetype generated. To compile, package and test the project, execute the following command from the command-line: 

{code}
$ cd ./hello-world-bc-su
$ mvn install 
{code}

This

...

command

...

should

...

produce

...

the

...

following

...

output:

No Format
 

{noformat}
[INFO] Scanning for projects...
[INFO] artifact org.apache.servicemix.tooling:jbi-maven-plugin: checking for updates from apache.incubating
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] artifact org.apache.maven.plugins:maven-install-plugin: checking for updates from apache.incubating
Downloading: http://people.apache.org/repo/m2-incubating-repository/xml-security/xmlsec/1.3.0/xmlsec-1.3.0.pom
[WARNING] Unable to get resource from repository apache.incubating (http://people.apache.org/repo/m2-incubating-repository)
Downloading: http://repo.mergere.com/maven2/xml-security/xmlsec/1.3.0/xmlsec-1.3.0.pom
[WARNING] Unable to get resource from repository central (http://repo1.maven.org/maven2)
Downloading: http://people.apache.org/repo/m2-incubating-repository/wss4j/wss4j/1.5.0/wss4j-1.5.0.pom
[WARNING] Unable to get resource from repository apache.incubating (http://people.apache.org/repo/m2-incubating-repository)
Downloading: http://repo.mergere.com/maven2/wss4j/wss4j/1.5.0/wss4j-1.5.0.pom
[WARNING] Unable to get resource from repository central (http://repo1.maven.org/maven2)
[INFO] [xbean:mapping {execution: default}]
Checking: org.apache.servicemix.samples.helloworld.MyComponent
Checking: [xbean:mapping {execution: default}]
Checking: org.apache.servicemix.samples.helloworld.bc.MyComponent
Checking: org.apache.servicemix.samples.helloworld.bc.MyConsumerEndpoint
Checking: org.apache.servicemix.samples.helloworld.bc.MyProviderEndpoint
[INFO] Generating META-INF properties file: 
/Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld.bc/1.0 for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/spring.handlers for namespace: 
http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/spring.schemas for namespace: 
http://org.apache.servicemix.samples.helloworld.MyConsumerEndpoint
Checking: org.apache.servicemix.samples.helloworld.MyProviderEndpointbc/1.0
[INFO] Generating META-INFHTML propertiesdocumentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld/1.0hello-world-bc.xsd.html for namespace: 
http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating Spring 2.0 handler mappingXSD file: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/META-INF/spring.handlers 
hello-world-bc.xsd for namespace: 
http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating SpringWIKI 2.0 schema mappingdocumentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/META-INF/spring.schemas 
hello-world-bc.xsd.wiki for namespace: 
\http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/hello-world-bc-su.xsd.html 
for namespace: http://Warning, could not load class: org.apache.servicemix.samples.helloworld.bc.MyEndpointType: java.lang.ClassNotFoundException: 
org.apache.servicemix.samples.helloworld/1.0.bc.MyEndpointType
[INFO] Generating XSD file: 
/Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/hello-world-bc-su.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating WIKI documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/hello-world-bc-su.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0Warning, could not load class: org.apache.servicemix.samples.helloworld.MyEndpointType: java.lang.ClassNotFoundException: org.apache.servicemix.samples.helloworld.MyEndpointType
[INFO] ...done.
[INFO] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml...done.
[INFO] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 5 source files to /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.bc.MySpringComponentTest
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
log4j:WARN Please initialize the log4j system properly.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.52431 sec

Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/hello-world-bc-su-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFOWARNING] Attempting Generatingto installer /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/hello-world-bc-su-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Usersbuild MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/hello-world-bc-su-1.0-SNAPSHOT-installer.zip
[INFO] Building [install:install]
[INFO] Installingjar: /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/hello-world-bc-su-1.0-SNAPSHOT.jar -installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc-su/1.0-SNAPSHOT/hello-world-bc-su-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/hello-world-bc-su.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc-su/1.0-SNAPSHOT/hello-world-bc-su-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/xbean/hello-world-bc-su.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc-su/1.0-SNAPSHOT/hello-world-bc-su-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc-su/target/hello-world-bc-su-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc-su/1.0-SNAPSHOT/hello-world-bc-su-1.0-SNAPSHOT-installer.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1615 seconds
[INFO] Finished at: MonTue JanMar 1506 2118:4729:51 MST 2007
[INFO] Final Memory: 13M/31M28M
[INFO] ------------------------------------------------------------------------
{noformat}

Again, the key here is to make sure you see BUILD SUCCESSFUL. This means that the project skeleton created by the archetype was compiled, packaged and tested successfully. Now we just need to add some custom functionality. 

h2. Creating the JBI Component 

Before we create any custom functionality, let's first examine some of the items generated by the servicemix-service-engine Maven archetype in this simple component we're developing. These classes extend class from either the [JBI spec APIs|http://java.sun.com/integration/1.0/docs/sdk/api/index.html] or from the [{{servicemix-common}}|http://fisheye3.cenqua.com/browse/servicemix/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common] package. 

* {{pom.xml}} - This is the [Maven POM|http://maven.apache.org/guides/introduction/introduction-to-the-pom.html]] file. This XML file contains all the metadata related to the project so Maven can carry out its functionality. 

* {{MyBootstrap.java}} - Implements [{{javax.jbi.component.Boostrap}}|http://java.sun.com/integration/1.0/docs/sdk/api/javax/jbi/component/Bootstrap.html] which is called by the JBI container as part of the component lifecycle 

Your output may look slightly different because Maven will download the required artifacts. Again, the key here is to make sure you see BUILD SUCCESSFUL. This means that the project skeleton created by the archetype was compiled, packaged and tested successfully. Now we just need to add some custom functionality.

Creating the JBI Component

Before we create any custom functionality, let's first examine some of the items generated by the servicemix-binding-component Maven archetype in this simple component we're developing. These classes extend class from either the JBI spec APIs or from the servicemix-common package.

  • pom.xml - This is the Maven POM] file. This XML file contains all the metadata related to the project so Maven can carry out its functionality.
  • src/main/java/org/apache/servicemix/samples/bc/MyBootstrap.java - Implements javax.jbi.component.Boostrap which is called by the JBI container as part of the component lifecycle (i.e.g,

...

  • when

...

  • the

...

  • component

...

  • is

...

  • installed

...

  • and

...

  • uninstalled).

...

  • This

...

  • is

...

  • where

...

  • you

...

  • place

...

  • logic

...

  • to

...

  • set

...

  • up

...

  • and

...

  • tear

...

  • down

...

  • things

...

  • when

...

  • the

...

  • component

...

  • is

...

  • started

...

  • and

...

  • stopped

...

  • . This class is no longer needed.
  • src/main/java/org/apache/servicemix/samples/bc/MyComponent.java

...

  • -

...

  • Extends

...

  • the

...

  • DefaultComponent, a convenience class that makes creating JBI components much easier and provides some additional lifecycle management for the BC when it's deployed to the JBI container. This class should be fleshed out by overriding methods in the DefaultComponent to configure and initialize the component.
  • src/main/java/org/apache/servicemix/samples/bc/MyConsumerEndpoint.java - Extends ConsumerEndpoint and implements MyEndpointType. If you'd like to create a BC that fulfills the consumer role, implement the process() method in this class.
  • src/main/java/org/apache/servicemix/samples/bc/MyEndpointType.java - This class is simply an interface marker for Apache XBean so it can generate an XML schema document.
  • src/main/java/org/apache/servicemix/

...

  • samples/

...

  • bc/

...

  • MyProviderEndpoint.java

...

...

  • like

...

  • to

...

  • create

...

  • a

...

  • BC

...

  • that

...

  • fulfills

...

  • the

...

  • provider role, depending on the MEP being supported, you will need to implement the processInOnly() method or the processInOut() method in this class.
  • src/main/java/org/apache/servicemix/samples/bc/MyEndpointType.java - This is a marker interface used by XBean so it can generate a XML schema.
  • src/test/java/org/apache/servicemix/samples/bc/MySpringComponentTest.java - A simple JUnit test class that extends a helper class to make configuring ServiceMix very easy.
  • src/test/resources/spring.xml - A very simple and generic ServiceMix configuration file for use with the MySpringComponentTest.

Now that we've gotten a bird's eye view of what we're working with, let's proceed to adding the custom functionality.

Adding Custom Functionality

Before creating custom functionality for the BC, you need to understand the role of a JBI BC. A BC is simply a binding to a service that is external to the JBI normalized message router (NMR) using some type of communications protocol (e.g., FTP, HTTP, JMS, etc.). It's also the responsibility of the BC to handle any conversion of the message format into a normalized message so that can be sent along to the NMR. This is known as message normalization.

Just as an example, if we were to create a BC that uses SNMP as the application layer protocol, the SNMP RFC specifies the message format to be used with particular versions of SNMP. It would be the responsibility of the BC to handle not only the communication via the SNMP protocol but also to handling the marshalling of SNMP messages to/from JBI normalized messages. The BC would simply be a binding to a service external to the NMR that speaks SNMP messages via the SNMP protocol.

More on this later in the tutorial. For now, let's proceed with the custom functionality.

Note
titleUsing an IDE

It is at this stage that you should employ the use of an IDE. An IDE can dramatically reduce the work necessary to import clases, override methods and so much more. Because Maven can easily generate project files for Eclipse or IntelliJ IDEA, either one can be used. Throughout this tutorial, Eclipse will be used. To generate project files for Eclipse, execute the Maven eclipse:eclipse goal from the command line and then import the project into your Eclipse IDE.

The creation of a binding component is dependent upon the role that it will play. BCs are consumers, providers or both. Below are definitions of the two roles as they pertain to BCs:

  • Consumer - A consumer BC receives requests from a service external to the JBI container and publishes those requests to the NMR.
  • Provider - A provider BC receives requests from the NMR and publishes those requests to a service that is external to the JBI container.

This is why both the MyConsumerEndpoint.java and the MyProviderEndpoint.java files exist when using the servicemix-binding-component archetype to create a Maven project. This way the BC that you're creating can play either the consumer role or the provider role or both. For the sake of this tutorial, we will implement the provider role. Let's proceed to implement the provider functionality. To do so, open MyProviderEndpoint.java and let's take a look at he processInOut() method as shown below:

Code Block

protected void processInOut(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws Exception {
    throw new UnsupportedOperationException("Unsupported MEP: " + exchange.getPattern());
}

One important item of note before we get started is that this tutorial will not actually be accessing any services external to the JBI container. The reason for this is that setting up a service external to the JBI container would dramatically increase the complexity of this tutorial. Instead, we will just simulate such functionality by hard-coding some text to be returned.

The processInOut() method is just a stub that needs to be populated with our custom functionality. Below is the method body that can be copied and pasted into the method stub add some custom functionality. Following the display of this method, we will pick apart this method a bit to explain the various pieces of logic:

Code Block

protected void processInOut(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws Exception {
	// Grab the in message 
	SourceTransformer sourceTransformer = new SourceTransformer();
	DOMSource inMessageXml = (DOMSource) sourceTransformer.toDOMSource(in); 
	
	// Parse out the actual message content 
	CachedXPathAPI xpath = new CachedXPathAPI();
	Node inMessageNode = xpath.selectSingleNode(inMessageXml.getNode(), "/hello");
	String inMessage = inMessageNode.getTextContent(); 
	
	// Create the out message and set it 
	String outMessage = "<hello>Message [" + inMessage + "] contains [" + inMessage.getBytes().length + "] bytes</hello>";
	out.setContent(new StringSource(outMessage));
}

Adding this method will require the import of the following classes:

  • javax.xml.transform.dom.DOMSource
  • org.apache.servicemix.jbi.jaxp.SourceTransformer
  • org.apache.servicemix.jbi.jaxp.StringSource
  • org.apache.xpath.CachedXPathAPI
  • org.w3c.dom.Node

All of these classes can be found in either the servicemix-core project or its transitive dependencies. If you're using Eclipse, you can tell Eclipse to automatically import them by selecting Source->Organize Imports.

Note
titleImportant Information!

This tutorial will not be accessing any services external to the JBI container. Instead, we will just simulate such functionality by hard-coding some text to be returned.

Now let's move on to testing this component and then we'll compile and test it.

Testing the Hello World Binding Component

Thanks to the Maven archetype, testing the component is very easy because it already created a test. The only change we'll make is to the string being sent by the client code. In the src/test/java directory is the org.apache.servicemix.samples.helloworld.bc.MySpringComponentTest test. Simply open this test and change line #36 from this:

Code Block

me.getInMessage().setContent(new StringSource("<hello>world</hello>"));

to something more meaningful, like this:

Code Block

me.getInMessage().setContent(new StringSource("<hello>Ski Colorado!</hello>"));

Also, add the following block of code to line # 40 below the comment:

Code Block

if (me.getStatus() == ExchangeStatus.ERROR) {
    if (me.getError() != null) { 
        throw me.getError();
    } else {
        fail("Received ERROR status");
    }       
} else if (me.getFault() != null) { 
    fail("Received fault: " + new SourceTransformer().toString(me.getFault().getContent()));
}
System.err.println(new SourceTransformer().toString(me.getOutMessage().getContent()));
client.done(me);

Though there are no asserts in the test, it is more about seeing visual confirmation of the message being output to the console when running the test. So to compile the source and to execute the test, simply run the Maven install goal on the command line from within the hello-world-bc directory like so:

Code Block

$ mvn install 

Below is the output that will print to the console:

No Format

[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [xbean:mapping {execution: default}]
Checking: org.apache.servicemix.samples.helloworld.bc.MyComponent
Checking: org.apache.servicemix.samples.helloworld.bc.MyConsumerEndpoint
Checking: org.apache.servicemix.samples.helloworld.bc.MyProviderEndpoint
[INFO] Generating META-INF properties file: 
/Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/services/org/apache/xbean/spring/http/org.apache.servicemix.samples.helloworld.bc/1.0 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/hello-world-bc.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/hello-world-bc.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] Generating WIKI documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/hello-world-bc.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld.bc/1.0
[INFO] ...done.
[INFO] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.bc.MySpringComponentTest
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
log4j:WARN Please initialize the log4j system properly.
<?xml version="1.0" encoding="UTF-8"?>
<hello>Message [Ski Colorado!] contains [13] bytes</hello>
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.635 sec

Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[WARNING] Attempting to build MavenProject instance for Artifact of type: jar; constructing POM artifact instead.
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc/1.0-SNAPSHOT/hello-world-bc-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/hello-world-bc.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc/1.0-SNAPSHOT/hello-world-bc-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/xbean/hello-world-bc.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc/1.0-SNAPSHOT/hello-world-bc-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-bc/target/hello-world-bc-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/bc/hello-world-bc/1.0-SNAPSHOT/hello-world-bc-1.0-SNAPSHOT-installer.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15 seconds
[INFO] Finished at: Tue Mar 06 19:59:50 MST 2007
[INFO] Final Memory: 13M/25M
[INFO] ------------------------------------------------------------------------

Notice that not only do we see that the build was successful, but also note the text in the output above that was printed by the test:

<?xml version="1.0" encoding="UTF-8"?><hello>Message [Ski Colorado!] contains [13] bytes</hello>

This is the message we were expecting to be output from the test. So if you see this, you just wrote a JBI component and tested your first JBI BC successfully.

Now let's look at how this component is deployed to ServiceMix.

Deploying the BC to ServiceMix

Thanks to Maven, this BC has already been packaged properly to be deployed to ServiceMix. Just take a look in the target directory of the project and you will see the zip file:

Panel

$ ls -l ./target | awk {'print $9'}

classes
hello-world-bc-1.0-SNAPSHOT-installer
hello-world-bc-1.0-SNAPSHOT-installer.zip
hello-world-bc-1.0-SNAPSHOT.jar
jbi.xml
surefire-reports
test-classes
xbean

This zip file contains everything needed to deploy the BC to ServiceMix. This can be done by simply copying the zip file to the ServiceMix component installation directory. By default, this is a directory named install. However, this does not complete the deployment of the BC.

In order to actually make use of the BC, you will need to create a JBI service unit (SU) that uses the BC. A SU is really just a configuration for a JBI component to tell it how to behave. Just like all the JBI components that come with ServiceMix, in order to use one, you will need to create a SU that configures it, telling the JBI container how the component should behave. But the situation with this component is a bit different. Because the Hello World BC contains a hard-coded message, there's not much configuration to be done other than just stating that it should be used. So let's create the SU for the Hello World BC and then we'll move on to testing it.

Creating a Hello World BC Service Unit

This is a work in progress

Wrapping the Service Unit in a Service Assembly

The component we created above and packaged as a SU cannot be directly deployed to a JBI container until it's wrapped in a SA. This can be done by creating a SA with a dependency on the SA. From within the hello-world-smx directory, execute the following commands to create the project for the SA:

Code Block
 implement the {{process()}} method in this class. 

* {{MyEndpointType.java}} - This class is simply an interface marker for [Apache XBean|http://geronimo.apache.org/xbean] so it can generate an XML schema document. 

* {{MyProviderEndpoint.java}} - Extends [{{ProviderEndpoint}}|http://fisheye3.cenqua.com/browse/servicemix/trunk/common/servicemix-common/src/main/java/org/apache/servicemix/common/endpoints/ProviderEndpoint.java?r=trunk] and implements {{MyEndpointType}}. If you'd like to create a BC that fulfills the provider role, depending on the MEP being supported, implement the {{processInOnly()}} method or the {{processInOut()}} method in this class. 

* {{MySpringComponentTest.java}} - A simple JUnit test class that extends a helper class to make configuring ServiceMix very easy. 

* {{src/test/resources/spring.xml}} - The very simple and generic ServiceMix configuration file. 

Now that we've gotten a bird's eye view of what we're working with, let's proceed to adding the custom functionality. 

h3. Adding Custom Functionality 

Before creating custom functionality for the BC, you need to understand the role of a JBI BC. A BC is simply a binding to a service that is external to the JBI normalized message router (NMR) using some type of communications protocol (e.g., FTP, HTTP, JMS, etc.). It's also the responsibility of the BC to handle any conversion of the message format into [Normalized Messages|http://servicemix.org/site/5-jbi.html#5.JBI-Normalizedmessage] that can be sent along to the NMR. This is known as message normalization. 

For example, if we were to create a BC that uses [SNMP|http://www.protocols.com/pbook/tcpip9.htm#SNMP] as the application layer protocol, the SNMP RFC specifies the message format to be used with particular versions of SNMP. It would be the responsibility of the BC to handle not only the communication via the SNMP protocol but also to handling the marshalling of SNMP messages to/from JBI normalized messages. The BC would simply be a binding to a service external to the NMR that speaks SNMP messages via the SNMP protocol. 

More on this later in the tutorial. For now, let's proceed with the custom functionality. 

{note:title=Using an IDE}
It is at this stage that you should employ the use of an IDE. An IDE can dramatically reduce the work necessary to import clases, override methods and so much more. Because Maven can generate project files for Eclipse and IntelliJ IDEA, either one can be used. Throughout this tutorial, Eclipse will be used. To generate project files for Eclipse, execute the Maven {{eclipse:eclipse}} goal and then import the project into your Eclipse IDE. 
{note}

The creation of a binding component is dependent upon the role that it will play. BCs are consumers, providers or both. Below are definitions of the two roles as they pertain to BCs: 

* *Consumer* - A consumer BC receives requests from an external service and publishes those requests to the NMR. 
* *Provider* - A provider BC receives requests from the NMR and publishes those requests to an external service. 

This is why both the {{MyConsumerEndpoint.java}} and the {{MyProviderEndpoint.java}} exist when using the servicemix-binding-component archetype to create a Maven project for a SU. This way the BC that you're creating can play both the consumer role and the provider role. For the sake of this tutorial, we will create implement both roles. 

First let's implement the consumer functionality. To do so, open {{MyConsumerEndpoint.java}} and let's take a look at he {{process()}} method as shown below: 

{code}
public void process(MessageExchange exchange) throws Exception {
    // TODO: As we act as a consumer (we just send JBI exchanges)
    // we will receive responses or DONE / ERROR status here
}
{code}

One important item of note before we get started is that this tutorial will not be accessing any services external to the JBI container. The reason for this is that setting up a service external to the JBI container would dramatically increase the complexity of this tutorial. Instead, we will just simulate such functionality by hard-coding some text to be returned. 

This method is just a stub that needs to be filled in with our custom functionality. Take note of the comment in that method stub stating that this method will send JBI message exchanges and will receive responses or status messages in this method. Based on these comments, we know that we have a few tasks to handle in the implementation of this method. So let's get started. 

Below is the method body that can be copied and pasted into the method stub. Following the display of this method, we will pick apart this method a bit to explain the various pieces of logic: 

{code:title=The {{MyConsumerEndpoint.process()}} Method}
public void process(MessageExchange exchange) throws Exception {
    // TODO: As we act as a consumer (we just send JBI exchanges)
    // we will receive responses or DONE / ERROR status here
	
	// The component acts as a consumer, this means this exchange is received because
    // we sent it to another component.  As it is active, this is either an out or a fault
    // If this component does not create / send exchanges, you may just throw an UnsupportedOperationException
    if (exchange.getRole() == MessageExchange.Role.CONSUMER) {
        // Exchange is finished
        if (exchange.getStatus() == ExchangeStatus.DONE) {
            return;
        // Exchange has been aborted with an exception
        } else if (exchange.getStatus() == ExchangeStatus.ERROR) {
            return;
        // Exchange is active
        } else {
            // Out message
            if (exchange.getMessage("out") != null) {
                // TODO ... handle the response
                exchange.setStatus(ExchangeStatus.DONE);
                getChannel().send(exchange);
            // Fault message
            } else if (exchange.getFault() != null) {
                // TODO ... handle the fault
                exchange.setStatus(ExchangeStatus.DONE);
                getChannel().send(exchange);
            // This is not compliant with the default MEPs
            } else {
                throw new IllegalStateException("Consumer exchange is ACTIVE, but no out or fault is provided");
            }
        }
    // Unknown role
    } else {
        throw new IllegalStateException("Unkown role: " + exchange.getRole());
    }
}
{code}



{note:title=Important Information!}
This tutorial will not be accessing any services external to the JBI container. Instead, we will just simulate such functionality by hard-coding some text to be returned. 
{note}

imports

* {{javax.jbi.messaging.ExchangeStatus}} 
* 

_This is a work in progress. I will finish this up very soon._

h2. Testing the Hello World Binding Component

Thanks to the archetype, testing the component is very easy because it already created a test. The only change we'll make is to the string being sent by the client code. In the {{src/test/java}} directory is the {{org.apache.servicemix.samples.helloworld.bc.MySpringComponentTest}} test. Simply open this test and change line #36 from this: 

{code}
me.getInMessage().setContent(new StringSource("<hello>world</hello>"));
{code}

to something more meaningful, like this: 

{code}
me.getInMessage().setContent(new StringSource("<hello>Ski Colorado!</hello>"));
{code}

To execute the test, simply run the Maven {{install}} goal from within the {{hello-world-bc-su}} directory like so: 

{code}
$ mvn install 
{code}

Below is the output that will print to the console: 

{noformat}

{noformat}

Notice that not only do we see that the build was successful, but also note the text in the output above that was printed by the test (*<hello>Hello World! Message \[<hello>Ski Colorado!</hello>\] contains \[28\] bytes.</hello>*). This is the message we were expecting to be output from the test. So if you see this, you just wrote a JBI component and tested it successfully. Now this SU needs to be wrapped in a SA so it can be deployed to the JBI container. 

h2. Wrapping the Service Unit in a Service Assembly 

The component we created above and packaged as a SU cannot be directly deployed to a JBI container until it's wrapped in a SA. This can be done by creating a SA with a dependency on the SA. From within the {{hello-world-smx}} directory, execute the following commands to create the project for the SA: 

{code}
$ pwd
/Users/bsnyder/src/hello-world-smx/hello-world-bc-su
$ cd .. 
$ mvn archetype:create \
    -DarchetypeGroupId=org.apache.servicemix.tooling \
    -DarchetypeArtifactId=servicemix-service-assembly \
    -DarchetypeVersion=3.2.1-incubating-SNAPSHOT \
    -DgroupId=org.apache.servicemix.samples.helloworld \
    -DartifactId=hello-world-sa
{code}

Upon

...

successful

...

execution

...

of

...

the

...

archetype:create

...

goal,

...

look

...

for

...

the

...

BUILD

...

SUCCESSFUL

...

output

...

as

...

displayed

...

below:

No Format
 

{noformat}
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:create] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] ************************************************************** 
[INFO] Starting Jakarta Velocity v1.4
[INFO] RuntimeInstance initializing.
[INFO] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties
[INFO] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl)
[INFO] Resource Loader Instantiated: org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader
[INFO] ClasspathResourceLoader : initialization starting.
[INFO] ClasspathResourceLoader : initialization complete.
[INFO] ResourceCache : initialized. (class org.apache.velocity.runtime.resource.ResourceCacheImpl)
[INFO] Default ResourceManager initialization complete.
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Include
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
[INFO] Created: 20 parsers.
[INFO] Velocimacro : initialization starting.
[INFO] Velocimacro : adding VMs from VM library template : VM_global_library.vm
[ERROR] ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
[INFO] Velocimacro : error using  VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: 
Unable to find resource 'VM_global_library.vm'
[INFO] Velocimacro :  VM library template macro registration complete.
[INFO] Velocimacro : allowInline = true : VMs can be defined inline in templates
[INFO] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
[INFO] Velocimacro : allowInlineLocal = false : VMs defined inline will be  global in scope if allowed.
[INFO] Velocimacro : initialization complete.
[INFO] Velocity successfully started.
[INFO] [archetype:create]
[INFO] Defaulting package to group ID: org.apache.servicemix.samples.helloworld
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating Archetype: servicemix-service-assembly:3.2.1-incubating-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.apache.servicemix.samples.helloworld
[INFO] Parameter: packageName, Value: org.apache.servicemix.samples.helloworld
[INFO] Parameter: basedir, Value: /Users/bsnyder/src/hello-world-smx
[INFO] Parameter: package, Value: org.apache.servicemix.samples.helloworld
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: hello-world-sa
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 71,column 18] : 
${servicemix-version} is not a valid reference.
[INFO] ********************* End of debug info from resources from generated POM ***********************
[INFO] Archetype created in dir: /Users/bsnyder/src/hello-world-smx/hello-world-sa
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Fri Jan 05 23:40:32 MST 2007
[INFO] Final Memory: 4M/8M
[INFO] ------------------------------------------------------------------------
{noformat}

The {{

The hello-world-smx

...

directory

...

should

...

now

...

contain

...

the

...

following

...

two

...

directories:

Code Block
 

{code}
$ ls 
hello-world-sa hello-world-bc-su
{code}

If you see the above directories, proceed to the next step below. If instead you see the BUILD FAILED output, you'll need to analyze the rest of the output to troubleshoot the issue. Assistance with any issue you might experience is available from the ServiceMix community via the [ServiceMix mailing lists archive|Mailing Lists]. 

Now that we have a project for the SA, we need to edit the POM so that the project depends upon the JBI component we created above. This can be done by editing the POM for the SA to add a dependency upon the {{hello-world-bc-su}} as listed below: 

{code}

If you see the above directories, proceed to the next step below. If instead you see the BUILD FAILED output, you'll need to analyze the rest of the output to troubleshoot the issue. Assistance with any issue you might experience is available from the ServiceMix community via the ServiceMix mailing lists archive.

Now that we have a project for the SA, we need to edit the POM so that the project depends upon the JBI component we created above. This can be done by editing the POM for the SA to add a dependency upon the hello-world-bc as listed below:

Code Block
<dependency>
  <groupId>org.apache.servicemix.samples.helloworld.bc</groupId>
  <artifactId>hello-world-bc-su<bc</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
{code}

Upon

...

adding

...

this

...

dependency

...

to

...

the

...

POM,

...

build

...

the

...

project

...

using

...

the

...

command

...

below:

Code Block
 

{code}
$ cd hello-world-sa
$ mvn install 
{code}

{noformat}

{noformat}

h2. Incorporating the Projects Into a Top Level POM

Now that we have created the SU and SA projects, a top level {{pom.xml}} must be manually created and made aware of each subproject. This will allow all the projects to be built automatically without having to build each project in order manually. Maven will discover all the projects and build them in the proper order. In the {{hello-world-bc-su}} directory, create a file named {{pom.xml}} containing the following content:

{code}
No Format

Incorporating the Projects Into a Top Level POM

Now that we have created the SU and SA projects, a top level pom.xml must be manually created and made aware of each subproject. This will allow all the projects to be built automatically without having to build each project in order manually. Maven will discover all the projects and build them in the proper order. In the hello-world-smx directory, create a file named pom.xml containing the following content:

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>org.apache.servicemix.samples.helloworld</groupId>
  <artifactId>hello-world-smx</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Hello World JBI Component</name>

  <modules>
    <module>hello-world-sa</module>
    <module>hello-world-bc-su<bc</module>
  </modules>

</project>

{code}

This

...

POM

...

will

...

allow

...

the

...

example

...

to

...

be

...

easily

...

folded

...

in

...

to

...

the

...

ServiceMix

...

samples.

...

The

...

<modules>

...

element

...

denotes

...

the

...

other

...

projects

...

that

...

were

...

created

...

above

...

using

...

the

...

Maven

...

archetypes.

...

Once

...

the

...

pom.xml

...

file

...

from

...

above

...

is

...

saved

...

into

...

the

...

hello-world-smx

...

directory,

...

you

...

should

...

now

...

see

...

the

...

following:

Code Block
 

{code}
$ ls 
hello-world-sa hello-world-bc-su pom.xml
{code}

All

...

projects

...

can

...

now

...

be

...

built

...

using

...

the

...

following

...

command

...

on

...

the

...

command-line

...

from

...

the

...

top

...

level

...

hello-world-smx

...

directory:

Code Block
 

{code}
$ mvn clean install 
{code}

The

...

command

...

above

...

should

...

display

...

the

...

output

...

below:

...

No Format

As long as you see the BUILD SUCCESSFUL message in the output continue to the next section to give each project a unique name.

Give Each of the Maven Subprojects a Name

Notice in the output above that there are a two projects named A custom project. This is because the archetypes create projects with this generic name. Let's give each project a unique name via each component's pom.xml file. This name will allow Maven's output to denote a component's name in its output making our development work a bit easier. To name each project, simply edit each pom.xml and replace <name>A custom project</name> with an appropriate name. Below are the instructions for naming each component's project:

  • Edit hello-world-sa/pom.xml

...

  • and

...

  • replace

...

  • <name>A

...

  • custom

...

  • project</name>

...

  • with

...

  • <name>Hello

...

  • World

...

  • Service

...

  • Assembly</name>

...

  • Edit hello-world-bc

...

  • /pom.xml

...

  • and

...

  • replace

...

  • <name>A

...

  • custom

...

  • project</name>

...

  • with

...

  • <name>Hello

...

  • World

...

  • BC

...

  • Service

...

  • Unit</name>

...

Now

...

when

...

the

...

projects

...

are

...

built

...

you

...

will

...

no

...

longer

...

see

...

a

...

project

...

named

...

A

...

custom

...

project

...

.

...

Instead

...

you'll

...

now

...

see

...

Hello

...

World

...

SE

...

Service

...

Unit

...

and

...

Hello

...

World

...

Service

...

Assembly

...

.

...

Rebuild

...

the

...

projects

...

again

...

using

...

the

...

mvn

...

clean

...

install

...

command

...

on

...

the

...

command-line

...

to

...

see

...

the

...

change.

...

Deploying the Component

Now that the SA is built, we're

...

ready

...

to

...

deploy

...

it

...

to

...

the

...

JBI

...

container.

...

This

...

is

...

a

...

work

...

in

...

progress.

...

I

...

will

...

finish

...

this

...

up

...

very soon.

...

Note
titleDeploying Component Dependencies

When working with the jbi:projectDeploy you may want to disable dependency deployment. When deploying to a server which has other components sharing these dependencies, they can cause problems during deployment. To stop the Maven JBI plugin from undeploying and redeploying dependencies each time, alter its configuration by disabling the deployment of dependencies using the following:

soon._ ---- {note:title=Deploying Component Dependencies} When working with the {{jbi:projectDeploy}} you may want to disable dependency deployment. When deploying to a server which has other components sharing these dependencies, they can cause problems during deployment. To stop the Maven JBI plugin from undeploying and redeploying dependencies each time, alter its configuration by disabling the deployment of dependencies using the following: {code}
Code Block

<build>
<plugins>
  <plugin>
    <artifactId>jbi-maven-plugin</artifactId>
    <configuration>
      <deployDependencies>false</deployDependencies>
    </configuration>
  </plugin>
</plugins>
</build>
{code}

The

configuration

above

introduces

the

{{

deployDependencies

}}

element

to

the

Maven

JBI

plugin

and

sets

it

to

false.

For

a

few

more

configurable

options

on

the

Maven

JBI

plugin,

see

also

[

Ability

to

configure

jbi:projectDeploy

goal

to

exclude

updating

dependencies.

Note
titleTODO

The default implementation of the component accepts InOut MEPs (ADD
LINK TO FURTHER READING CONCERNING MEPs) and return the input content
as the out message. This is already nearly what we want.

OUTLINE for further work:

  • Get Messages
  • read Messages
  • count the bytes
    Maybe easiest by XSLT endpoint (can be used to apply an XSLT stylesheet to the incoming exchange and will return the transformed result as the output message.)
    see [ servicemix-saxon|servicemix-saxon]
  • send a message back
  • Configure SA so that the example receives messages
    create & populate
|https://issues.apache.org/activemq/browse/SM-605]. {note} {note:title=TODO} The default implementation of the component accepts InOut MEPs (ADD LINK TO FURTHER READING CONCERNING MEPs) and return the input content as the out message. This is already nearly what we want. OUTLINE for further work: * Get Messages * read Messages * count the bytes Maybe easiest by XSLT endpoint (can be used to apply an XSLT stylesheet to the incoming exchange and will return the transformed result as the output message.) see \[ servicemix-saxon\|servicemix-saxon\] * send a message back * Configure SA so that the example receives messages create & populate
  • C:\hello-world-SE-SU-SA\hello-world-SU\src\main\resources\servicemix.xml
*
  • as
  • MyDeployer
  • extends
  • AbstractXBeanDeployer
  • create
  • xbean.xml
  • for
  • SU
*
  • make
  • something
  • send
  • messages
  • (eg
  • quartz
  • timer,
  • HTTP
  • POST,...)
  • and
  • dump
  • the
  • answer
  • (eg
  • TraceComponent,
  • FireWriter,
  • EIP,...)
*
  • add
  • a
  • chapter
  • what
  • user
  • may
  • do
  • now
  • /
  • "how
  • to
  • continue
  • when
  • having
  • the
  • working
  • example"

Classpath

for

SU to include manually till v3.1, see [mail|http://mail-archives.apache.org/mod_mbox/geronimo-servicemix-users/200610.mbox/%3cb23ecedc0610042315k30c03d67y240be0bb97358784@mail.gmail.com%3e] manually editing [

SU to include manually till v3.1, see mail

manually editing http://goopen.org/confluence/display/SM/Working+with+Service+Units

]


manually

editing

[

http://www.servicemix.org/site/working-with-service-assemblies.html

]


use

the

SU

archetype

like

in

[

http://www.servicemix.org/site/creating-a-protocol-bridge.html

]


use

the

SA

archetype

like

in

[

http://www.servicemix.org/site/creating-a-protocol-bridge.html

]

INS

When

to

use

this

JBI

Component


INS

Using

the

component

that

you

created

provide

exact

position

in

the

SVN

\

!


/samples/hello-world-SE-SU-SA/


integrate

from

SVN

source

like

it

is

done

at

Configuration

at

[

http://www.servicemix.org/site/visualisation.html

]

maybe

moving

the

content

of

overlapping

existing

docus

to

this

new

tut

and

-

where

appropriate

-

delete

the

old

ones

(only

leaving

a

redirect).

[


http://www.servicemix.org/site/notes-on-creating-jbi-component-using-maven2.html

]

version14

[


http://www.servicemix.org/site/creating-a-standard-jbi-component.html

]

version26


are

already

fully

incorporated

in

the

mentioned

versions,

so

delete

content

and

point

from

there

to

here

(and

delete

note

at

the

very

top)

This

shall

already

include

everything

stated

at

[


http://www.servicemix.org/site/maven-jbi-plugin.html#MavenJBIplugin-GettingStarted

]


and

[


http://www.servicemix.org/site/working-with-components.html

]

provide

additional

reading

[


Creating

a

protocol

bridge

]

.for

a

"bigger"

example


The

[

examples

]

page

lists

examples

providing

more

information,

showing

further

possibilities

and

components.

{note} h2. Additional Resources * [Creating a Standard JBI Component] * [Notes on Creating JBI Component using maven2] * [Roadmap for a perspective Servicemix developer]

Additional Resources