...
Note | ||
---|---|---|
| ||
This tutorial is a work in progress and the last parts is not yet complete. Please check back for updates. |
Tip | ||
---|---|---|
| ||
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 service 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:
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 service 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 -incubating or higherSee the ServiceMix downloads to grab a nightly build as ServiceMix 3.1 has not yet been released
- A broadband internet connection so Maven can automatically download dependencies
...
Panel |
---|
$ mvn archetype:create \ |
The command above 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.2.1-incubating) 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-se) 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. The very last parameter tells Maven to look at the Incubator repository at the ASF. Because Incubator policy disallows incubating projects to publish artifacts outside of the Incubator repository, the remoteRepositories
system property tells Maven to use the Incubator repository.
Tip |
---|
The value of the |
...
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 [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-se [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-se [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2 seconds [INFO] Finished at: Mon Jan 15 13:04:08 MST 2007 [INFO] Final Memory: 4M/8M [INFO] ------------------------------------------------------------------------ |
...
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
- Implementsjavax.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 theDefaultComponent
, 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 theDefaultComponent
to configure and initialize the component.
...
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:
Tip | ||
---|---|---|
| ||
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. |
Adding this method will require the import of the following classes:
org.apache
org.apache.servicemix.jbi.jaxp.SourceTransformer
org.apache.servicemix.jbi.jaxp.SourceTransformer
org.apache.servicemix.jbi.jaxp.StringSource
These classes can be found in the servicemix-core project.
...
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 ------------------------------------------------------- T E S T S ------------------------------------------------------- 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.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-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] 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] ------------------------------------------------------------------------ |
...
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.
...
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 .. |
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 | ||||
---|---|---|---|---|
| ||||
<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.
...
Create a file hello-world-su/src/main/resources/xbean.xml
with the following contents:
Code Block | ||||
---|---|---|---|---|
| ||||
<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> |
...
Code Block |
---|
$ mvn archetype:create \ -DarchetypeGroupId=org.apache.servicemix.tooling \ -DarchetypeArtifactId=servicemix-http-consumer-service-unit \ -DarchetypeVersion=3.2.1-incubating \ -DgroupId=org.apache.servicemix.samples.helloworld.se \ -DartifactId=hello-world-bchttp-su \ -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository |
There should now be a hello-world-bchttp-su directory under hello-world-smx.
Configure hello-world-
...
http-su
Create configuration for http binding component in hello-world-bchttp-su/src/main/resources/xbean.xml
Code Block | ||||
---|---|---|---|---|
| ||||
<?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"> <!-- Define an additional classpath location for wsdl resources --> <classpath> <location>.</location> </classpath> <http:endpoint <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
Code Blockpanel |
---|
$ mvn archetype:create \
\
\
\
\
|
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 | ||||
---|---|---|---|---|
| ||||
<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-bchttp-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. This is a work in progress
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-sesmx
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> <module>hello-world-bchttp-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-bchttp-su hello-world-sa hello-world-se hello-world-su pom.xml |
...
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:
...
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 it 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-incubating-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. I will finish this up very soon.
Step 10: Testing
- Save http://svn.apache.org/viewvc/incubator/servicemix/trunk/samples/bridge/client.html to your local desktop and then open it in your browser.
- Set
Target
tohttp://localhost:8192/Service/
- Click
Send
Note | ||
---|---|---|
| ||
When working with the
The configuration above introduces the For a few more configurable options on the Maven JBI plugin, see also Ability to configure jbi:projectDeploy goal to exclude updating dependencies. |
...
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
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-SA\hello-world\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-SA/
integrate from SVN source like it is done at Configuration at http://www.servicemix.org/site/visualisation.html
End-to-End Testing
This is a work in progress
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
...