Nous allons faire nos premiers pas en développant un bundle OSGi basé sur Spring et Camel sans utiliser Maven (utilisation de ANT). Dans cet exemple, nous allons créer un bundle qui attend une requête GET HTTP, qui trace le contenu dans un fichier et retourne une page Web au navigateur. Il s’agit d’un exemple sans JSP et sans servlet.
1) Environnement
Il vous faudra Eclipse, le SDK Java, Fuse, Camel 2.4 et vos doigts.
Dans la console Karaf de Fuse, il faudra installer un composant supplémentaire : camel-jetty. Pour se faire, vous pouvez taper la commande : features:install camel-jetty. En cas de problème du genre :
URL [mvn:org.apache.camel/camel-http/2.2.0-fuse-02-00] could not be resolved
Il faudra placer les jars de Camel à la main, ça se fait simplement en créant l’arborescence suivante :
/opt |-/apache-servicemix |-/system |-/org |-/apache |-/camel |-/camel-http | |-/2.2.0-fuse-02-00 | |-/camel-http-2.2.0-fuse-02-00.jar |-/camel-jetty |-/2.2.0-fuse-02-00 |-/camel-jetty-2.2.0-fuse-02-00.jar
2) Sous Eclipse
Il va falloir récupérer le jar BND sur aQute.
On crée une librairie utilisateur pour Camel :
On crée un nouveau projet java ayant l’arborescence suivante :
app.env=DEV serviceMix.deploy=/opt/apache-servicemix/deploy bnd.path= lib/biz.aQute.bnd.jar camel.home=/opt/apache-camel/lib
Puis le build.xml pour ANT :
<project name="HTTP-Camel-Test" default="all" basedir="."> <property file="build.properties" /> <property name="bnd.file" value="bnd.bnd" /> <property name="build.home" value="${basedir}/build" /> <property name="dist.home" value="${basedir}/dist" /> <property name="src.home" value="${basedir}/src" /> <property name="resources.home" value="${basedir}/resources" /> <property name="lib.home" value="${basedir}/lib" /> <property name="compile.debug" value="true" /> <property name="compile.deprecation" value="false" /> <property name="compile.optimize" value="true" /> <taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="${bnd.path}" /> <path id="compile.classpath"> <fileset dir="${camel.home}"> <include name="*.jar" /> </fileset> <pathelement location="${common.lib.path}/bin/" /> <fileset dir="${lib.home}"> <include name="*.jar" /> </fileset> </path> <target name="all" depends="clean,build,deploy" /> <target name="clean"> <delete dir="${build.home}" /> <delete dir="${dist.home}" /> </target> <target name="build" depends="confenv,prepare"> <javac encoding="utf8" srcdir="${src.home}" destdir="${build.home}" debug="${compile.debug}" deprecation="${compile.deprecation}" optimize="${compile.optimize}"> <classpath refid="compile.classpath" /> </javac> <bnd classpath="${build.home}" eclipse="false" failok="false" exceptions="true" output="${dist.home}" files="${bnd.file}" /> </target> <target name="confenv"> <copy todir="${build.home}" overwrite="true" preservelastmodified="true"> <fileset dir="${resources.home}" casesensitive="yes" /> <mapper type="regexp" from="^(.*)${app.env}-(.*)$" to="\1\2" /> </copy> </target> <target name="deploy" depends="build"> <copy todir="${serviceMix.deploy}" overwrite="true" preservelastmodified="true"> <fileset dir="${dist.home}" casesensitive="yes" /> </copy> </target> <target name="prepare"> <mkdir dir="${build.home}" /> <mkdir dir="${dist.home}" /> <copy todir="${build.home}"> <fileset dir="${src.home}" /> </copy> <copy todir="${build.home}"> <fileset dir="${resources.home}" /> </copy> </target> </project>
Enfin créer un fichier bnd.bnd à la racine :
Bundle-SymbolicName: HTTP-Camel-Test Bundle-Name: HTTP-Camel-Test :: test de Camel-HTTP Bundle-Version: 1.0 Export-Package: *;-noimport:=true Import-Package: * Include-Resource: -runfw: org.apache.felix.framework
J’expliquerai comment fonctionne le fichier bnd, mais vous pouvez avoir un avant goût sur aQute.
3) En route pour Camel
Entrons dans le vif du sujet. Commençons par nos classes :
3.1) La route Camel
package org.giwi.test.camel.http.routes; import org.apache.camel.builder.RouteBuilder; import org.giwi.test.camel.http.processor.MyHTTPProcessor; public class TestRoute extends RouteBuilder { /* * (non-Javadoc) * * @see org.apache.camel.builder.RouteBuilder#configure() */ @Override public void configure() throws Exception { from("jetty:http://0.0.0.0:8181/httpTest/index.jsp?sessionSupport=true") .process(new MyHTTPProcessor()) .to("file:/home/giwi/temp/?fileName=toto.txt&fileExist=Append") .to("bean:processContent"); } }
Explication : la requête HTTP sera attrapée par le composant Jetty à partir de l’instruction from, la requête HTTPRequest est passée à un processeur. Puis le résultat du processeur est enregistré dans un fichier (attention, un simple / en début de path indique un path absolu, un double / indique un path relatif. Puis le message continue son chemin vers un bean Java et le résultat de ce bean sera le corps de HTTPResponse.
3.2) Le processeur
package org.giwi.test.camel.http.processor; import javax.servlet.http.HttpServletRequest; import org.apache.camel.Exchange; import org.apache.camel.Processor; public class MyHTTPProcessor implements Processor { @Override public void process(final Exchange exchange) throws Exception { // accès à la requête final HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class); final String name = req.getParameter("name"); exchange.getOut().setBody(name); } }
3.3) Le bean Java
package org.giwi.test.camel.http.generator; public class Generator { public String generate(final String value) { return "Hello " + value + ""; } }
3.4) Le Contexte Camel
Il s’agit de la subtilité du bouzin. il faut créer un fichier /resources/META-INT/spring/camel-context.xml.
<?xml version="1.0" encoding="UTF-8"?> <!-- Configures the Camel Context --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext id="HTTP-Camel-Test" xmlns="http://camel.apache.org/schema/spring"> <routeBuilder ref="route01" /> </camelContext> <bean id="route01" /> <bean id="processContent" /> </beans>
Dans ce fichier, nous déclarons la route et le bean.
4) Déploiement et test
Il faut lancer la tâche ANT all pour que le bundle se compile, se package en jar et se dépose dans /opt/apache-servicemix/deploy. Si Fuse est démarré, le bundle se déploie automatiquement. Pour le tester, il suffit d’utiliser l’url : http://localhost:8181/httpTest/index.jsp?name=toto.
Normalement, vous devriez voir « Hello toto » dans votre navigateur et le fichier /home/giwi/temp/toto.txt doit contenir la chaîne « toto ».
5) Pour aller plus loin
- Les composants Camel : http://camel.apache.org/components.html
- Fuse : http://fusesource.com/products/enterprise-servicemix/#documentation
- aQute : http://www.aqute.biz/Code/Bnd