Forum Home » Fuse Distributions » Fuse ESB

Thread: Deployment Best Practices

 
This question is answered. Helpful answers available: 1. Correct answers available: 1.


Permlink Replies: 5 - Last Post: Jul 13, 2010 10:13 PM Last Post By: blackdogtags
shanaghe

Posts: 14
Registered: 09/21/09
Deployment Best Practices
Posted: Nov 12, 2009 5:38 PM
 
  Click to reply to this thread Reply
I have a set of bundles which I deploy as part of my ESB application. I have added a features XML to the build process which refers to all required bundles; those built by me as well as third party dependencies. It deploys fine in fuse with the features/addUrl, features/install commands.

I'm now facing the problem of packaging and deploying all this in a production system. Before installing my features, I also have to osgi/uninstall some camel bundles which I'm upgrading as part of my features install.

Is there a best practice for packaging this kind of deployment?
Can I package in a way that will update my system directory to the state required for a working production system? I'm worried that there will be too many manual steps for production install requiring starting and stopping of the ESB.

Any advice from experienced Fusers out there?
patfox

Posts: 7
Registered: 09/07/09
Re: Deployment Best Practices
Posted: Nov 13, 2009 12:19 PM   in response to: shanaghe in response to: shanaghe
Helpful
  Click to reply to this thread Reply
Can I package in a way that will update my system directory to the state >>required for a working production system?

One approach would be to use the maven-feature-plugin "add-features-to-repo" goal to populate a directory with all the bundles specified in the feature (similar in structure to system folder) . This goal is mentioned in passing on the following mail thread (http://cwiki.apache.org/SM/discussion-forums.html#nabble-td23285317 ).

You could then append this newly created folder to the "org.ops4j.pax.url.mvn.defaultRepositories" property defined in "<fuseinstall>/etc/org.ops4j.pax.url.mvn.cfg". This folder will then act as a "local" repo containing all the bundles that are specified in the feature.

Best Regards
Pat.

Edited by: patfox on Nov 13, 2009 12:21 PM
shanaghe

Posts: 14
Registered: 09/21/09
Re: Deployment Best Practices
Posted: Nov 17, 2009 10:49 PM   in response to: patfox in response to: patfox
 
  Click to reply to this thread Reply
Thanks Pat,
I'm going to give this a proper attempt. I took a quick look at it, and it seems that, in theory, both the features.xml and repository generation capabilities of the features plugin should do the job. It seems there's a serious lack of documentation on this, so if I can get it working properly, I'll report back here.
jwebb

Posts: 3
Registered: 02/02/10
Re: Deployment Best Practices
Posted: Feb 9, 2010 3:03 PM   in response to: shanaghe in response to: shanaghe
 
  Click to reply to this thread Reply
Do you have any status updates on your situation?

I am having problems related to managing our features.xml file:

1. What is the best strategy for keeping our features file versioned with our code, preferebly through a maven project. I tryed to add a module to our existing aggregator project with packaging "xml" and maven complains "Cannot find lifecycle for packaging 'xml'". We tryed this because when we perform a "mvn deploy:deploy-file" to put the features file on our local Nexus server, it generated a pom.xml file that had packaging=xml. Any suggestions?

2. Is there any documentation/examples of the features-maven-plugin? This solution looks promising for managing features.xml files however I cannot find any good resources for explaining how to utilize it properly.
shanaghe

Posts: 14
Registered: 09/21/09
Re: Deployment Best Practices
Posted: Feb 12, 2010 10:47 PM   in response to: jwebb in response to: jwebb
 
  Click to reply to this thread Reply
Hi,
Getting the features plugin working was non-trivial but I eventually managed it.
I had a few bundles I wanted to package up along with the features.xml and dependencies. Within my maven project, I had submodules for my bundles and one more for the 'features' module. It has <packaging>pom</packaging>, so you have to use a few maven plugins to get what you want.

In the src/main/resource folder, I have my features.xml. It looks a bit like this:

<features>
<feature name="my-first-feature" version="${pom.version}">
<bundle>mvn:org.apache.camel/camel-core/1.6.1.2-fuse</bundle>
<bundle>mvn:org.apache.camel/camel-osgi/1.6.1.2-fuse</bundle>
<bundle>mvn:org.blah.me/my-bundle/${pom.version}
.......
</bundle>
</feature>
</features>

For a 'pom' project, you need the maven resource plugin to copy this to your output folder. For that, you need this in your pom.xml:

<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>filter</id>
<phase>generate-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
....
</plugins>

Then, in order for your features.xml to become an installable/relesable/deployable artifact, use the build-helper plugin. This is what give you more than just pom.xml in your target folder or maven repository.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/classes/features.xml</file>
<type>xml</type>
<classifier>features</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>

Once you have that, you can already add your features URL in Fuse and have it install all the bundles for you (assuming all the dependencies are set up properly)

The next step for me was to create my own repository folder. Installing artifacts in Fuse from my Maven repository was fine for development but not an option for production. I had heard that the recommended best practice was to create a repository folder using the features plugin. It's like the "system" folder in your Fuse installation. It is layed out like a Maven repository but does not require Maven to be installed. This is the bit you need in your XML to have this folder generated when you build the 'features' module:

<plugin>
<groupId>org.apache.felix.karaf.tooling</groupId>
<artifactId>features-maven-plugin</artifactId>
<executions>
<execution>
<id>add-features-to-repo</id>
<phase>generate-resources</phase>
<goals>
<goal>add-features-to-repo</goal>
</goals>
<configuration>
<descriptors>
<descriptor>file:${basedir}/target/classes/features.xml</descriptor>
</descriptors>
<features>
<feature>my-first-feature</feature>
</features>
<repository>target/my-own-repo</repository>
</configuration>
</execution>
</executions>
</plugin>

This takes all the bundles in your features.xml, including third party bundles pulled from your Maven repository, and lays them out in target/my-own-repo.

My final step was to use the assembly plugin to package this up in a tar.gz. I wanted to be able to install fuse, then extract this tar.gz on top of it so that the user could just start servicemix and have everything just 'work'.

So, for completeness, here's the assembly plugin bit:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<executions>
<execution>
<id>package</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assemble/package.xml</descriptor>
</descriptors>
<finalName>${pom.artifactId}-${pom.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>

... and (some of) the assembly descriptor....

<assembly>
<id></id> <!-- intentionally left blank -> http://jira.codehaus.org/browse/MASSEMBLY-301 -->
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/my-own-repo</directory>
<outputDirectory>my-own-repo</outputDirectory>
<excludes>
<exclude>
org/apache/camel/**
</exclude>
<exclude>
org/apache/cxf/**
</exclude>
<exclude>org/apache/servicemix/bundles/**</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>target/my-own-repo</directory>
<outputDirectory>system</outputDirectory>
<includes>
<include>org/apache/camel/**</include>
<include>org/apache/cxf/**</include>
<include>org/apache/servicemix/bundles/**</include>
</includes>
</fileSet>
<fileSet>
<directory>target/my-own-repo/</directory>
<outputDirectory>system</outputDirectory>
<includes>
<include>org/apache/camel/**</include>
<include>org/apache/cxf/**</include>
</includes>
</fileSet>
<fileSet>
<!-- Overwrite ServiceMix/Fuse-provided configuration -->
<directory>target/classes/etc</directory>
<outputDirectory>etc</outputDirectory>
</fileSet>
</fileSets>

<dependencySets>
<dependencySet>
<outputDirectory>deploy</outputDirectory>
<includes> <include>com.oracle.jdbc:ojdbc14</include>
</includes>
</dependencySet>
</dependencySets>

<files>
<file>
<source>${basedir}/target/classes/features.xml</source>
<outputDirectory>my-own-repo/org/test/me/${artifactId}/${version}
</outputDirectory>
<destName>${artifactId}-${version}-features.xml</destName>
<fileMode>0644</fileMode>
<lineEnding>unix</lineEnding>
</file>
</files>
</assembly>

As you can see, I had to put some of thee bundles in the system repository. This prevented version conflicts with the versions provided by fuse. Getting the dependencies right and avoiding conflicts was a long and painful process requiring lots of trial and error. I needed a different version of camel to the default one, and it caused endless headaches. This is the biggest drawback of Fuse and since I can't see any major benefits of using Fuse over plain Felix + the bundles I require, I might just move away from this hassle.

I also had a custom org.apache.servicemix.features.cfg file in my package which overwrites the default one. It has my featuresUrl (mvn:org.test.me/features-package/${pom.version}/xml/features) at the end. I modified to featuresBoot to include my feature and remove some of the default ServiceMix ones.

So, I hope that contains all the info needed to get your feature going. If anyone comes up with any improvements, please let me know! This setup works and gives me something which is easily installed, but it's far from perfect.

blackdogtags

Posts: 1
Registered: 07/13/10
Re: Deployment Best Practices
Posted: Jul 13, 2010 10:13 PM   in response to: shanaghe in response to: shanaghe
 
  Click to reply to this thread Reply
This post was really helpful. Thanks!