Développez votre première application multi-bundles avec S2AP

Suite à ce billet : Vos premiers pas avec SpringSource Application Platform et eclipse où j’avais montré comment configurer le tooling STS avec Eclipse ainsi que la création et le déploiement d’une application exemple, je vais montrer dans ce billet comment développer une application multi-tiers s’étalant sur plusieurs bundles.

1. Vue d’ensemble

L’application que je vais utiliser comme exemple est simpliste : elle ne sert qu’à afficher une liste de personnes (peu importe comment cette liste est retrouvée) dans une page web.

Seulement, histoire de faire propre, je vais découper cette application en 4 bundles:

  1. domain: C’est un bundle qui définit les objets métier (un seul dans notre cas: Person)
  2. service-api: C’est un bundle qui définit les interfaces (contrats) de la couche métier
  3. service-impl: C’est un bundle qui définit les implémentations des services mais aussi les exporte en tant que services OSGi qui seront consommés par le dernier bundle.
  4. web-frontend: C’est un bundle qui définit le front-end web de l’application et qui consomme les services exposés par service-impl

N.B.: Je suppose tout au long de ce billet que le serveur S2AP ainsi que le tooling Eclipse correspondant est déjà en place comme je le montre ici.

2. Créer le bundle domain

Dans Eclipse, lancez le wizard “New Bundle Project” :

New Bundle Project

Saisissez un nom parlant pour ce bundle (djo.s2ap.demo.domain pour moi) et cliquez sur Next.
Là, et c’est une nouveauté dans le tooling S2AP pour Eclipse (sur une suggestion de ma part, merci à Christian Dupuis qui l’a implémenté), il est possible de choisir le type du bundle (None ou Web) :

Bundle Personality

Choissisez None et validez.
Créer un package dans le dossier src (j’utilise habituellement le nom du projet comme package de base), et créez une classe Person (forcément, mon type de données préféré :) )

package djo.s2ap.demo.domain; 
 
public class Person { 
  private String name; 
  private int age; 
 
  public Person(String name, int age) { 
    super(); 
    this.name = name; 
    this.age = age; 
  } 
 
  public String getName() { 
    return name; 
  } 
 
  public void setName(String name) { 
    this.name = name; 
  } 
 
  public int getAge() { 
    return age; 
  } 
 
  public void setAge(int age) { 
    this.age = age; 
  } 
 
}

Je vais me contenter de cette classe comme mon domaine.

Il faut ensuite exporter le package de cette classe pour qu’elle soit visible aux autres bundles.
Pour ce faire, localisez le fichier src/META-INF/MANIFEST.MF et double-cliquez la dessus, ce qui ouvre l’éditeur de manifest de STS (encore une fonctionnalité proposé par l’auteur de ce billet (moi) et implémentée par l’equipe STS (re-merci) !).
Dans l’éditeur multi-pages qui se lance, localisez la page “Runtime” et activer la.
A gauche, vous trouverez une liste présentant les packages exportés par le bundle en question. Cliquez sur le bouton “Add” et dans la fenêtre qui s’affiche, sélectionnez l’unique package présent (djo.s2ap.demo.domain).

Sinon, il est toujours possible de travailler directement sur le manifest en utilisant le contenu suivant:

Manifest-Version: 1.0 
Bundle-Version: 1.0.0 
Bundle-Name: Domain Bundle 
Bundle-ManifestVersion: 2 
Bundle-SymbolicName: djo.s2ap.demo.domain 
Export-Package: djo.s2ap.demo.domain

Voilà, le premier bundle est prêt.

3. Créer le bundle service-api

Comme énoncé plus haut, ce bundle va juste définir les contrats des services (sous forme d’interfaces). C’est LE pattern OSGi à mon avis, i.e. séparer l’interface de l’implémentation dans des bundles différents, histoire de pouvoir changer (mettre à jour, corriger des bugs, peaufiner, etc.) l’implémentation séparément de son interface mais aussi pour éviter que le consommateur d’un service ne dépende de son implémentation.

Dans le cadre de cette application exemple, je vais me contenter d’un seul service exposant une seule fonctionnalité qui est de récupérer une liste de personnes.

Commencez par créer un autre bundle nommé “djo.s2ap.demo.service.api” dans mon cas (même procédure que pour le bundle domain, choisissez “None” comme personality).
Ce bundle aura besoin de voir la classe Person du bundle domain.
Or, justement, j’ai exporté le package contenant cette classe. Il ne reste plus qu’à importer ce package dans le bundle service.api.

Pour ce faire, localisez et double-cliquez sur le fichier “src/META-INF/MANIFEST.MF” du bundle service.api.
Dans l’éditeur multi-pages qui s’affiche, activez la page “Dependencies”.
Dans la liste à gauche (Import Package”, cliquez sur Add, et localisez le package “djo.s2ap.demo.domain” contenant la classe Person (utilisez le filtre):

Import Package

Sélectionnez ce package et validez.
Ainsi, la classe Person devient visible dans le second bundle.

Créez ensuite un package “djo.s2ap.demo.service.api” avec une interface IPersonRepository dont voici le code:

package djo.s2ap.demo.service.api; 
 
import java.util.List; 
 
import djo.s2ap.demo.domain.Person; 
 
public interface IPersonRepository { 
  List<Person> getPersonsList(); 
} 

Pour finir, il faut exporter le package qui définit cette interface car l’implémentation de ce service aura besoin d’y accéder.
Donc, comme montré plus haut, exportez le package “djo.s2ap.demo.service.api” en utilisant soit l’editeur graphique du manifest ou en jouant directement sur le manifest.

4. to be continued

Faute d’espace et de temps, je vais m’arrêter là pour ce billet et je finirais la chose bientôt dans un autre billet.

Toujours faute de temps, mais aussi à cause du fait que j’ai abandonné S2DMS, j’arrive pas à finir le second volet :(
J’espère au moins pouvoir parler des raisons du pourquoi j’ai abandonné cette plateforme (1 raison plus précisément, la notion de PAR)

—-

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: