Enterprise Java

JBoss Fuse: dynamic Blueprint files with JEXL

In this post I’ll show how to add a little bit of inline scripting in your Apache Aries Blueprint xml files.

I wouldn’t call it necessarely a best practice, but I have always had the idea that this capability might be usueful; probably I started wanting this when I was forced to use xml to simulate imperative programming structures like when using Apache Ant.

And I have found the idea validated in projects like Gradle or Vagrant where a full programming language is actually hiding in disguise, pretending to be a Domain Specific Languge or a surprisingly flexible configuration syntax.

I have talked in past about something similar, when showing how to use MVEL in JBoss Fuse.
This time I will limit myself to show how to use small snippets of code that can be inlined in your otherwise static xml files, trick that might turn useful in case you need to perform simple operations like replacement of strings, aritmetics or anything else but you want to avoid writing a java class for that.

Let me say that I’m not inventing anything new around here. I’m just showing how to use a functionality that has been provided directly by the Apache Aries project but that I haven’t used that often out there.

The goal is to allow you to write snippet like this:

...
 <bean id="accountFactory" class="org.apache.aries.simple.AccountFactory">  
     <argument value="$[karaf.home.replaceAll("\\\\", "/")]">  
</argument></bean>
...

You can see that we are invoking java.lang.String.replaceAll() method on the value of an environment variable.

We can do this thanks to the Apache Aries Bluerpint JEXL Evaluator, an extension to Apache Aries Blueprint, that implements a custom token processor that “extends” the base functionality of Aries Blueprint.

In this specific case, it does it, delegating the token interpolation to the project Apache JEXL.

JEXL, Java Expression Language, it’s just a library that exposes scripting capabilities to the java platorm. It’s not unique in what it does, since you could achieve the same with the native support for Javascript or with Groovy for instance. But we are going to use it since the integration with Blueprint has alredy been written, so we can use it straight away on our Apache Karaf or JBoss Fuse instance.

The following instructions have been verified on JBoss Fuse 6.2.1:

# install JEXL bundle
install -s mvn:org.apache.commons/commons-jexl/2.1.1 
# install JEXL Blueprint integration:
install -s mvn:org.apache.aries.blueprint/org.apache.aries.blueprint.jexl.evaluator/1.0.0

That was all the preparation that we needed, now we just need to use the correct XSD version, 1.2.0 in our Bluerpint file:

xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"

Done that, we can leverage the functionality in this way:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0" xsi:schemalocation="
            http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
 
    <ext:property-placeholder system-properties="override" evaluator="jexl" placeholder-prefix="$[" placeholder-suffix="]">
 
    <bean id="myString" class="java.lang.String">
         <argument value="1">
    </argument></bean>
     
    <service interface="java.lang.CharSequence" ref="myString">
      <service-properties>
              <entry key="osgi.jndi.service.name" value="$[karaf.home.toUpperCase()]___$[1+2]">
      </entry></service-properties>
    </service>
</ext:property-placeholder></blueprint>

Copy that blueprint.xml directly into deploy/ folder, and you can check from Karaf shell that the dynamic invocation of those inline script has actually happened!

JBossFuse:karaf@root> ls (id blueprint.xml) | grep osgi.jndi.service.name
osgi.jndi.service.name = /OPT/RH/JBOSS-FUSE-6.2.1.REDHAT-107___3

This might turn useful in specific scenarios, when you look for a quick way to create dynamic configuration.

In case you might be interested into implementing your custom evaluator, this is the interface you need to provide an implementation of:

And this is an example of the service you need to expose to be able to refer it in your <property-placeholder> node:

<service interface="org.apache.aries.blueprint.ext.evaluator.PropertyEvaluator">
    <service-properties>
        <entry key="org.apache.aries.blueprint.ext.evaluator.name" value="jexl">
    </entry></service-properties>
     
    <bean class="org.apache.aries.blueprint.jexl.evaluator.JexlPropertyEvaluator">
</bean></service>
Reference: JBoss Fuse: dynamic Blueprint files with JEXL from our JCG partner Paolo Antinori at the Someday Never Comes blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button