Camel

Camel

Créer un composant Apache Camel de connexion à l’APNS – 3 sur 3

Créer un composant Apache Camel de connexion à l’APNS – 3 sur 3

Nous avons vu dans un premier article comment initier le développement d’un composant Apache Camel, puis dans un second comment implémenter ses différentes classes.

A ce stade de notre développement nous sommes déjà en mesure d’utiliser pleinement notre composant, mais nous ne pouvons pas encore en assurer sa qualité. Pour cela, il est nécessaire d’ajouter à notre composant différentes classes de test. Bien que la testabilité de frameworks d’intégration puisse parfois paraître difficile, le projet Apache Camel fournit tous les outils nécessaires permettant de répondre à ce besoin. Nous verrons donc dans cet article comment tester le composant que nous avons développé.

Pour finir, nous verrons comment intégrer notre développement à un projet Camel, ainsi que les limites de notre composant et les solutions pour résoudre ces limitations.

Tester la classe ApnsConsumer

Bien que le projet Apache Camel permette de travailler naturellement avec Spring, nous nous attarderons dans un premier temps sur les méthodes permettant de tester notre composant sur un mode standalone. Pour cela, nous étendrons la classe CamelTestSupport. Cette dernière fournit les méthodes nécessaires pour effectuer différentes assertions sur les valeurs attendues en fin de traitement, en particulier sur des endpoints de type MockEndpoint.

Nous devons tout d’abord implémenter les 2 méthodes suivantes:

Méthode Description
createCamelContext() Permet de créer le contexte Camel qui sera utilisé par le test
createRouteBuilder() Permet de construire la route qui sera appelée par le test. Idéalement, la route doit se terminer par l’appel d’un MockEpoint

Avant l’exécution de nos tests, un serveur APNS bouchonné doit être lancé. Il enverra sur le flux feedback des données factices.

L’objectif de ce test est de valider que le endpoint apns:consumer est capable de consommer les informations de test renvoyées par le flux feedback du serveur bouchonné. Le endpoint Camel mock:result nous permet de valider les assertions nécessaires sur les messages reçus par ce endpoint.

Le endpoint apns:consumer est configuré pour poller le flux feedback de l’APNS toutes les 500ms. Le test ne doit donc pas durer raisonnablement plus de 5 secondes en tenant compte du temps d’attente d’une seconde avant les assertions et du temps de démarrage du serveur bouchon APNS. Un timeout de 5 secondes est donc placé sur le test pour s’assurer que ce dernier tombe en erreur si un événement bloquant inattendu empêche le test de se terminer.

public class ApnsConsumerTest extends CamelTestSupport {

    ApnsServerStub server;

    public ApnsConsumerTest() {
    	super();
    }


    /**
     * Démarrage du serveur bouchonné simulant l'APNS
     */
    @Before
    public void startup() throws InterruptedException {
        server = ApnsServerStub.prepareAndStartServer(FixedCertificates.TEST_GATEWAY_PORT, FixedCertificates.TEST_FEEDBACK_PORT);
    }

    /**
     * Arrêt du serveur bouchonné simulant l'APNS
     */
    @After
    public void stop() {
        server.stop();
    }


    /**
     * Test de l'ApnsConsumer. L'objectif est de vérifier que le flux feedback est
     * bien consommé par la route Camel. Pour cela on vérifie après consommation
     * que le endpoint MockEndpoint a bien reçu les messages.
     */
    @Test(timeout=5000)
    public void testConsumer() throws Exception {

    	byte[] deviceTokenBytes = ApnsUtils.createRandomDeviceTokenBytes();
        String deviceToken = ApnsUtils.encodeHexToken(deviceTokenBytes);

        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);
        mock.message(0).body().isInstanceOf(InactiveDevice.class);

        byte[] feedBackBytes = ApnsUtils.generateFeedbackBytes(deviceTokenBytes);
        server.toSend.write(feedBackBytes);

        Thread.sleep(1000);

        assertMockEndpointsSatisfied();

        InactiveDevice inactiveDevice = (InactiveDevice)mock.getExchanges().get(0).getIn().getBody();
        assertNotNull(inactiveDevice);
        assertNotNull(inactiveDevice.getDate());
        assertNotNull(inactiveDevice.getDeviceToken());
        assertEquals(deviceToken, inactiveDevice.getDeviceToken());
    }

    /**
     * Création et configuration du contexte Camel avec une configuration de test.
     * Enregistrement du composant APNS, et configuration de l'ApnsService
     */
    protected CamelContext createCamelContext() throws Exception {
        CamelContext camelContext = super.createCamelContext();

        ApnsServiceFactory apnsServiceFactory = ApnsUtils.createDefaultTestConfiguration();
        ApnsService apnsService = apnsServiceFactory.getApnsService();

        ApnsComponent apnsComponent = new ApnsComponent(apnsService);

        camelContext.addComponent("apns", apnsComponent);

        return camelContext;
    }

    /**
     * Création de la route Camel permettant de simuler la consommation du flux
     * feedback de l'APNS
     */
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() throws Exception {
                from("apns:consumer?initialDelay=500&delay=500&timeUnit=MILLISECONDS")
                	.to("log:com.apache.camel.component.apns?showAll=true&multiline=true")
                	.to("mock:result");
            }
        };
    }

}

Tester la classe ApnsProducer

De la même façon que nous nous y sommes pris pour la classe de test ApnsConsumerTest, nous allons étendre la classe CamelTestSupport pour tester notre classe ApnsProducer. L’objectif est de vérifier que le serveur bouchonné reçoit bien les messages produits.

public class ApnsProducerTest extends CamelTestSupport {

    private ApnsServerStub server;
    private String FAKE_TOKEN = "19308314834701ACD8313AEBD92AEFDE192120371FE13982392831701318B943";

    public ApnsProducerTest() {
    	super();
    }


    /**
     * Démarrage du serveur bouchonné simulant l'APNS
     */
    @Before
    public void startup() {
        server = ApnsServerStub.prepareAndStartServer(FixedCertificates.TEST_GATEWAY_PORT, FixedCertificates.TEST_FEEDBACK_PORT);
    }

    /**
     * Arrêt du serveur bouchonné simulant l'APNS
     */
    @After
    public void stop() {
        server.stop();
    }


    /**
     * Test de l'ApnsProducer. L'objectif est de vérifier que le serveur APNS a
     * bien reçu les notifications envoyées. 
     * Pour cela on vérifie après production des notifications que le serveur bouchonné
     * a bien reçu les messages: On s'assure que les tableaux de bytes de la notification
     * produite et du contenu reçu par le serveur sont bien égaux.
     */
    @Test(timeout=2000)
    public void testProducer() throws Exception {
    	String message = "Hello World";
    	String messagePayload = APNS.newPayload().alertBody(message).build();

        ApnsNotification apnsNotification = new ApnsNotification(FAKE_TOKEN, messagePayload);
        server.stopAt(apnsNotification.length());

        template.sendBody("direct:test", message);

        server.messages.acquire();
        assertArrayEquals(apnsNotification.marshall(), server.received.toByteArray());
    }

    /**
     * Création et configuration du contexte Camel avec une configuration de test.
     * Enregistrement du composant APNS, et configuration de l'ApnsService
     */
    protected CamelContext createCamelContext() throws Exception {
        CamelContext camelContext = super.createCamelContext();

        ApnsServiceFactory apnsServiceFactory = ApnsUtils.createDefaultTestConfiguration();
        ApnsService apnsService = apnsServiceFactory.getApnsService();

        ApnsComponent apnsComponent = new ApnsComponent(apnsService);
        camelContext.addComponent("apns", apnsComponent);

        return camelContext;
    }

    /**
     * Création de la route Camel permettant de simuler la production de messages
     * à destination des serveurs APNS.
     */
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() throws Exception {
                from("direct:test").
                setHeader(ApnsConstants.HEADER_TOKENS, constant(FAKE_TOKEN)).
                to("apns:notify");
            }
        };
    }
}

Tester l’intégration d’un composant Camel avec Spring

Les configurations Camel sont souvent déclarées par des fichiers de configuration Spring. C’est pourquoi il est nécessaire de tester l’intégration du composant dans une configuration Spring. Un bon moyen d’automatiser ce type de test est d’utiliser les classes de support JUnit fournies par Spring ( _AbstractJUnit4SpringContextTests_ ).

L’ensemble de la configuration est déclarée dans le fichier SpringApnsConsumerTest-context.xml associé au test unitaire. Les différents beans utilisés par la classe de test sont injectés via les annotations @Autowired et @EndpointInject(uri = « mock:result »).

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       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">

	<bean id="apnsServiceFactory" class="org.apache.camel.component.apns.factory.ApnsServiceFactory">
		<property name="feedbackHost" value="localhost" />
		<property name="feedbackPort" value="7843" />
		<property name="gatewayHost" value="localhost" />
		<property name="gatewayPort" value="7654" />
		<property name="sslContext" ref="sslContext" />
	</bean>

	<!-- Déclaration de l'ApnsService, utilisé par l'ApnsComponent -->
	<bean id="apnsService" factory-bean="apnsServiceFactory" factory-method="getApnsService" />


	<bean id="sslContext" class="org.apache.camel.component.apns.util.FixedCertificates" factory-method="clientContext"/>

	<!-- Déclaration de l'ApnsComponent. Le scheme utilisé pour la création des endpoints -->
	<!-- sera l'Id utilisé pour la création du bean -->
	<bean id="apns" class="org.apache.camel.component.apns.ApnsComponent">
		<property name="apnsService" ref="apnsService" />
	</bean>

	<!-- Déclaration du context Camel, et de la route de test: 'apns-test' -->
	<!-- Les message reçus par le flux feedback seront envoyés vers le endpoint mock:result -->
	<camelcontext id="camel-apns-test" xmlns="http://camel.apache.org/schema/spring">

		<route id="apns-test">
			<from uri="apns:consumer?initialDelay=500&amp;amp;amp;amp;delay=500&amp;amp;amp;amp;timeUnit=MILLISECONDS" />
			<to uri="log:org.apache.camel.component.apns?showAll=true&amp;amp;amp;amp;multiline=true" />
			<to uri="mock:result" />
		</route>

	</camelcontext>

</beans>

Une fois la déclaration du composant Camel effectuée via le fichier de configuration Spring, il ne reste plus qu’à injecter les différents beans configurés dans les propriétés de la classe de test. Le contenu du test en lui-même reste identique, cependant la partie configuration a disparu ce qui rend le test plus lisible. Afin de faire disparaître du test ce qui peut encore en parasiter sa lisibilité, une classe de test parent peut être créée pour contenir les méthodes d’initialisation et d’arrêt du serveur APNS de test.

@ContextConfiguration
public class SpringApnsConsumerTest extends AbstractJUnit4SpringContextTests {

    ApnsServerStub server;

    /**
     * Injection du context Camel déclaré via Spring
     */
    @Autowired
    protected CamelContext camelContext;

    /**
     * Injection du endpoint Camel "mock:result" déclaré via Spring
     */
    @EndpointInject(uri = "mock:result")
    protected MockEndpoint mock;

    public SpringApnsConsumerTest() {
    	super();
    }


    /**
     * Démarrage du serveur bouchonné simulant l'APNS
     */
    @Before
    public void startup() throws InterruptedException {
        server = ApnsServerStub.prepareAndStartServer(FixedCertificates.TEST_GATEWAY_PORT, FixedCertificates.TEST_FEEDBACK_PORT);
    }

    /**
     * Arrêt du serveur bouchonné simulant l'APNS
     */
    @After
    public void stop() {
        server.stop();
    }


    /**
     * Test du consommateur
     */
    @Test(timeout=5000)
    public void testConsumer() throws Exception {

    	byte[] deviceTokenBytes = ApnsUtils.createRandomDeviceTokenBytes();
        String deviceToken = ApnsUtils.encodeHexToken(deviceTokenBytes);

        mock.expectedMessageCount(1);
        mock.message(0).body().isInstanceOf(InactiveDevice.class);

        byte[] feedBackBytes = ApnsUtils.generateFeedbackBytes(deviceTokenBytes);
        server.toSend.write(feedBackBytes);

        Thread.sleep(1000);

        mock.assertIsSatisfied();

        InactiveDevice inactiveDevice = (InactiveDevice)mock.getExchanges().get(0).getIn().getBody();
        Assert.assertNotNull(inactiveDevice);
        Assert.assertNotNull(inactiveDevice.getDate());
        Assert.assertNotNull(inactiveDevice.getDeviceToken());
        Assert.assertEquals(deviceToken, inactiveDevice.getDeviceToken());
    }

}

Limitations du composant actuel

Dans un soucis de simplicité, le composant présenté est limité fonctionnellement et ne propose qu’un ensemble réduit de fonctionnalités. L’implémentation proposée dans ce billet nous oblige à déclarer les tokens à notifier directement au niveau de la route. Cependant une implémentation plus complète pourrait permettre d’exploiter des en-têtes par exemple pour rendre la sélection de token à notifier plus dynamique.

Heureusement, la richesse du framework Apache Camel nous permet de passer outre cette restriction et d’obtenir l’aspect dynamique souhaité en utilisant le pattern Recipient List, qui permet par exemple l’extraction des URIs de destination depuis un en-tête de message produit au préalable.

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("direct:a").recipientList(
        header("recipientListHeader").tokenize(","));
    }
};

Dans cet exemple, l’en-tête recipientListHeader contiendrait les différentes URIs séparées par des virgules.

Utilisation du composant dans un projet

Pour utiliser le composant développé dans cette série d’articles, il suffit de l’importer en tant que dépendance Maven dans votre projet Camel et de déclarer le repository qui permettra de le charger à défaut de l’avoir déjà dans son répository local.

Ce qui donne les lignes suivantes à ajouter dans le pom de votre projet:

  • La dépendance Maven:
<dependency>
    <groupid>org.apache.camel</groupid>
    <artifactid>camel-apns</artifactid>
    <version>2.4.0</version>
</dependency>
  • Le repository Maven qui met à disposition le composant:
<repositories>
    <repository>
        <id>camel-apns.repo-release</id>
        <url>http://camel-apns.googlecode.com/svn/maven/public/repository/release/</url>
    </repository>
</repositories>

Exemples d’utilisation

Afin de donner une vision synthétique de l’usage de notre composant, voici un condensé de quelques exemples d’utilisation:

  • Consommation du flux feedback avec une configuration Java
      from("apns:consumer")
            .to("log:com.apache.camel.component.apns?showAll=true&amp;amp;amp;amp;multiline=true")
            .to("mock:result");

  • Envoi de notifications avec une configuration Java
      from("direct:test")
            .setHeader(ApnsConstants.HEADER_TOKENS, constant(FAKE_TOKEN))
            to("apns:notify");
  • Envoi d’une notification avec une configuration Spring
<camelcontext id="camel-apns-test" xmlns="http://camel.apache.org/schema/spring">

	<route id="apns-test">
		<from uri="apns:consumer" />
		<to uri="log:org.apache.camel.component.apns?showAll=true&amp;amp;amp;amp;multiline=true" />
		<to uri="mock:result" />
	</route>

</camelcontext>

Conclusion

Nous avons vu dans cet article comment créer et tester un composant Camel qui communique avec les serveurs de notifications d’Apple. Les API du framework ont été pensées pour faciliter le développement de nouveaux composants, et vous permettront d’implémenter et de tester facilement les composants dont vous avez besoin. Vous pouvez consulter le code source du composant camel-apns présenté dans cette série d’article sur sa page Google Code.

Liens utiles

Le site google code du composant ‘camel-apns’ présenté dans le billet:

D’autres liens utiles sur le développement de composants Camel:

Précédentes parties de l’article:

Créer un composant Apache Camel de connexion à l’APNS – 1 sur 3

Créer un composant Apache Camel de connexion à l’APNS – 1 sur 3

Le projet Apache Camel est un framework d’intégration basé sur l’implémentation de patterns d’intégration d’entreprise connus. Il permet d’implémenter des règles de routage et de médiation à partir d’un DSL Java ou bien via des configurations Spring au format Xml.

Apache Camel utilise la notion d’URIs, ce qui permet de travailler facilement avec différents types de transport ou modèles d’échange de messages, tels que HTTP ou JMS. De la même manière, Apache Camel est capable de travailler avec différents formats de données (Csv, Xml, Json, …).

L’utilisation des composants fournis out of the box permet de travailler avec de nombreux protocoles et formats de données. Mais qu’en est-il lorsqu’un connecteur vient à manquer?

Pour répondre à cette question, le projet Apache Camel propose une API complète permettant d’implémenter soi-même des composants adaptés à son besoin.

Objectif

L’objectif de cet article est de présenter comment initier le développement d’un composant Apache Camel.

Pour cela, nous mettrons en place un composant qui permettra de dialoguer avec l’Apple Push Notification Service, dans le but d’envoyer des notifications aux différents terminaux Apple (iPad, iPhone, iPod Touch).

Le composant proposera à la fois des endpoints de type producer et de type consumer qui permettrons respectivement d’envoyer des notifications et de lire un flux feedback d’informations en provenance de l’APNS.

En pré-requis, un ensemble de endpoints devra utiliser une même instance de la classe ApnsService proposée par la librairie java-apns, qui permet de dialoguer avec les serveurs d’Apple. La firme à la pomme préconise en effet de créer un nombre limité de connexions, et de réutiliser celles-ci pour communiquer avec ses serveurs. Nous utiliserons également le scheme apns pour déclarer les URIs qui représenteront les endpoints gérés par nos composants.

Présentation de l’APNS

L’Apple Push Notification Service est disponible pour les applications destinées aux iPhones, iPads et iPods touch. Il permet d’envoyer des notifications de 3 types : texte, image ou badge.

Pour envoyer une notification, un provider (une application serveur en général) doit en premier lieu envoyer la notification à l’Apple Push Notification Service qui se chargera à son tour de diffuser la notification aux terminaux concernés.

La notification est composée d’un token (identifiant unique d’un terminal) et d’un payload (contenu de la notification).

Simple notification APNS

L’APNS propose en complément de l’envoi de notifications, un flux feedback d’informations permettant de connaître la liste des terminaux pour lesquels les notifications n’ont pu être délivrées de façon répétée (généralement, lorsque l’application a été désinstallée).

Pour qu’une application iOS soit en mesure de recevoir des notifications, elle doit en premier lieu fournir à l’application serveur (celle qui va envoyer les notifications aux serveurs Apple) toutes les informations nécessaires notamment son token d’identification. Cette opération peut-être réalisée, par exemple, via un simple appel HTTP.

Séquence d'enregistrement

API Java de connexion à l’APNS

De nombreux projets permettent de dialoguer avec l’APNS via différents langages de programmation. Actuellement deux implémentations existent pour le langage Java :

Historiquement, l’implémentation javapns est apparue avant java-apns. Cependant nous choisirons d’utiliser la librairie java-apns qui a pour avantage de proposer des fonctionnalités complètes (gestion de pool de connections, capacité de reconnexion, …), ainsi qu’une API élégante et différentes facilités d’écriture de tests unitaires.

Les endpoints Camel

Le développement d’un endpoint Apache Camel implique d’implémenter une ou plusieurs des méthodes suivantes selon les besoins :

Méthode Description
createProducer() Crée un producer permettant d’envoyer des messages à un endpoint
createConsumer() Crée un consumer implémentant le pattern Event Driven Consumer pour consommer des messages depuis un endpoint
createPollingConsumer() Crée un consumer implémentant le Polling Consumer pour consommer des messages depuis un endpoint

L’Event Driven Consumer

Solution Event Driven Consumer

Ce modèle événementiel de consommation des messages correspond au modèle de consommation par défaut des messages par les composants Camel.

Le Polling Consumer

Solution Polling Consumer

Le polling consumer propose 3 types de méthodes:

Méthode Description
receive() Attend qu’un échange soit disponible et le retourne (potentiellement indéfiniment)
receive(long) Attend un échange jusqu’à un timeout défini. Renvoie null si aucun échange n’a été reçu dans le temps imparti
receiveNoWait() Tente de recevoir un message sans attendre de timeout et retourne null si aucun échange n’est disponible

Le composant camel-jms implémente cette notion de polling-consumer pour s’intégrer à Apache Camel.

Générer un squelette de composant

Partir de zéro pourrait s’avérer compliqué. Heureusement le projet Apache Camel met à disposition l’archétype Maven: camel-artefact-component.

mvn archetype:create 
-DarchetypeGroupId=org.apache.camel.archetypes 
-DarchetypeArtifactId=camel-archetype-component 
-DarchetypeVersion=2.3.0 
-DgroupId=org.apache.camel 
-DartifactId=camel-apns

L’exécution de la ligne de commande précédente va créer un squelette de composant sur lequel s’appuyer pour développer notre composant:

Contenu généré par l'archetype Maven

L’archétype va générer la structure nécessaire au développement du composant Camel. Cependant il sera nécessaire de personnaliser le composant nouvellement créé pour qu’il corresponde au nommage souhaité :

  • ‘META-INF/services/<PACKAGE_NAME>/direct’ devra être renommé selon le scheme de l’URI de votre composant (Dans notre cas: ‘apns’).
  • Les différentes classes générées seront préfixées par ‘Apns’ plutôt que ‘Direct’.

Il est possible de supprimer les classes qui ne seraient pas utilisées dans le cas où le composant serait uniquement destiné à consommer des messages ou à bien en produire.

Après renommage, le résultat obtenu doit être le suivant :

Vue composant APNS

Importer son composant dans Eclipse

Pour cela, il est possible d’utiliser la commande suivante:

mvn eclipse:eclipse

Le fichier pom.xml

Il est conseillé d’hériter du projet parent camel-parent:

	 
<parent>
	<groupid>org.apache.camel</groupid>
	<artifactid>camel-parent</artifactid>
	<version>2.4.0</version>
</parent>

Le composant camel-parent déclare en effet un certain nombre de dépendances nécessaires, ainsi que le type bundle qui permet d’OSGifier son composant. Ceci permettra aux utilisateurs/développeurs de le déployer dans un conteneur OSGi, tel qu’Apache ServiceMix.

Nous allons donc déclarer le packaging du composant, ainsi que différentes propriétés nécessaires à l’OSGificiation comme suit:

<packaging>bundle</packaging>
...
<properties>
	...
	<!-- OSGi bundles properties -->
	<camel .osgi.import.pkg><strong></strong></camel>
	<camel .osgi.private.pkg>!</camel>
	<camel .osgi.export>${camel.osgi.export.pkg}*;version=${camel.osgi.export.version}</camel>
	<camel .osgi.export.version>${project.version}</camel>
	<camel .osgi.import>${camel.osgi.import.pkg}</camel>
	<camel .osgi.symbolic.name>${groupId}.${artifactId}</camel>
</properties>

Il est également nécessaire de déclarer les dépendances Camel dont nous aurons besoin, ainsi que les dépendances nécessaires à l’implémentation du composant:

<dependencies>
	...
	<!-- Camel -->
	<dependency>
		<groupid>org.apache.camel</groupid>
		<artifactid>camel-core</artifactid>
		<version>${camel.version}</version>
	</dependency>
	<dependency>
		<groupid>org.apache.camel</groupid>
		<artifactid>camel-spring</artifactid>
		<version>${camel.version}</version>
	</dependency>
	<dependency>
		<groupid>org.apache.camel</groupid>
		<artifactid>camel-test</artifactid>
		<version>${camel.version}</version>
		<scope>test</scope>
	</dependency>
	...
	<!-- APNS -->
	<dependency>
		<groupid>com.notnoop.apns</groupid>
		<artifactid>apns</artifactid>
		<version>${apns.version}</version>
		<exclusions>
			<exclusion>
				<groupid>ch.qos.logback</groupid>
				<artifactid>logback-classic</artifactid>
			</exclusion>
		</exclusions>
	</dependency>
	...
</dependencies>

Le projet Apache Camel propose le plugin camel-maven-plugin que nous allons déclarer dans notre fichier pom. Celui-ci permet de lancer en ligne de commande une instance standalone d’Apache Camel et de démarrer les routes qui sont déclarées dans le classpath via le fichier Spring suivant: ‘META-INF/spring/camel-context.xml’.

<!-- allows the route to be ran via 'mvn camel:run' -->
<plugin>
	<groupid>org.apache.camel</groupid>
	<artifactid>camel-maven-plugin</artifactid>
	<version>${camel.version}</version>
</plugin>

Plusieurs entrées repository et pluginReposity doivent également être déclarées dans le pom afin que Maven puisse importer différentes dépendances et plugins nécessaires à notre projet:

<repositories>
	<repository>
		<id>open.iona.m2</id>
		<name>IONA Open Source Community Release Repository</name>
		<url>http://repo.open.iona.com/maven2</url>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
		<releases>
			<enabled>true</enabled>
		</releases>
	</repository>
	<repository>
		<id>open.iona.m2-snapshot</id>
		<name>IONA Open Source Community Snapshot Repository</name>
		<url>http://repo.open.iona.com/maven2-snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
		<releases>
			<enabled>false</enabled>
		</releases>
	</repository>
	<!-- java-apns repository -->
	<repository>
		<id>notnoop-repos</id>
		<url>http://notnoop.github.com/m2-repo</url>
	</repository>
	...
	<repository>
		<id>apache.incubating.releases</id>
		<name>Apache Incubating Release Distribution Repository</name>
		<url>http://people.apache.org/repo/m2-incubating-repository</url>
	</repository>
</repositories>
<pluginrepositories>
	<pluginrepository>
		<id>open.iona.m2</id>
		<name>IONA Open Source Community Release Repository</name>
		<url>http://repo.open.iona.com/maven2</url>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
		<releases>
			<enabled>true</enabled>
		</releases>
	</pluginrepository>
	<pluginrepository>
		<id>open.iona.m2-snapshot</id>
		<name>IONA Open Source Community Snapshot Repository</name>
		<url>http://repo.open.iona.com/maven2-snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
		<releases>
			<enabled>false</enabled>
		</releases>
	</pluginrepository>
	<pluginrepository>
		<id>maven-repository.dev.java.net</id>
		<name>Java.net Maven 2 Repository</name>
		<url>http://download.java.net/maven/2</url>
	</pluginrepository>
</pluginrepositories>

Conclusion

Nous avons vu dans cette première partie comment initier le développement d’un composant Camel à l’aide de l’archétype Maven camel-archetype-component.

Dans un prochain billet, nous verrons comment implémenter les différentes classes d’un composant Camel. Puis nous conclurons dans une troisième et dernière partie, par la présentation des méthodes permettant de tester notre composant afin de fournir un livrable de qualité.

Liens utiles

Le site google code du composant camel-apns présenté dans cet article:

Parties suivantes de l’article :