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

...

Service Engine

Note
titleWork In Progress

This tutorial is a work in progress and the last parts is not yet complete.
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 service engine and this FAQ entry will explain this.

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

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

Panel

Wiki Markup

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

Prerequisites

  • Maven 2.0.4 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
  • See the ServiceMix downloads
  • A broadband internet connection so Maven can automatically download dependencies

...

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.

...

Now let's move on to creating the Maven projects for the Hello World componentservice engine.

Creating a Maven Project For the JBI

...

SE

The focus of this section is on the creation of a JBI componentservice engine. 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.

...

Code Block
$ mkdir hello-world-smx
$ cd hello-world-smx

2) Use either the servicemix-service-engine or the servicemix-binding-component Maven archetype to generate a Maven project for the component.

Note

Being that the difference between a BC and a SE is not denoted by the JBI APIs but rather the functionality of the component (see comments above on BCs vs SEs) it is up to you what type of component you create. This tutorial will show the commands for creating both a BC and a SE.

To create a SE, execute the following command on the command-line:

Panel

$ mvn archetype:create \
-DarchetypeGroupId=org.apache.servicemix.tooling \
-DarchetypeArtifactId=servicemix-service-engine \
-DarchetypeVersion=3.2.1 -incubating-SNAPSHOT \
-DgroupId=org.apache.servicemix.samples.helloworld.se \
-DartifactId=hello-world-su

To create a BC, execute the following command on the command-line:

...

se

The command above will create a directory named hello-world-se 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-service-engine

...

-DarchetypeVersion=3.

...

The command above will create a directory named hello-world-su 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-service-engine -DarchetypeVersion=3.1-incubating-SNAPSHOT2.1) identify which Maven archetype to use for the archetype:create goal, while the last two parameters (-DgroupId=org.apache.servicemix.samples.helloworld.se -DartifactId=hello-world-suse) 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-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 in the <version> element.

...

No Format
[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.se
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating Archetype: servicemix-service-engine:3.2.1-incubating-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.apache.servicemix.samples.helloworld.se
[INFO] Parameter: packageName, Value: org.apache.servicemix.samples.helloworld.se
[INFO] Parameter: basedir, Value: /Users/bsnyder/src/hello-world-smx
[INFO] Parameter: package, Value: org.apache.servicemix.samples.helloworld.se
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: hello-world-suse
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 63,column 16] : 
${servicemix-version} is not a valid reference.
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 68,column 16] : 
${servicemix-version} is not a valid reference.
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 83,column 18] : 
${servicemix-version} is not a valid reference.
[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 94,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-suse
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 32 seconds
[INFO] Finished at: FriMon Jan 0515 1713:2404:3908 MST 2007
[INFO] Final Memory: 5M4M/9M8M
[INFO] ------------------------------------------------------------------------

...

Note
titleIn 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 Block
titleUnix
~/.m2/repository/org/apache/maven/plugins/maven-archetype-plugin 
Code Block
titleWindows
C:\Documents and Settings\<USERNAME>\.m2\repository\org\apache\maven\plugins\maven-archetype-plugin

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-suse directory. Below is a simple POM to use for this purpose:

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-su<se</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>

...

Code Block
$ cd ./hello-world-suse
$ mvn install 

This command should produce the following output:

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.se.MyComponent
Checking: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] Generating META-INF properties file: 
/Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld.se/1.0 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating WIKI documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
Warning, could not load class: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
Compiling 3 source files to /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
Compiling 1 source file to /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.se.MySpringComponentTest
<hello>world</hello>
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 12.366843 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-suse/target/hello-world-suse-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/hello-world-suse-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/hello-world-suse-1.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/hello-world-suse-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-suse/1.0-SNAPSHOT/hello-world-suse-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-suse/1.0-SNAPSHOT/hello-world-suse-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-suse/1.0-SNAPSHOT/hello-world-suse-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/hello-world-suse-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-suse/1.0-SNAPSHOT/hello-world-suse-1.0-SNAPSHOT-installer.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1641 seconds
[INFO] Finished at: FriMon Jan 0515 2213:5206:4503 MST 2007
[INFO] Final Memory: 12M/33M26M
[INFO] ------------------------------------------------------------------------
[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.MyComponent
Checking: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] Generating META-INF properties file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld/1.0 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-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-su/target/xbean/hello-world-su.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
Warning, could not load class: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
Compiling 3 source files to /Users/bsnyder/src/hello-world-smx/hello-world-su/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
Compiling 1 source file to /Users/bsnyder/src/hello-world-smx/hello-world-su/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.MySpringComponentTest
<hello>world</hello>
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.366 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-su/target/hello-world-su-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16 seconds
[INFO] Finished at: Fri Jan 05 22:52:45 MST 2007
[INFO] Final Memory: 12M/33M
[INFO] ------------------------------------------------------------------------

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-service-engine 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.
  • 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.
  • MyComponent.java - Extends the DefaultComponent, a convenience class that makes creating JBI components much easier and provides some additional lifecycle management of components deployed to the JBI container. This class should be fleshed out by overriding methods in the DefaultComponent to configure and initialize the component.
  • MyEndpoint.java - Extends Endpoint and implements ExchangeProcessor. Endpoint provides a referencable resource for the component and the ExchangeProcessor provides the ability for the JBI container to process a message exchange with the component. The ExchangeProcessor.process() method is where we will add custom functionality to print out the Hello World message.
  • 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.

Adding Custom Functionality

When creating a JBI component, how a message exchange is handled depends on whether a component is a consumer or a provider. Because the Hello World component will not be consuming any other service (i.e., sending a message to another service), it is a provider (i.e., it will only be providing its service via a return message). As mentioned above, the ExchangeProcessor.process() method is of interest because it is where the message exchange is handled, so let's examine this method:

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-service-engine 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.
  • 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 not longer needed
  • MyComponent.java - Extends the DefaultComponent, a convenience class that makes creating JBI components much easier and provides some additional lifecycle management of components deployed to the JBI container. This class should be fleshed out by overriding methods in the DefaultComponent to configure and initialize the component.
  • MyEndpoint.java - Extends Endpoint and implements ExchangeProcessor. Endpoint provides a referencable resource for the component and the ExchangeProcessor provides the ability for the JBI container to process a message exchange with the component. The ExchangeProcessor.process() method is where we will add custom functionality to print out the Hello World message.
  • 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.

Adding Custom Functionality

Before we proceed to creating some custom functionality for the SE, you need to understand the role a JBI SE is meant to fulfill. A SE is an engine that provides a service that is local to the JBI normalized message router (NMR). It does not communicate directly with anything external to the NMR. If communication needs to occur with a service that is external to the NMR, this should take place using a JBI binding component (see the Hello World BC for a tutorial on creating a JBI binding component). The SE is deployed to the JBI container and provides a service directly to the NMR by communicating with the NMR using Normalized Messages.

For example, consider a BPEL engine like Apache Ode. It's job is to handle the execution of BPEL processes. Ode can be deployed to the JBI container as a JBI SE through the use of the servicemix-bpe SE. In this capacity, Ode communicates via JBI normalized messages. Ode handles all of the processing of a given BPEL flow via it's engine and to communicate outside the engine, it speaks normalized messages. It's the responsibility of the Ode SE to handle the execution of processes defined using BPEL and in its capacity as a JBI SE it only communicates outwardly via normalized messages.

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 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.

When creating a JBI component, how a message exchange is handled depends on whether a component is a consumer or a provider. Because the Hello World SE will not be consuming any other service (i.e., sending a message to another service), it is a provider (i.e., it will only be providing its service via a return message). As mentioned above, the ExchangeProcessor.process() method is of interest because it is where the message exchange is handled, so let's examine this method:

Code Block

public void process(MessageExchange exchange) throws Exception {
        // The component acts as a provider, this means that another component has requested our service
        // As this exchange is active, this is either an in or a fault (out are send by this component)
        if (exchange.getRole() == MessageExchange.Role.PROVIDER) {
            // Check here if the mep is supported by this component
            if (exchange instanceof InOut == false) {
               throw new UnsupportedOperationException("Unsupported MEP: " + exchange.getPattern());
            }
            // NOTE: Added check for DONE/ERROR status -- Jeff Peterson
            // TODO: FIX in archetype
            // 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 {
                // In message
                if (exchange.getMessage("in") != null) {
                    NormalizedMessage in = exchange.getMessage("in");
                    // TODO ... handle the in message
                    // If the MEP is an InOnly, RobustInOnly, you have to set the exchange to DONE status
                    // else, you have to create an Out message and populate it
                    // For now, just echo back
                    NormalizedMessage out = exchange.createMessage();
                    out.setContent(in.getContent());
                    exchange.setMessage(out, "out");
                    channel.send(exchange);
                // Fault message
                } else if (exchange.getFault() != null) {
                    // TODO ... handle the fault
                    exchange.setStatus(ExchangeStatus.DONE);
                    channel.send(exchange);
                // This is not compliant with the default MEPs
                } else {
                    throw new IllegalStateException("Provider exchange is ACTIVE, but no in or fault is provided");
                }
            }
        // 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
Code Block

public void process(MessageExchange exchange) throws Exception {
        // The component acts as a provider, this means that another component has requested our service
        // AsIf this exchangecomponent isdoes active,not thiscreate is/ eithersend anexchanges, inyou ormay ajust faultthrow (outan areUnsupportedOperationException
 send by this component)
    }   else if (exchange.getRole() == MessageExchange.Role.PROVIDERCONSUMER) {
            // Check here if the mep is supported by this componentExchange is finished
            if (exchange instanceof InOut .getStatus() == falseExchangeStatus.DONE) {
               throw new UnsupportedOperationException("Unsupported MEP: " + exchange.getPattern()) return;
            }
// Exchange has been aborted with an exception
     // In message
     }      else if (exchange.getMessagegetStatus("in") !== nullExchangeStatus.ERROR) {
                NormalizedMessage in = exchange.getMessage("in")return;
                // TODOExchange ... handle the in messageis active
            } else {
  // If the MEP is an InOnly, RobustInOnly, you have to set the exchange to// DONEOut statusmessage
                // else, you have to create an Out message and populate it
 if (exchange.getMessage("out") != null) {
                    // For now, just echo backTODO ... handle the response
                NormalizedMessage  out = exchange.createMessagesetStatus(ExchangeStatus.DONE);
                out.setContent(in.getContent())    channel.send(exchange);
                exchange.setMessage(out, "out");
                channel.send(exchange);
       // Fault message
     // Fault message
            } else if (exchange.getFault() != null) {
                    // TODO ... handle the fault
                    exchange.setStatus(ExchangeStatus.DONE);
                    channel.send(exchange);
                // This is not compliant with the default MEPs
                } else {
                    throw new IllegalStateException("ProviderConsumer exchange is ACTIVE, but no inout or fault is provided");
            }
    }
    // The component acts as a consumer, this means this exchange is received because }
        // weUnknown sentrole
 it to another component.  As it is} active,else this{
 is either an out or a fault
     throw new  // If this component does not create / send exchanges, you may just throw an UnsupportedOperationException
        } else if (IllegalStateException("Unkown role: " + 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);
                    channel.send(exchange);
                // Fault message
                } else if (exchange.getFault() != null) {
                    // TODO ... handle the fault
                    exchange.setStatus(ExchangeStatus.DONE);
                    channel.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());
        }
    }

The implementation of the method above was provided by the servicemix-service-engine Maven archetype. Because the archetype can be used to create either a consumer or a provider service engine, this method is very generic and contains a conditional block for handling either a consumer or a provider role. But this method will still require us to make the decision of which style of Message Exchange Pattern (MEP) to handle. In the case of the Hello World component, we know that it is a provider so it will need to send a return message. Therefore it will need to handle an In-Out MEP. So instead of having MyEndpoint extend the very basic Endpoint class and implement its own process() method, we're going to extend a different class that is specifically for provider endpoints named
ProviderEndpoint.

Image Removed

Notice the diagram above showing the class hierarchy of Endpoint. The ProviderEndpoint supplies some additional conveniences for provider components beyond what the Endpoint class provides and will make the job of implementing MyEndpoint as a provider much easier. So let's make some changes to the MyEndpoint class. First remove the process() method shown above. Second, change the definition of the MyEndpoint class from this:

Code Block

public class MyEndpoint extends Endpoint implements ExchangeProcessor

to this:

Code Block

public class MyEndpoint extends ProviderEndpoint implements ExchangeProcessor

By the way, making this change will require the import of the full class (org.apache.servicemix.common.endpoints.ProviderEndpoint).

Third, because the ProviderEndpoint.process() method already handles an In-Out MEP, MyEndpoint will simply need to override the ProviderEndpoint.processInOut() method. Below is the content for implementing this method. Copy/paste this method:

Code Block

protected void processInOut(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws Exception {
	SourceTransformer sourceTransformer = new SourceTransformer();
	String inMessage = sourceTransformer.toString(in.getContent()); 
	out.setContent(new StringSource("<hello>Hello World! Message [" + inMessage + "] contains [" + inMessage.getBytes().length + "] bytes</hello>."));
}

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

  • org.apache.servicemix.jbi.jaxp.SourceTransformer
  • org.apache.servicemix.jbi.jaxp.StringSource

This method is the logic for the Hello World component. We're not doing anything complex here at all in order to keep this tutorial very simple. Now it's time to test the component.

Testing the Hello World 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.se.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>"));

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

Code Block

$ mvn install 

Below is the output that will print to the console:

}

The implementation of the method above was provided by the servicemix-service-engine Maven archetype. This method is very generic and contains a conditional block for handling either a consumer or a provider role. But this method will still require us to make the decision of which style of Message Exchange Pattern (MEP) to handle. In the case of the Hello World SE, we know that it is a provider so it will need to send a return message. Therefore it will need to handle an In-Out MEP. So instead of having MyEndpoint extend the very basic Endpoint class and implement its own process() method, we're going to extend a different class that is specifically for provider endpoints named
ProviderEndpoint.

Image Added

Notice the diagram above showing the class hierarchy of Endpoint. The ProviderEndpoint supplies some additional conveniences for provider components beyond what the Endpoint class provides and will make the job of implementing MyEndpoint as a provider much easier. So let's make some changes to the MyEndpoint class. First remove the process() method shown above. Second, change the definition of the MyEndpoint class from this:

Code Block

public class MyEndpoint extends Endpoint implements ExchangeProcessor

to this:

Code Block

public class MyEndpoint extends ProviderEndpoint implements ExchangeProcessor

By the way, making this change will require the import of the full class (org.apache.servicemix.common.endpoints.ProviderEndpoint). This class can be found in the servicemix-common project.

Third, because the ProviderEndpoint.process() method already handles an In-Out MEP (and other MEPs), MyEndpoint will simply need to override the ProviderEndpoint.processInOut() method. Below is the content for implementing this method. Copy/paste this method:

Code Block

protected void processInOut(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws Exception {
	SourceTransformer sourceTransformer = new SourceTransformer();
	String inMessage = sourceTransformer.toString(in.getContent()); 
	out.setContent(new StringSource("<hello>Hello World! Message [" + inMessage + "] contains [" + inMessage.getBytes().length + "] bytes</hello>."));
}
Tip
titleChanges to example code

NOTE: You may have problems running above code. In this case remove <? ... ?> string from inMessage. ServiceMix validates XML on every step. So simple concatenating of two xml message will not work.
Also use logger to view actual message you send to StringSource, you may find invalid xml.

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

  • org.apache.servicemix.jbi.jaxp.SourceTransformer
  • org.apache.servicemix.jbi.jaxp.StringSource

These classes can be found in the servicemix-core project.

This method is the custom functionality for the Hello World SE. We're not doing anything complex here at all in order to keep this tutorial very simple. Apache Ode was mentioned earlier as an example of an engine that can be deployed as a JBI SE, this class is where Ode would be referenced and called. If you're interested to see how Ode is called, see the BPEEndpoint class for the details. Now it's time to test the Hello World SE.

Testing the Hello World 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.se.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>"));

To execute the test, simply run the Maven install goal from within the hello-world-se 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.se.MyComponent
Checking: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] Generating META-INF properties file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld.se/1.0 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating WIKI documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
Warning, could not load class: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[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-se/target/surefire-reports

No Format

[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [install]
[INFO] --------------------------------------------------------------------
 T E S T S
-----------------------------
[INFO] [xbean:mapping {execution: default}]
Checking: --------------------------
Running org.apache.servicemix.samples.helloworld.MyComponent
Checking: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] Generating META-INF properties file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld/1.0 for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating Spring 2.0 handler mappingse.MySpringComponentTest
<hello>Hello World! Message [<hello>Ski Colorado!</hello>] contains [28] bytes</hello>.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.487 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-suse/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0hello-world-se-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFO] Generating Spring 2.0 schema mapping: installer /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0hello-world-se-1.0-SNAPSHOT-installer.zip
[INFO] Generating HTML documentation fileBuilding jar: /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-se-su.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld/1.01.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Generating XSD file: /Users/Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-su.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0se-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT.jar
[INFO] Generating WIKI documentation file: Installing /Users/bsnyder/src/hello-world-smx/hello-world-suse/target/xbean/hello-world-suse.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
Warning, could not load class: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[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-su/target/surefire-reports

 to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/hello-world-se-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT-installer.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16 seconds
[INFO] Finished at: Mon Jan 15 13:19:51 MST 2007
[INFO] Final Memory: 13M/24M
[INFO] -------------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.MySpringComponentTest
<hello>Hello World! Message [<hello>Ski 

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.

Deploying the Component

Now it's time to deploy this component to the JBI container. Because the component was just built above, you should now see a filed named hello-world-se-1.0-SNAPSHOT-installer.zip in the target directory of the project. This is the component all packaged up and ready to be deployed. To deploy the component, simply copy the ZIP file to the ServiceMix install directory. You can do this before starting ServiceMix or while ServiceMix is running.

As long as the component deploys properly, you're now ready to create a deploy a configuration for the component.

Deploying a Service Unit That Depends Upon the Component

In order to actually make use of the component, you will need to deploy a configuration for the component. Once JBI components are deployed to the JBI container, they're just hanging out there waiting for a configuration to be deployed to them. This is why JBI is often referred to as a container of containers. The JBI container accepts deployment of JBI components and JBI components accept deployment of service units (SUs) that configure them. This is very similar to the way RAR files work in JavaEE-land. RAR files are generic components that are deployed to the JavaEE container that accept the deployment of a configuration file to tell it how to run. This is exactly how JBI components work. To achieve this, you need to create a JBI SU that depends on the JBI component in it's pom.xml file and to deploy the SU to the JBI container as well.

In the case of the Hello World SE, we're lucky that there are no configuration options really, so all we need to do is create SU that depends on the Hello World SE and deploy that. To do this, use the command below:

Panel

$ cd ..
$ mvn archetype:create \
-DarchetypeGroupId=org.apache.servicemix.tooling \
-DarchetypeArtifactId=servicemix-service-unit \
-DarchetypeVersion=3.2.1 \
-DgroupId=org.apache.servicemix.samples.helloworld.se \
-DartifactId=hello-world-su

This creates a directory named hello-world-su. Now edit the hello-world-su/pom.xml file to add the following dependency on the Hello World SE:

Code Block
xml
xml

<dependency>
  <groupId>org.apache.servicemix.samples.helloworld.se</groupId>
  <artifactId>hello-world-se</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

This tells Maven that the hello-world-su project depends upon the hello-world-se project. After compiling the hello-world-su, copy the JAR file to the ServiceMix deploy directory. As long as it starts up without error, you're ready to begin sending messages to it.

Configure hello-world-su

Create a file hello-world-su/src/main/resources/xbean.xml with the following contents:

Code Block
xml
xml

<beans xmlns:hwse="http://org.apache.servicemix.samples.helloworld.se/1.0" 
       xmlns:xyz="http://companyxyz.com">
  <hwse:endpoint service="xyz:helloWorld" endpoint="helloWorld"/>
</beans>
Info

TODO: explain

Create a Service Unit for HTTP Binding Component

This service unit will configure the servicemix-http binding component so we can issue some soap-over-http requests for testing purposes.

Code Block

$ mvn archetype:create \
-DarchetypeGroupId=org.apache.servicemix.tooling \
-DarchetypeArtifactId=servicemix-http-consumer-service-unit \
-DarchetypeVersion=3.2.1 \
-DgroupId=org.apache.servicemix.samples.helloworld.se \
-DartifactId=hello-world-http-su

There should now be a hello-world-http-su directory under hello-world-smx.

Configure hello-world-http-su

Create configuration for http binding component in hello-world-http-su/src/main/resources/xbean.xml

Code Block
xml
xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:http="http://servicemix.apache.org/http/1.0"
       xmlns:hwse="http://org.apache.servicemix.samples.helloworld.se/1.0"
       xmlns:xyz="http://companyxyz.com">

    <http:endpoint service="xyz:helloWorld"
                   endpoint="helloWorld"
                   role="consumer" 
                   locationURI="http://localhost:8192/Service/"
                   defaultMep="http://www.w3.org/2004/08/wsdl/in-out" />	   
</beans>
Info

TODO: explain

Create a service assembly to wrap all of the SUs

Panel

$ mvn archetype:create \

Wiki Markup
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. 

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
$ pwd /Users/bsnyder/src/hello-world-smx/hello-world-su $ cd .. $ mvn archetype:create \

-DarchetypeGroupId=org.apache.servicemix.tooling

\


-DarchetypeArtifactId=servicemix-service-assembly

\


-DarchetypeVersion=3.2.1

-incubating-SNAPSHOT \ -DgroupId=org

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

\

.se \
-DartifactId=hello-world-sa

There should now be a hello-world-sa

...

directory under hello-world-smx.

Add the following dependencies to hello-world-sa/pom.xml

Code Block
xml
xml

<dependency>
  <groupId>org.apache.servicemix.samples.helloworld.se</groupId>
  <artifactId>hello-world-su</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
  <groupId>org.apache.servicemix.samples.helloworld.se</groupId>
  <artifactId>hello-world-http-su</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

Build and Deploy the SA

The easiest way to build all the projects is to create a top level POM file that will tell Maven to build everything for you. The following section describes how to do this.

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
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-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-su</module>
    <module>hello-world-http-su</module>
    <module>hello-world-se</module>
  </modules>
</project>

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

$ ls 
hello-world-http-su  hello-world-sa  hello-world-se  hello-world-su  pom.xml

All projects can now be built using the following command on the command-line from the top level hello-world-smx directory:

Code Block

$ mvn clean install 

The command above should display the output below:

No Format

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   A custom project
[INFO]   A custom project
[INFO]   Hello World JBI Component
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-se/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-se/target/classes
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-se/target/test-classes
[INFO] [xbean:mapping {execution: default}]
Checking: org.apache.servicemix.samples.helloworld.se.MyComponent
Checking: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] Generating META-INF properties file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld.se/1.0 for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd 
for namespace: http://org.apache.servicemix.samples.helloworld.se/1.0
[INFO] Generating WIKI documentation file

Upon successful execution of the archetype:create goals, look for the BUILD SUCCESSFUL output as displayed below:

No Format

[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.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: /hello-world-se/target/xbean/hello-world-se.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld
[INFO] Parameter: version, Value: .se/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:
Warning, could not load class: org.apache.servicemix.samples.helloworld.se.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
Compiling 3 source files to /Users/bsnyder/src/hello-world-smx/hello-world-sase/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
Compiling 1 source file to /Users/bsnyder/src/hello-world-smx/hello-world-se/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-------se/target/surefire-reports

---------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] 
 T E S T S
------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Fri Jan 05 23:40:32 MST 2007
[INFO] Final Memory: 4M/8M
[INFO] ------------------------------------------------------------------------

The hello-world-smx directory should now contain the following two directories:

Code Block

$ ls 
hello-world-sa hello-world-su

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-su as listed below:

Code Block

<dependency>
  <groupId>org.apache.servicemix.samples.helloworld</groupId>
  <artifactId>hello-world-su</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

Upon adding this dependency to the POM, build the project using the command below:

Code Block

$ cd hello-world-sa
$ mvn install 
No Format

[INFO] Scanning for projects...
Running org.apache.servicemix.samples.helloworld.se.MySpringComponentTest
<hello>Hello World! Message [<hello>Ski Colorado!</hello>] contains [28] bytes</hello>.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.464 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-se/target/hello-world-se-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-se/target/hello-world-se-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-se/target/hello-world-se-1.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/hello-world-se-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/xbean/hello-world-se.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-se/target/hello-world-se-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/se/hello-world-se/1.0-SNAPSHOT/hello-world-se-1.0-SNAPSHOT-installer.zip
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
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://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] [clean:clean]
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/classes
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/test-classes
[INFO] [jbi:generate-jbi-service-assembly-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] No sources to compile
[INFO] [surefire:test]
[INFO] No tests to run.
[INFO] [jbi:jbi-service-assembly]
[INFO] [jar:jar]
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/hello-world-sa-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/hello-world-sa-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-sa/1.0-SNAPSHOT/hello-world-sa-1.0-SNAPSHOT.zip
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] Building Hello World JBI Component
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 10 seconds[clean:clean]
[INFO] FinishedDeleting at: Fri Jan 05 23:53:19 MST 2007directory /Users/bsnyder/src/hello-world-smx/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/target/classes
[INFO] FinalDeleting Memory: 12M/22Mdirectory /Users/bsnyder/src/hello-world-smx/target/test-classes
[INFO] ------------------[site:attach-descriptor]
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/pom.xml to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-smx/1.0-SNAPSHOT/hello-world-smx-1.0-SNAPSHOT.pom
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------

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. In the hello-world-se 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-su</module>
  </modules>

</project>

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 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

$ ls 
hello-world-sa hello-world-su pom.xml

All projects can now be built using the following command on the command-line:

Code Block

$ mvn clean install 

The command above should display the output below:

No Format

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   A custom project
[INFO]   A custom project
[INFO]   Hello World JBI Component
[INFO] ------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] A custom project ...................................... SUCCESS [17.091s]
[INFO] A custom project ...................................... SUCCESS [2.465s]
[INFO] Hello World JBI Component ............................. SUCCESS [1.552s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------
[INFO] Building A custom project
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-su/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-su/target/classes
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-su/target/test-classes
[INFO] [xbean:mapping {execution: default}]
Checking: org.apache.servicemix.samples.helloworld.MyComponent
Checking: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] Generating META-INF properties file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/services/org/apache/xbean/spring/http/
org.apache.servicemix.samples.helloworld/1.0 for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating Spring 2.0 handler mapping: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/spring.handlers 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating Spring 2.0 schema mapping: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/META-INF/spring.schemas 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating HTML documentation file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd.html 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
[INFO] Generating XSD file: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-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-su/target/xbean/hello-world-su.xsd.wiki 
for namespace: http://org.apache.servicemix.samples.helloworld/1.0
Warning, could not load class: org.apache.servicemix.samples.helloworld.MyEndpoint
[INFO] ...done.
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://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] [jbi:generate-jbi-component-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
Compiling 3 source files to /Users/bsnyder/src/hello-world-smx/hello-world-su/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
Compiling 1 source file to /Users/bsnyder/src/hello-world-smx/hello-world-su/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.apache.servicemix.samples.helloworld.MySpringComponentTest
<hello>Hello World! Message [<hello>Ski Colorado!</hello>] contains [28] bytes</hello>.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 9.47 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-su/target/hello-world-su-1.0-SNAPSHOT.jar
[INFO] [jbi:jbi-component]
[INFO] Generating installer /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT.jar
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT.xsd
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/xbean/hello-world-su.xsd.html to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT-schema.html
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-su/target/hello-world-su-1.0-SNAPSHOT-installer.zip to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-su/1.0-SNAPSHOT/hello-world-su-1.0-SNAPSHOT-installer.zip
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/classes
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/test-classes
[WARNING] 
        Artifact junit:junit:jar:3.8.1:test retains local scope 'test' overriding broader scope 'compile'
        given by a dependency. If this is not intended, modify or remove the local scope.

[INFO] [jbi:generate-jbi-service-assembly-descriptor]
[INFO] Generating jbi.xml
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] No sources to compile
[INFO] [surefire:test]
[INFO] No tests to run.
[INFO] [jbi:jbi-service-assembly]
[INFO] [jar:jar]
[INFO] Building jar: /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/hello-world-sa-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/hello-world-sa/target/hello-world-sa-1.0-SNAPSHOT.jar to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-sa/1.0-SNAPSHOT/hello-world-sa-1.0-SNAPSHOT.zip
[INFO] ----------------------------------------------------------------------------
[INFO] Building Hello World JBI Component
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/target
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/target/classes
[INFO] Deleting directory /Users/bsnyder/src/hello-world-smx/target/test-classes
[INFO] [site:attach-descriptor]
[INFO] [install:install]
[INFO] Installing /Users/bsnyder/src/hello-world-smx/pom.xml to 
/Users/bsnyder/.m2/repository/org/apache/servicemix/samples/helloworld/hello-world-smx/1.0-SNAPSHOT/hello-world-smx-1.0-SNAPSHOT.pom
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] A custom project ...................................... SUCCESS [30.738s]
[INFO] A custom project ...................................... SUCCESS [3.080s]
[INFO] Hello World JBI Component ............................. SUCCESS [1.547s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 36 seconds
[INFO] Finished at: Sat Jan 06 16:59:57 MST 2007
[INFO] Final Memory: 15M/28M
[INFO] ------------------------------------------------------------------------

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-su/pom.xml and replace <name>A custom project</name> with <name>Hello World 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 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:

Code Block

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

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.

...

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
  • Wiki Markup
    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

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

----------------
[INFO] Total time: 22 seconds
[INFO] Finished at: Mon Jan 15 13:30:59 MST 2007
[INFO] Final Memory: 14M/28M
[INFO] ------------------------------------------------------------------------

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-se/pom.xml and replace <name>A custom project</name> with <name>Hello World SE 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 and the SU

Now that the SA is built, we're ready to deploy the Hello World SE, the dependency components and the Hello World SA to the JBI container.

Code Block

$ cp hello-world-se/target/hello-world-se-1.0-SNAPSHOT-installer.zip $SERVICEMIX_HOME/install/
$ cp $SERVICEMIX_HOME/components/servicemix-shared-3.2.1-installer.zip $SERVICEMIX_HOME/install/
$ cp $SERVICEMIX_HOME/components/servicemix-http-3.2.1-installer.zip $SERVICEMIX_HOME/install/
$ cp hello-world-sa/target/hello-world-sa-1.0-SNAPSHOT.jar $SERVICEMIX_HOME/deploy/

This is a work in progress

End-to-End Testing

This is a work in progress

...

Additional Resources