Friday, May 18, 2012

OSGi on OpenShift (Free, OpenSource Cloud)

While JBoss OSGi support for OpenShift is being looked at, I had a go at getting Apache Felix to work on OpenShift. And I have to say, the results were good :)

OpenShift is Red Hat's cloud. You can create and use cloud instances for free, for development purposes - a free cloud playground!! 
OpenShift comes with a number of cartridges, including a somewhat reduced version of JBoss AS7 (no OSGi), Node.js and Jenkins. However OpenShift also has a DIY application type. With this you can deploy whatever you like :) So, I took the Felix OSGi framework and deployed that in OpenShift using the DIY type!

Here's what I did.
1. Get a free OpenShift account by signing up at http://openshift.redhat.com
2. Once you have your account you can create an application:
Select the Do-It-Yourself application type.

3. Create a URL for the application:
I went for http://felix-coderthoughts.rhcloud.com.
When you click create, the an empty holder application is created for you. We can fill the application in using git.

4. Now you can clone the application using git, OpenShift will tell you the URL to use, mine looks like this:
$ git clone ssh://blahblahblah@felix-coderthoughts.rhcloud.com/~/git/felix.git
Oh, yes, it only works once you have an SSH key added to your account. You can do that in the 'My Account' section of the web console, or from the command line, see here for more info.

5. At this point you can start putting your cloud content into git. Initially your clone contains a README, some mostly empty directories and some openshift hooks:
$ ls -a
.git        README        misc
.openshift  diy

So what next?
I started by adding a modified Apache Felix installation to a directory called osgi/felix-framework-4.0.2. I took Felix 4.0.2 and instead of the gogo terminal-based console bundles I used the Web Console with Config Admin and Pax-Web.

Next we need to modify the OpenShift action hooks to start the OSGi Framework. This is what my .openshift/action_hooks/start script does:
cd $OPENSHIFT_GEAR_DIR/repo/osgi/felix-framework-4.0.2
export felixcmd="java -Dorg.ops4j.pax.web.listening.addresses=$OPENSHIFT_INTERNAL_IP -jar bin/felix.jar"
nohup $felixcmd &
First the current directory is changed to where Felix is stored, and then Felix is launched with as extra option for Pax Web, the IP address that OpenShift wants us to use. The port number is configured as 8080, as required by OpenShift, this is specified in the Felix configuration file.

That's pretty much it - I also created a fairly blunt stop script that kills all the Java processed. I guess that could be refined ;)

Ok, so let's try it out.
As a convenience I added this setup as a github project called felix-openshift, you can get it into your freshly cloned OpenShift repo with:
$ git fetch git://github.com/bosschaert/felix-openshift.git
From git://github.com/bosschaert/felix-openshift
 * branch            HEAD       -> FETCH_HEAD
Then merge the content in with:
$ git merge -Xtheirs FETCH_HEAD
Note that -Xtheirs automatically takes the start and stop scripts from the fetched project and overwrites the local ones. If your git client doesn't support this option you'll probably have to merge these scripts by hand...

To see it all in action, run:

$ git push
Counting objects: 32, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (21/21), done.
Writing objects: 100% (27/27), 3.49 MiB | 86 KiB/s, done.
Total 27 (delta 2), reused 10 (delta 1)
remote: Starting application...
remote: Done
... you will see more logging messages, and then ...
remote: 2012-05-17 16:19:11.133:INFO:oejs.AbstractConnector:Started NIOSocketConnectorWrapper@127.2.146.129:8080 STARTING
remote: 2012-05-17 16:19:11.561:INFO:oejsh.ContextHandler:started HttpServiceContext{httpContext=org.apache.felix.webconsole.internal.servlet.OsgiManagerHttpContext@174d93a}
Aha - the webconsole has started!

I can now launch it at http://felix-coderthoughts.rhcloud.com/system/console/bundles (or whatever your OpenShift URL is). Default Felix Web Console credentials are admin/admin:
From here on I can use the Felix Web Console to deploy more bundles, control the framework and so on.

After pushing the git repo, you can also control the cloud instance from the commandline with rhc:
$ rhc app start -a felix -l user@domain.org
and
$ rhc app stop -a felix -l user@domain.org

There you go, OSGi running in the cloud. And you can develop and play with this stuff without the need to give anyone your credit card details :)