How to deploy your Fuse bundles on OpenShift with Maven

openshiftRed Hat’s JBoss Fuse is a big, complex environment; maybe you’re trying to learn it at the same time that you’re playing around with OpenShift Online. You might get lost quickly.

I hope this guide will get you up and running relatively quickly in deploying your code (e.g., your Fuse bundle or FAB or whatever) via Maven to OpenShift Online. If you’re like me (that is, used to just dropping a jar in a deploy folder), this is going to feel a little foreign and complex at first. Bear with me.

First, you need to have a running Fuse instance

This is the easiest step in the process. Login or setup an account on OpenShift.com and fire up a gear with Fuse on it by clicking on the big “Add Application…” button.

create-fuse

A small caution, however: if you’re running on the free OpenShift plan, you will only have access to the small gear sizes. This may or may not work very well because Fuse is pretty heavyweight. If you bump into OutOfMemory exceptions in your logs or you have a little trouble deploying, this could be the cause. Consider signing up while you play around in this environment.

Second, update your Maven settings.xml

This is the file your local Maven instance uses for all kinds of stuff. For OpenShift, the stuff you need to add is a <servers> block to it so you can deploy artifacts to your OpenShift Fuse instance. When you create your Fuse instance, OpenShift will give you a admin password; add it here.

Next, create an OSGI bundle that Fuse can consume

I left this section ambiguous because either (a) you are totally new and you’re just working through the examples that the Fuse documentation provides or (b) you already have some kind of Fuse/Camel/CXF or whatever app that you want to deploy

If you don’t have anything, run the following command on a blank directory so you can follow along:

Obviously, you should change the groupId, artifactId, and version to whatever you’re working on.

Next, configure your pom.xml so that it can deploy to your Fuse server

Make sure you’re pointing to the root Fuse server and not any particular container. Add the following to your pom.xml (ideally, a parent pom.xml if you’ve got a complex deployment):

Happy with your bundle? Deploy to fuse

Since you setup the <distributionManagement> element of your project’s pom.xml, just run this command to send your jar file (OSGI bundle) up to your fuse server:

Next, create a new profile on your hawtio interface

Ok, still with me? It’s not actually that many steps when you get used to it. Trust me?

Navigate your browser to the web ui that OpenShift gave you when you set up the Fuse cartridge and gear. Click on the “Runtime” tab. Next click on the “Manage” subtab. Create a new profile by clicking the plus icon at the top of the profiles.

new-profileNow, add the features you need. The first aspect of this is changing the parent of your new profile — don’t overlook it! If you’re just running the camel example I documented above, then all you need to do is select Camel as the parent:

change-parentsIf you’re just running the Camel example I documented above, then you don’t have to add any additional features.

In case you’re wondering why we’re doing all this, when you’re running Fuse on OpenShift you’re getting the enterprise-mode Fabric Agent version of deployments. You’ll learn a lot more about this as you go, but basically you set up a “profile” with your jar and lots of other optional details, and that gets deployed as you enlist more and more servers (containers) in the overall Fuse/Fabric deployment. Lots to learn, but the summary is simple: you’re going to have to setup your application as a profile.

Almost there, now link your profile to the Maven project you uploaded

Remember all that work you did to configure your local Maven environment to point to OpenShift? It’s about to pay off. First, add the artifact you deployed with maven to your profile:

add-bundleNotice what my settings were, and alter yours to reflect what you’ve developed. Notice the “mvn” prefix to your bundle… this is what will cause Fuse to pull from its local Maven (and I do mean local, it’s got it’s own Maven repo separate from the normal roor user on OpenShift) when it deploys your code.

Let’s go. Deploy your profile!

Finally, let’s assign your new profile to the root Fuse profile. You can either “Assign” your profile to the root Fuse profile, which it probably a good idea if you’re just playing around. On the other hand, you can also create a new container to host your new profile.

assign-or-newFinally. Let’s see what you did.

If you’re using the archetype example I highlighted above, the only way you’re going to see what happened is by getting to the log file on your Fuse server. Fuse has a nice OSGI command for doing there.

There are two steps. First ssh into your OpenShift machine. To do this, type rhc ssh <machine-name> on your console:

Now, cd into fuse/container/bin and type ./fuse to get the fancy Karaf CLI interface.

To see your new camel route running (from my example above), type log:tail:

At the end of the day, it should look something like this:

log-tail-1And then:

log-tail-2Need help?

Seriously. There are a lot of steps in this process. I spent a lot of time trying to figure it out and ultimately needed the help of two experienced people at Red Hat because I didn’t have time to parse through all the documentation, which is really very good if you spend some time with it.

So if you need help, just let me know via email or by comments to this blog. My email is me@michaelrice.com

8 thoughts on “How to deploy your Fuse bundles on OpenShift with Maven”

  1. HI! Thanks for the tutorial, very informative! 🙂
    I have only one question for you, I’ve done everything you said so far but I’m having this issue when adding the profile (that contains my bundle) to the container:

    Provision Exception:
    io.fabric8.agent.utils.MultiException: Error while downloading artifacts
    at io.fabric8.agent.utils.AgentUtils$ArtifactDownloader.await(AgentUtils.java:314)
    at io.fabric8.agent.DeploymentBuilder.download(DeploymentBuilder.java:160)
    at io.fabric8.agent.DeploymentAgent.doUpdate(DeploymentAgent.java:503)
    at io.fabric8.agent.DeploymentAgent$2.run(DeploymentAgent.java:252)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
    java.util.zip.ZipException: zip file is empty
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.(ZipFile.java:215)
    at java.util.zip.ZipFile.(ZipFile.java:145)
    at java.util.jar.JarFile.(JarFile.java:153)
    at java.util.jar.JarFile.(JarFile.java:117)
    at org.fusesource.common.util.Manifests.getManifest(Manifests.java:43)
    at io.fabric8.agent.DeploymentBuilder.getAttributes(DeploymentBuilder.java:468)
    at io.fabric8.agent.DeploymentBuilder.manageResource(DeploymentBuilder.java:439)
    at io.fabric8.agent.DeploymentBuilder.access$300(DeploymentBuilder.java:88)
    at io.fabric8.agent.DeploymentBuilder$2.downloaded(DeploymentBuilder.java:406)
    at io.fabric8.agent.utils.AgentUtils$ArtifactDownloader.onDownloaded(AgentUtils.java:289)
    at io.fabric8.agent.utils.AgentUtils$ArtifactDownloader$1.operationComplete(AgentUtils.java:255)
    at io.fabric8.agent.utils.AgentUtils$ArtifactDownloader$1.operationComplete(AgentUtils.java:252)
    at io.fabric8.agent.download.DefaultFuture.notifyListener(DefaultFuture.java:342)
    at io.fabric8.agent.download.DefaultFuture.notifyListeners(DefaultFuture.java:327)
    at io.fabric8.agent.download.DefaultFuture.setValue(DefaultFuture.java:255)
    at io.fabric8.agent.download.AbstractDownloadTask.setFile(AbstractDownloadTask.java:62)
    at io.fabric8.agent.download.AbstractDownloadTask.run(AbstractDownloadTask.java:78)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

    Full stack: http://pastebin.com/yKrYe6wj

    Thanks in advance! 🙂

    1. Hey Christian — sorry it took me a while to see your comment! I’ll take a look and let you know what I can find.

      1. Hi – any updates on this? I am running into the same error while deploying a OSGi bundle into openshift. The same bundle gets deployed fine on a local instance of fuse.

        1. Uhhh… you caught me; I haven’t gotten around to looking. I’ll try to take a look in the next day or two. Sorry! I think it’s one of those, you know, works in my environment things. Thanks for running through it though.

          1. This is working just fine now. Thanks! 🙂
            Another question though.. I’ve noticed that I need to bump my bundle’s version and after running the maven command I have to delete and add the it manually in my JBoss Fuse console. Is there a way of doing this automatically? I think running the mvn command with the same version every time just doesn’t update the bundle in my JBoss Fuse profile.

            Thanks in advance.

  2. You need to agree ID of the repository in both files: pom.xml and settings.xml to one like ‘openshift-fabric-maven-proxy’

    Anyway: very usefull article

    P.S. Another small corection helpfull would be to clear what feature to choose. I had problem because ‘Camel’ doesn’t exist. ‘feature-camel’ or simple ‘camel’

Leave a Reply

Your email address will not be published. Required fields are marked *