Créer une façade REST avec camel-cxf dans un environnement OSGi

Nous allons voir comment créer simplement une façade REST avec camel-cxf et la déployer dans un container OSGi.

Voici les versions utilisées :

  • Karaf 3.0.2
  • Camel 2.13.2

Commençons tout d'abord par le pom du projet :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.netapsys</groupId>
	<artifactId>blog</artifactId>
	<version>1.0.0</version>
	<packaging>bundle</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-cxf</artifactId>
			<version>2.13.2</version>
		</dependency>
		<dependency>
			<groupId>javax.ws.rs</groupId>
			<artifactId>javax.ws.rs-api</artifactId>
			<version>2.0</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Import-Package>*</Import-Package>
						<Export-Package>!*</Export-Package>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
pom.xml

et le code de la façade :

package com.netapsys.blog.facade;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

/**
 * Blog facade
 * @author ssenouci 
 *
 */
@Path("/")
public class BlogFacade {

	/**
	 * Ask visitor's name
	 * @return
	 */
	@GET
	@Path("/")
	public String askName() {
		return "";
	}

	/**
	 * Receive visitor's name
	 * @param content Visitor's name 
	 * @return
	 */
	@POST
	@Path("/")
	public String receiveName(String content) {
		return "";
	}
}
BlogFacade.java

La façade comprend deux méthodes :

  • askName() : bindée sur la méthode HTTP GET. Elle permettra de demander à l'utilisateur son nom.
  • receiveName(String content) : bindée sur la méthode HTTP POST. Elle permettra de récupérer le nom de l'utilisateur

Pour traiter les requêtes HTTP, nous allons nous servir du composant camel-cxf.

Voici la route à utiliser :

package com.netapsys.blog.facade.route;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;

/**
 * Route used to process blog REST requests.
 * @author ssenouci
 *
 */
public class BlogFacadeRoute extends RouteBuilder {

	/**
	 * Blog facade URI.
	 */
	private String blogFacadeUri;

	/**
	 * Ask name URI
	 */
	private static final String ASK_NAME_URI = "direct:askName";

	/**
	 * Receive name URI
	 */
	private static final String RECEIVE_NAME_URI = "direct:receiveName";

	/* (non-Javadoc)
	 * @see org.apache.camel.builder.RouteBuilder#configure()
	 */
	@Override
	public void configure() throws Exception {

		from(blogFacadeUri)
		.routeId(blogFacadeUri)
		// Redirect exchange to matching route
		.recipientList(simple("direct:${header.operationName}"));

		// Route handling askName facade method requests / messages
		from(ASK_NAME_URI)
		.routeId(ASK_NAME_URI)
		.process(new Processor() {

			public void process(Exchange exchange) throws Exception {
				exchange.getOut().setBody("Hi. What's your name ?");
			}
		})
		.end();

		// Route handling receiveName facade method requests / messages
		from(RECEIVE_NAME_URI)
		.routeId(RECEIVE_NAME_URI)
		.process(new Processor() {

			public void process(Exchange exchange) throws Exception {
				exchange.getOut().setBody("Welcome " + exchange.getIn().getBody(String.class));
			}
		})
		.end();
	}

	public void setBlogFacadeUri(String blogFacadeUri) {
		this.blogFacadeUri = blogFacadeUri;
	}
}
BlogFacadeRoute.java

Le point d'entrée de la route est bindé sur l'URI de la façade et chaque exchange sera redirigé vers une sous-route (appelée en direct), dont l'URI est défini par le nom de la méthode appelée dans la façade.

Pour terminer, voici le blueprint de notre bundle :

<?xml version="1.0" encoding="UTF-8"?><blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
	xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
	xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd">

	<!-- Facade definitions -->
	<cxf:rsServer id="blogFacade" address="/blog" serviceClass="com.netapsys.blog.facade.BlogFacade"/>

	<!-- Route definitions -->
	<bean id="blogFacadeRoute" class="com.netapsys.blog.facade.route.BlogFacadeRoute">
		<property name="blogFacadeUri" value="cxfrs:bean:blogFacade?bindingStyle=SimpleConsumer" />
	</bean>

	<!-- Camel context definition -->
	<camelContext id="blogCamelContext" autoStartup="true" trace="true" xmlns="http://camel.apache.org/schema/blueprint">
		<routeBuilder ref="blogFacadeRoute" />
	</camelContext>
</blueprint>
blueprint.xml

dans lequel nous retrouvons :

  • La déclaration de la façade et du path auquel elle sera associée.
  • La déclaration de la route, dans laquelle nous injectons l'URI de la façade.

Et voilà, c'est tout pour la partie code.

Passons à présent au déploiement. Voici le features repository associé à notre projet :

<?xml version="1.0" encoding="UTF-8"?>

<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="blog-1.0.0">

	<repository>mvn:org.apache.camel.karaf/apache-camel/2.13.2/xml/features</repository>

	<!-- Project features -->
	<feature name="com.netapsys.blog" version="1.0.0">
		<feature>camel-http</feature>
		<feature>camel-blueprint</feature>
		<feature>camel-cxf</feature>
		<bundle>mvn:com.netapsys/blog/1.0.0</bundle>
	</feature>
</features>
features.xml

La feature com.netapsys.blog déploiera les features camel-http, camel-blueprint, camel-cxf ainsi que notre bundle.

Pour ce faire, démarrons Karaf et enregistrons notre features repository :

feature:repo-add mvn:com.netapsys/features/1.0.0/xml/features

Puis, installons notre feature :

feature:install com.netapsys.blog

L'appel en GET à l'URL http://localhost:8181/cxf/blog nous retourne bien la réponse suivante :

Hi. What's your name ?

Et l'appel en POST avec le body "John Doe" nous retourne "Welcome John Doe" comme escompté.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.