You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

Tutorial: Creation of a "Hello World - SE"

This tutorial describes how to create a very simple "Hello world" JBI service engine (SE) component, pack it into a Service Unit (SU) which will be packed to a Service Assambly (SA), and finally how to run the SE inside ServiceMix. The SE will answer received messages with "Hello, I received xyz bytes!", so we literally see that it works. As it has the same structure as real, useful SE, the given hints help to use the presented code as a blueprint to create own SE-SA-SUs. Still, the example is as minimalistic as possible, so readers shall not get lost in too many details but get an idea of the big picture.

This tutorial shows the desired/best practices or "clean" way to create a SE-SA-SU using ServiceMix Maven archetypes and the Maven plugin (see Maven JBI plugin), so how the workflow shall be - of course, other possibilities exist and may be better suited for certain situations. Furthermore, it will explain the reasons for critical choices and how required information can be retrieved. Where appropriate, additional reading is suggested.

To make it as easy as possible to follow the descriptions, they contain only the relevant code snippets, while the full code is available in the SVN repository. Please note that the code snippets are fetched directly from the full code in the SVN repository, thus the wiki and the code share always at the same, up to date state.

Handy Hints

This tutorial is especially useful for ServiceMix beginners.

The Maven Getting Started Guide is a recommended and short reading. It explains most of the Maven related things needed.

TODO

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
http://www.servicemix.org/site/creating-a-standard-jbi-component.html
are already fully incorporated, so delete content and point from there to here

This shall already include everything stated at
http://www.servicemix.org/site/maven-jbi-plugin.html#MavenJBIplugin-GettingStarted
and
http://www.servicemix.org/site/working-with-components.html

provide additional reading
Creating a protocol bridge.for a "bigger" example

Prerequisites

The following is required:

  • Around 15 minutes of time
  • A running copy of ServiceMix 3.0 and Maven 2.0.4 or higher
  • A connection to the Internet to download dependencies
  • A text editor to alter XML files
  • An editor or IDE for Java files

Overview SE-SU-SA

JBI components are can be tought of as the "smallest applications" you can access in an ESB. They have a very specific purpose, thus a narrow scope and set of functionallity. Components come in two flavours: Service Engine (SE) and Binding Components (BC).

Components are enriched by metadata (which?) and the whole is packed into a Service Unit (SU) - basically a JAR archive.

Several SUs are packed into a Service Assambly (SA). An SA is a complete "application" consisting of multiple components (reminder: the "smallest appliactions") interacting with each other and making up the big "application".

Further reading: JSR 208

Creating the main POM and the stubs of the SE, SU, SA

Creating the stub of the SE

First, a JBI component has to be created. Here, we use archetypes, just like shown at Creating a Standard JBI Component and Notes on Creating JBI Component using maven2 and Creating a protocol bridge. The Maven 2 archetypes are a kind of pattern, generic model, blueprint or template, or as Merriam-Webster defines "the original pattern or model of which all things of the same type are representations or copies". Using archetypes, Maven creates the basis for components, settings and so on, thus archetypes spare developers repetetive work and avoid errors like typos etc.

Note: As this text describes how to create a "Hello World" Service Engine and pack it into an SU and SA, the project name is hello-world-SE-SU-SA and the single pieces are named analogous. For a custom project, the IDs and names shall be altered such that they describe the purpose or function of the given piece of the SA.

First, we create a directory hello-world-SE-SU-SA and open a command line in this folder. Now we execute the following command (it has to be one line but was split to be readable):

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-service-engine
-DarchetypeVersion=3.0-incubating -DgroupId=org.apache.servicemix.samples.helloWorldSE -DartifactId=hello-world-SE

The first three parameters identify the maven 2 archetype to use, while the last two parameters define the generated maven 2 project. The version information "3.0-incubating" may have to be changed; a look at any of ServiceMix' pom.xml reveals the version to use. Maven uses the group ID (printed in pink) as default Java package (see output below as well), thus invalid characters like minus, percent etc. must be avoided or a custom package name has to be given as parameter. Mavens output following the command looks like this (only relevant information preserved):

[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] <span style="color: #ff00ff">Defaulting package to group ID: org.apache.servicemix.samples.helloWorldSE</span>
...
[INFO] *********** End of debug info from resources from generated POM *********************
[INFO] <span style="color: #009900">Archetype created in dir: C:\hello-world-SE-SU-SA\hello-world-SE</span>
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

Maven creates a new folder having the same name as the artifact ID provided (printed in green in the command and output). Inside this folder, a file called pom.xml is created. This contains the Project Object Model providing Maven with all needed information for building (see Introduction to the POM at the Maven website). Moreover, Java source files and tests were created.

Creating the stub of the SU and SA 

The archetypes for SUs and SAs do not contain much code, but rather help with tasks related to Maven. Later, we will only need to adapt the POMs to our project - just little work.

In the directory hello-world-SE-SU-SA we execute the following commands (they have to be one line but were split to be readable) for the SU

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-service-unit
-DarchetypeVersion=3.0-incubating -DgroupId=org.apache.servicemix.samples.helloWorldSE -DartifactId=hello-world-SU

and the SU

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-service-assembly
-DarchetypeVersion=3.0-incubating -DgroupId=org.apache.servicemix.samples.helloWorldSE -DartifactId=hello-world-SA

By now, the full structure of files is created by Maven and looks like this:

C:\hello-world-SE-SU-SA\hello-world-SA
C:\hello-world-SE-SU-SA\hello-world-SA\pom.xml


C:\hello-world-SE-SU-SA\hello-world-SE
C:\hello-world-SE-SU-SA\hello-world-SE\pom.xml

C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MyBootstrap.java
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MyComponent.java
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MyDeployer.java
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MyEndpoint.java
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MyLifeCycle.java
C:\hello-world-SE-SU-SA\hello-world-SE\src\main\java\org\apache\servicemix\samples\helloWorldSE\MySpringComponent.java

C:\hello-world-SE-SU-SA\hello-world-SE\src\test\java\org\apache\servicemix\samples\helloWorldSE
C:\hello-world-SE-SU-SA\hello-world-SE\src\test\java\org\apache\servicemix\samples\helloWorldSE\MySpringComponentTest.java

C:\hello-world-SE-SU-SA\hello-world-SE\src\test\resources
C:\hello-world-SE-SU-SA\hello-world-SE\src\test\resources\spring.xml


C:\hello-world-SE-SU-SA\hello-world-SU
C:\hello-world-SE-SU-SA\hello-world-SU\pom.xml
C:\hello-world-SE-SU-SA\hello-world-SU\src\main\resources

According to the template rules, all the classes have the word "My" prefixed to them. We can rename the prefix to whatever we want to, as long as we make sure we change the corresponding resource files (all tests and the pom.xml) as well.

Incorporating the SU and SA into the main POM

Now that we have created the SU and SA structure, we incorporate them into the main POM. We create a file called pom.xml in the hello-world-SE-SU-SA directory and instert the following content:

<project>
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.apache.servicemix.samples</groupId>
	<artifactId>helloWorldSE</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>pom</packaging>
	<modules>
		<module>hello-world-SA</module>
		<module>hello-world-SU</module>
	</modules>
	<dependencies>
		<dependency>
			<groupId>org.apache.servicemix.samples.helloWorldSE</groupId>
			<artifactId>hello-world-SU</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

The <modules> entity defines which child projects belong to the main project. The <dependencies> entity causes Maven to include the SU into the SA.

Note: The content of <version> describes not the version of ServiceMix but of the project we create, thus we may choose any desired version (e.g. 3.0-final). We just have to use consitently the same version when we reference this project.

Maven commands 

By now, it is already possible to call Maven with the relevant goals.

Compiling the SE's code

We can build the code by executing

mvn compile

in the hello-world-SE-SU-SA/hello-world-SE directory and Maven shall present as one of the last lines of output

[INFO] BUILD SUCCESSFUL

In case this success information is not appearing, the output shall give information on the reasons. Further information can be found in the ServiceMix mailing lists archive and the Maven website.

Testing the SE's code

Doing automated testing of the code is possible as well. As ServiceMix' root POM disables testing, we have to be activate it for the subprojects that shall be tested. To do so, the <build> entity of our hello-world-SE-SU-SA/hello-world-SE/pom.xml has to be enriched by

<pluginManagement>
     <plugins>
          <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
                    <skip>false</skip><!-- this overrides ServiceMix' root POM and forces to execute the tests -->
               </configuration>
          </plugin>
     </plugins>
</pluginManagement>

where <skip>false</skip> is the relevant line of code. Now, when executing

mvn test

tests will be done and Maven outputs the following (truncated to the relevant information):

[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building A custom project
[INFO]    task-segment: [test]
[INFO] ----------------------------------------------------------------------------
...
[INFO] [compiler:compile]
...
[INFO] [surefire:test]
[INFO] Setting reports dir: c:\java\tmp\servicemix-helloWorldSE\target/surefire-reports
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
[surefire] Running org.apache.servicemix.samples.helloWorldSE.MySpringComponentTest
...
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 1,422 sec
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
...

TODO

Maybe add further testingat the end of the tutarial (as "how to continue when having the working example")

Generation and deployment of the SA

By running

mvn install

from the hello-world-SE-SU-SA directory, the SA is generated in the hello-world-SE-SU-SA/hello-world-SA/target/ directory. Of course, our code does not yet do anything, but we can already deploy the SA and needed components to a running ServiceMix container by switching to the hello-world-SE-SU-SA/hello-world-SA/ directory and calling

mvn jbi:projectDeploy

Essentially, the plugin will walk the dependencies starting in the current project, then deploy each of the dependencies in reverse order. So it copies contents of the hello-world-SA-1.0-SNAPSHOT.zip and orther sources to ServiceMix subdirectories. For further information see Maven JBI plugin. When the deployment is complete, ServiceMix will output this confirmation:

INFO  - ServiceAssemblyLifeCycle       - Starting service assembly: hello-world-SA

Note: The command mvn install executed in the hello-world-SE directory creates a JAR and also a component installer. For installation, mvn jbi:installComponent has to be executed.

Deploying Dependencies

When working with the jbi:projectDeploy one may want to disable dependency deployment. When deploying to a server which has other components sharing these dependencies, they can cause problems while trying to undeploy and redeploy them. To stop the jbi-maven-plugin undeploying and redeploying dependencies, the configuration files (usually in the SA's or the component's pom.xml) have to be extended by a new entity called deployDependencies with a value of false. This has to be placed in the configuration section for the jbi-maven-plugin. The final structure looks like this (reduced to the bare minimum, the inserted entity is bold):

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

Adding functionality

The structure is done, so the functionality have to be added. Using an IDE like IDEA or
Eclipse this is easier; here, the workflow with Eclipse is described. 

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:
Get Messages
read Messagescount the bytessend a message backConfigure SA so that the example receives messages
make something send messages (eg quartz timer, HTTP POST,...) and dump the answer (eg TraceComponent, FireWriter, EIP,...)
 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 

  • No labels