CDI mis en pratique avec Seam Social et Weld OSGI

1,882 views
1,799 views

Published on

Cette présentation est le support d'une Université faite à Devoxx par Mathieu Ancelin (Serli) et moi même. Elle propose une exploration pratique des fonctionnalités de CDI et de quelques extensions Seam 3 à travers le module Seam Social (solution d'interconnexion aux réseaux sociaux).
Les sujets suivants seront abordés :

Retour rapide sur la spécification CDI

Création et manipulation de Bean CDI

Création d'extension CDI

Utilisation d'événements CDI

Création de décorateurs et intercepteurs CDI

Extension de CDI pour une approche modulaire grace à Weld OSGI

Création d'une appli web cliente se connectant à plusieurs services (Twitter, Facebook LinkedIn)

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,882
On SlideShare
0
From Embeds
0
Number of Embeds
41
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • Rappeler que Seam 3 != Seam 2 et que c’était une erreur de garder le nom de Seam\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • les encodages sont fait en UTF-8 et percent encoding\nL’algorithme de signature est HMAC-SHA1\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • on doit être à 1h40 max\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Il doit nous rester une heure ici !!!\n
  • \n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • Modulaire va arriver avec le JDK8, il va falloir s’y habituer\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • CDI mis en pratique avec Seam Social et Weld OSGI

    1. 1. CDI mis en pratique avec Seam Social et Weld OSGI par Mathieu Ancelin @TrevorReznik et Antoine Sabot-Durand @antoine_sd 1
    2. 2. Antoine Sabot-DurandExpert Java EE16 ans d’expérienceJava & OSS : Leader sur Seam Social Commiter Apache Deltaspike Membre de l’EG CDI 1.1(JSR 346) @antoine_sd 2
    3. 3. Ippon technologiesSSII parisienne spécialisée en JavaDomaines de compétence Java EE Portail SOA RIA e-commerce MobilitéPartenaire Devoxx.Venez sur notre Stand ! 3
    4. 4. Mathieu ANCELINDéveloppeur @SERLIJava & OSS JOnAS, GlassFish, Weld, etc ... Membre de l’équipe du Poitou-Charentes JUG Membre de l’expert group CDI 1.1 (JSR-346)@TrevorReznik 4
    5. 5. SERLISociété de conseil et d’ingénierie du système d’information65 employés80% de business JavaContribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346www.serli.com @SerliFr 5
    6. 6. SERLISociété de conseil et d’ingénierie du système d’information65 employés80% de business JavaContribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346www.serli.com @SerliFr 5
    7. 7. Avant de commencer#DevoxxFR #CDIPratique 6
    8. 8. AbstractLa plupart des présentations CDI restent théoriquesNous allons vous montrer comment CDI a été mis en pratique à travers lefonctionnement du module Seam SocialVous verrez également comment CDI peut être modularisé grâce à WeldOSGINous profiterons également de ces 3 heures pour monter une petiteapplication sociale en CDI et JSF / Primefaces et la même utilisant TwitterBootstrap 7
    9. 9. Concepts généraux 8
    10. 10. Historique CDISpring Seam CDI Guice @Inject 9
    11. 11. Messaging Application Client Container CDI dans Java EE Web Browser SOA Client Tier JSF 2.0 CDI est une technologie d’intégration qui enrichi aussi bien des POJO que des EJB JAX-WS JAX-RS JMS Servlet 3.0 Web Tier Il a vocation à servir de «glue» entre les différentes parties de la stack Java EE EJB Container Managed Bean (POJO) C’est la première technologie qui permet d’étendre Java EE de manière portable et naturelle Service Tier CDI JTA JPA JAAS JAXB JCA Serveur Java EE 6 10
    12. 12. Seam SocialSeam Social est un module CDI pour faciliter l’utilisation des réseauxsociauxInspiré par Spring Social, il propose un noyau très différent tirant parti desspécificités CDILes binding des API des réseaux sociaux, en revanche sont pour l’instant desforks de ceux de Spring SocialConnecteurs out of the box 11
    13. 13. Inside Seam Social Seam Social repose sur des bibliothèques tierces comme : Scribe-java pour le client Rest et OAuth Jackson pour le mapping JSON JBoss Solder, helpers CDI 12
    14. 14. Jackson@JsonIgnoreProperties(ignoreUnknown = true)@SuppressWarnings("unused")abstract class TwitterProfileMixin { @JsonCreator L’un des frameworks les plus performants pour TwitterProfileMixin(@JsonProperty("id") String id, @JsonProperty("screen_name")String screenName, parser du JSON @JsonProperty("name") String name, @JsonProperty("url") String url, @JsonProperty("profile_image_url") String profileImageUrl,@JsonProperty("description") String description, Jackson permet également de mapper du JSON @JsonProperty("location") String location, @JsonProperty("created_at") @JsonDeserialize(using = sur des classes javaTimelineDateDeserializer.class) Date createdDate) { } Pour ça il peut utiliser des annotations JAXB ou @JsonProperty("notifications") ses propres annotations private boolean notificationsEnabled; @JsonProperty("lang") En plus Jackson propose la notion de Mixin qui private String language; permet de déporter les annotations sur une @JsonProperty("statuses_count") private int statusesCount; classe dédiée et de laisser la classe d’origine... propre. 13
    15. 15. Jackson : Utilisation d’un MixinPojo PojoMixin Texte Pour le Pojo que l’ont veut binder, il faut créer une classe abstraite : un Mixin Ce mixin comporte les annotations Jackson qui seront utilisées pour associé le JSON au pojo Module Un module Jackson est nécessaire pour créer l’association Jackson 14
    16. 16. Concepts et technos utilisés par les réseaux sociaux 15
    17. 17. La big pictureTous les réseaux sociaux reposent sur REST comme protocole d’échangeLes données transmises sont au format JSON et certains proposent XML enoptionEnfin, la sécurisation (encryption et authentification) passe par le protocoleOAuth. 16
    18. 18. OAuthOAuth est un protocole pour déléguer une autorisation à l’utilisation d’unservice donné (autoriser sans partager ses données d’accès avec l’entité à quion délègue l’accès au service)Développé par Twitter, Magnolia puis Google, il est normalisé par l’IETF en avril2010 via la RFC 5849La version 2.0 plus simple d’utilisation est en cours de standardisation mais déjàutilisée par certains acteurs (Facebook, Google, Microsoft)Tous les Réseaux Sociaux s’appuient sur Oauth 1.0a ou 2.0Pour utiliser OAuth on doit commencer par déclarer une application sur leservice concerné. Celui-ci vous délivrera une Consumer_Key (clé asymétrique) 17
    19. 19. Le cycle OAuth 1.0a Service tiers (OAuth)Client Serveur de l’application 18
    20. 20. Le cycle OAuth 1.0a Service tiers (OAuth) Client 1 Le client demandeune ressource sur le service tiers Serveur de l’application 18
    21. 21. Le cycle OAuth 1.0a Service tiers (OAuth) Client L’application demande un 1 request Token (relatif à 2 l’application déclarée) au service et envoie une url de callback à associer au token Le client demandeune ressource sur le service tiers Serveur de l’application 18
    22. 22. Le cycle OAuth 1.0a Service tiers (OAuth) Le service retourne le token Client 3 L’application demande un 1 request Token (relatif à 2 l’application déclarée) au service et envoie une url de callback à associer au token Le client demandeune ressource sur le service tiers Serveur de l’application 18
    23. 23. Le cycle OAuth 1.0a Service tiers (OAuth)L’application 4 redirige le client sur lapage de login Le service retourne le token du service Client 3 L’application demande un 1 request Token (relatif à 2 l’application déclarée) au service et envoie une url de callback à associer au token Le client demande une ressource sur le service tiers Serveur de l’application 18
    24. 24. Le cycle OAuth 1.0a Une fois connecté le service Service tiers (OAuth) redirige le client vers l’URL de callback avec un code de vérificationL’application 4 redirige le 5 client sur lapage de login Le service retourne le token du service Client 3 L’application demande un 1 request Token (relatif à 2 l’application déclarée) au service et envoie une url de callback à associer au token Le client demande une ressource sur le service tiers Serveur de l’application 18
    25. 25. Le cycle OAuth 1.0a Une fois connecté le service Service tiers (OAuth) redirige le client vers l’URL de callback avec un code de vérificationL’application 4 redirige le 5 client sur lapage de login Le service retourne le token du service Client 3 L’application demande un 1 request Token (relatif à 2 l’application déclarée) au 6 service et envoie une url de callback à associer au token Le client demande une ressource sur le A l’aide du code et du Token, le service tiers service demande un Access Token Serveur de l’application 18
    26. 26. Le cycle OAuth 1.0a Une fois connecté le service Service tiers (OAuth) redirige le client vers l’URL de callback avec un code de vérification Le service retourne l’access tokenL’application 4 redirige le 5 client sur lapage de login 7 Le service retourne le token du service Client 3 L’application demande un 1 request Token (relatif à 2 l’application déclarée) au 6 service et envoie une url de callback à associer au token Le client demande une ressource sur le A l’aide du code et du Token, le service tiers service demande un Access Token Serveur de l’application 18
    27. 27. JSON 1: { 2: "firstName": "John", 3: "lastName" : "Smith", 4: "age" : 25, 5: "address" : 6: { 7: "streetAddress": "21 2nd Street", Javascript Object Notation : format de 8: 9: "city" "state" : "New York", : "NY", structuration de données provenant de10: "postalCode" : "10021" Javascript et adopté comme standard d’échange11: },12: "phoneNumber": dans la quasi totalités des services en ligne13: [14: { Comparable à XML mais sans XSD15: "type" : "home",16: "number": "212 555-1234" Tous les langages disposent de bibliothèques17:18: }, { pour exploiter / générer du JSon19: "type" : "fax",20: "number": "646 555-4567"21: }22: ]23: } 19
    28. 28. Composants principaux de Seam Social 20
    29. 29. Objectifs de Seam Social Fournir un socle générique pour construire des API d’accès aux réseaux sociaux La connexion et l’identification sont génériques pour fournir un moyen standard de s’authentifier Découverte dynamique de nouveaux modules (le socle reconnait automatiquement un nouveau connecteur) Fourniture de services haut niveau (bindings et appels) vers les services en ligne 21
    30. 30. «interface» Les classes principales OAuthSession «interface» OAuthService+getRequestToken()+setRequestToken(OAuthToken) +getAccessToken()+getAccessToken() +getAuthorizationUrl() +getVerifier() «interface»+setAccessToken(OAuthToken)+getVerifier() +initAccessToken() SocialNetworkServicesHub+setVerifier(String) +sendSignedRequest(RestVerb, String)+setUserProfile(UserProfile) +sendSignedRequest(RestVerb, String, Map)+getUserProfile() +sendSignedRequest(RestVerb, String, String, Object)+getServiceQualifier() +setVerifier(String)+isConnected() +setAccessToken(String, String) AbstractSocialNetworkService+getName() +setAccessToken(OAuthToken) +sendSignedXmlRequest(RestVerb, String, String) +getSession() +buildUri(String, String, String) +requireAuthorization() +buildUri(String, Map) +sendSignedRequest(OAuthRequest) +getApiRootUrl() +buildUri(String) +buildUri(String, Object) «interface» «interface»SocialNetworkServicesHub OAuthProvider+getMyProfile()+getSession() +getRequestToken()+resetConnection() +getAccessToken(OAuthToken, String)+isConnected() +signRequest(OAuthToken, OAuthRequest)+configureService(OAuthService) +getVersion()+getVerifierParamName() +getAuthorizationUrl(OAuthToken) +requestFactory(RestVerb, String) +tokenFactory(String, String) 22
    31. 31. Bootstraping Social @Twitter @ApplicationScoped Grace à une extension CDI incluse dans Solder, on créé 4 beans portant @OAuthApplication(apiKey = "FQzlQC49UhvbMZoxUIvHTQ", apiSecret = "VQ5CZHG4qUoAkUUmckPn4iN4yyjBKcORTW0wnok4r1k", callback = "http://localhost:8080/social-web-client/callback.jsf") @Produces public TwitterServicesHub twitterProducer(TwitterServicesHub service) { le même qualifier et le scope de son return service; } choix lié à celui du producer@Twitter @ApplicationScoped «interface» @Twitter @SessionScoped OAuthService «interface» OAuthSession @Twitter @ApplicationScoped+getAccessToken() «interface»+getAuthorizationUrl() +getRequestToken() OAuthProvider+getVerifier() +setRequestToken(OAuthToken)+initAccessToken() +getAccessToken()+sendSignedRequest(RestVerb, String) +getRequestToken() +setAccessToken(OAuthToken)+sendSignedRequest(RestVerb, String, Map) +getAccessToken(OAuthToken, String) +getVerifier()+sendSignedRequest(RestVerb, String, String, Object) +signRequest(OAuthToken, OAuthRequest) +setVerifier(String)+setVerifier(String) +getVersion() +setUserProfile(UserProfile)+setAccessToken(String, String) +getAuthorizationUrl(OAuthToken) +getUserProfile()+setAccessToken(OAuthToken) +requestFactory(RestVerb, String) +getServiceQualifier()+sendSignedXmlRequest(RestVerb, String, String) +tokenFactory(String, String) +isConnected()+getSession() +getName()+requireAuthorization()+sendSignedRequest(OAuthRequest) 23
    32. 32. Etendre Seam SocialPour créer un nouveau module (supporter un nouveau réseau social) il faut : S’assurer que Scribe-Java propose un connecteur vers ce service ou créer ce connecteur (une classe) Etendre AbstractSocialNetworkService pour fournir le socle aux API du service Créer un Qualifier (annotation) portant la meta annotation @ServiceRelated Implementer SocialNetworkService Hub pour les services génériques.Il ne reste plus qu’à coder les bindings JSON et API. 24
    33. 33. DEMO Socializer Primefaces 25
    34. 34. CDI 26
    35. 35. CDILa meilleur spec. de Java EE 6 (la plus cool) #annotationsEverywhere #noXml TypesafeAucune limite à ce que vous pouvez faire avec CDI Si vous pouvez l’imaginer, vous pouvez le faire Extensions portables standard :-)JBoss Weld en est l’implémentation de référence plutôt mature, très bonne communauté Deux autres implémentations : Apache Open WebBeans Caucho CandiLimité à Java EE 6 ? et bien, pas forcément ... 27
    36. 36. Environnements for CDI/WeldIl est possible de bootstraper Weld très simplement en dehors de JavaEE 6 à priori, vous pouvez le bootstraper n’importe où :-)Weld-Servlet Jetty Tomcat 6/7 Weld-SE Bonne vieilles applications desktop 28
    37. 37. Le BeanEn Java EE 6 tout est Managed Bean 29
    38. 38. Le Bean Pensez au fichier beans.xml 30
    39. 39. Le BeanEn Java EE 6 tout est Managed Bean le managed bean est le composant de base il a un cycle de vie il est interceptable il est injectable accessible via JNDI 31
    40. 40. Injection de dépendance@Inject 32
    41. 41. Injection de dépendancepublic class HelloService {    public String hello() {        return "Hello World!";    }} 33
    42. 42. Injection de dépendancepublic class MyBean extends Application {    private HelloService service;    @Inject    public MyBean(HelloService service) {        this.service = service;    }    public void displayHello() {        display( service.hello();    }} 34
    43. 43. Injection de dépendancepublic class MyBean extends Application {    private HelloService service;    @Inject    public void setService(HelloService service) {        this.service = service;    }    public void displayHello() {        display( service.hello();    }} 35
    44. 44. Injection de dépendancepublic class MyBean extends Application {    @Inject HelloService service;    public void displayHello() {        display( service.hello();    }} 36
    45. 45. Injection de dépendancepublic interface HelloService {    public String hello();}public class FrenchHelloService implements HelloService {    public String hello() {        return "Bonjour tout le monde!";    }}public class EnglishHelloService implements HelloService {    public String hello() {        return "Hello World!";    }} 37
    46. 46. Les qualifierspublic class MyBean extends Application {    @Inject @French HelloService service;    public void displayHello() {        display( service.hello();    }}public class MyBean extends Application {    @Inject @English HelloService service;    public void displayHello() {        display( service.hello();    }} 38
    47. 47. Les qualifiers@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface French {}@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface English {} 39
    48. 48. Les qualifiers@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface French {}@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface English {} 40
    49. 49. Les qualifiers@Frenchpublic class FrenchHelloService implements HelloService {    public String hello() {        return "Bonjour tout le monde!";    }}@Englishpublic class EnglishHelloService implements HelloService{    public String hello() {        return "Hello World!";    }} 41
    50. 50. Les qualifiers@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface Language {    Languages value(); @Nonbinding String description() default "";    public enum Languages {        FRENCH, ENGLISH    }} 42
    51. 51. Les qualifiers@Language(FRENCH)public class FrenchHelloService implements HelloService {    public String hello() {        return "Bonjour tout le monde!";    }}@Language(ENGLISH)public class EnglishHelloService implements HelloService {    public String hello() {        return "Hello World!";    }} 43
    52. 52. Les qualifierspublic class MyBean extends Application {    @Inject @Language(ENGLISH) HelloService service;    public void displayHello() {        display( service.hello();    }}public class MyBean extends Application {    @Inject @Language(FRENCH) HelloService service;    public void displayHello() {        display( service.hello();    }} 44
    53. 53. Les qualifierspublic class MyBean extends Application {    @Inject @French HelloService service;}@French @Console @Securedpublic class FrenchHelloService implements HelloService {} 45
    54. 54. Les qualifierspublic class MyBean extends Application {    @Inject @French @Console HelloService service;}@French @Console @Securedpublic class FrenchHelloService implements HelloService {} 46
    55. 55. Les qualifierspublic class MyBean extends Application {    @Inject @French @Console @Secured HelloService service;}@French @Console @Securedpublic class FrenchHelloService implements HelloService {} 47
    56. 56. Les qualifierspublic class MyBean extends Application {    @Inject @French @Console @Secured HelloService service;}@French @Securedpublic class FrenchHelloService implements HelloService {} 48
    57. 57. Les qualifierspublic class MyBean extends Application {    @Inject @French @Console @Secured HelloService service;}@French @Securedpublic class FrenchHelloService implements HelloService {} 48
    58. 58. Injection programmatiquepublic class MyBean extends Application {    @Inject Instance<HelloService> service;    public void displayHello() {        display( service.get().hello() );    }} 49
    59. 59. Injection programmatiquepublic class MyBean extends Application {    @Inject Instance<HelloService> service;    public void displayHello() {        if (!service.isUnsatisfied()) {            display( service.get().hello() );        }    }} 50
    60. 60. Injection programmatiquepublic class MyBean extends Application {    @Any @Inject Instance<HelloService> services;    public void displayHello() {        display(            service.select( new AnnotationLiteral()<French> {})                .get() );    }} 51
    61. 61. Les contextesGestion du cycle de vie des beans choix du moment de la création et de la destruction des beans ‘un singleton pour un contexte donné’Contexte requête, session, conversation, application, singletonPossibilité de créer des scopes personnalisés via les extensions 52
    62. 62. Les contextes@SessionScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 53
    63. 63. Les contextes@ApplicationScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 54
    64. 64. Les contextes@ApplicationScoped ! !!public class CartBean { IL A    public void addItem(Item item) { F ...    }} 54
    65. 65. Les contextes@ConversationScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 55
    66. 66. Les contextes@ThreadScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 56
    67. 67. Les contextes@HourScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 57
    68. 68. Les contextes@RandomScopedpublic class CartBean {    public void addItem(Item item) { ...    }} 58
    69. 69. Les décorateurs@Decoratorpublic class HelloDecorator implements HelloService {    @Inject @Delegate HelloService service;    public String hello() {        return service.hello() + "-decorated";    }} @Inject HelloService service; 59
    70. 70. Les décorateurs@Decoratorpublic abstract class HelloDecorator implements HelloService{    @Inject @Delegate HelloService service;    public String hello() {        return service.hello() + "-decorated";    }} @Inject HelloService service; 60
    71. 71. Les décorateurs<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://java.sun.com/xml/ns/javaee"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">  <decorators>    <class>foo.bar.HelloDecorator</class>  </decorators></beans> 61
    72. 72. Les évènements@Inject Event<String> evt;...evt.fire("Bonjour");@Inject Event<Post> evt;...evt.fire( new Post( "Mathieu ANCELIN ", "Bonjour", )); 62
    73. 73. Les évènementspublic void receiveEvt(@Observes String evt) {    System.out.println("Reçut : " + evt);} public void receiveEvt(@Observes Post evt) {     System.out.println("Reçut : " + evt.message()); } 63
    74. 74. Les évènements@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER})public @interface English {} 64
    75. 75. Les évènements @Inject @English Event<String> evt; ... evt.fire("Hello");public void receiveEvt(@Observes @English String evt) {    System.out.println("Received : " + evt);} 65
    76. 76. CDI en pratique dans Seam Social Visite guidée 66
    77. 77. Les extensions CDI 67
    78. 78. Extensions CDI pourquoi faire ?Une extension CDI permet : De créer des Beans (fichier de configuration) ou des points d’injection modifier des beans ou des points d’injection Annuler la création de beansD’une manière générale inventorierl’ensembles de lécosystème CDI del’application, le modifier ou l’enrichir. 68
    79. 79. Pour comprendre les extensionsUne fois l’application lancée le BeanManagerest en lecture seule (pas de création de Beanau runtime)Ne pas confondre Bean (définition) avecInstance de BeanNos extensions seront donc exécutées audémarrage de l’application et devront influersur le contenu du BeanManager et des futursbeansLes extensions peuvent aussi devenir desBeans (avec quelques restrictions) 69
    80. 80. Cycle de vie CDI Deploy Process Process Before UndeployApplication Beans Producers Shutdown Application ProcessBefore Bean Process Application Observer Discovery Injection Taget Running Methods After Scan Process After Bean Deployment Archive Anotated Types Discovery Validation 70
    81. 81. Pour Faire une Extension CDICréer une classe qui implémente Extension avec unconstructeur sans paramètresY placer une ou plusieurs méthodes avec un observer surles événements du cycle de vie CDI pour intervenir sur lecontenu du bean managerAjouter dans le classpath le fichierMETA-INF/services/javax.enterprise.inject.spi.Extensiondans lequel on ajoutera le nom qualifié de la classed’extension 71
    82. 82. Exemple simple : @Veto <X> void processAnnotatedType(@Observes final ProcessAnnotatedType<X> pat, BeanManager beanManager) {        final AnnotatedType<X> annotatedType = pat.getAnnotatedType();        final Class<X> javaClass = annotatedType.getJavaClass();        final Package pkg = javaClass.getPackage();        // Support for @Veto        if (annotatedType.isAnnotationPresent(Veto.class) || (pkg != null &&pkg.isAnnotationPresent(Veto.class))) {            pat.veto();            log.info("Preventing " + javaClass + " from being installed as bean due to @Veto annotation");            return;        }} 72
    83. 83. Exemple simple : @Veto <X> void processAnnotatedType(@Observes final ProcessAnnotatedType<X> pat, BeanManager beanManager) {        final AnnotatedType<X> annotatedType = pat.getAnnotatedType();        final Class<X> javaClass = annotatedType.getJavaClass();        final Package pkg = javaClass.getPackage();        // Support for @Veto        if (annotatedType.isAnnotationPresent(Veto.class) || (pkg != null &&pkg.isAnnotationPresent(Veto.class))) {            pat.veto();            log.info("Preventing " + javaClass + " from being installed as bean due to @Veto annotation");            return;        }} 72
    84. 84. Demo Extension 73
    85. 85. Et OSGi ?Seam Social est un projet open source Et nous comptons sur vous pour créer des modules Seulement ajouter un module nécessite de redéployer l’application Comment faire pour charger un module à chaud ?OSGi arrive à la rescousse pour résoudre ce problème 74
    86. 86. Concepts liés à OSGi 75
    87. 87. OSGiPlateforme modulaire et dynamique pour JavaTrès stable et puissante mais APIs vieillottes ... Plateforme Java 76
    88. 88. OSGiPlateforme modulaire et dynamique pour JavaTrès stable et puissante mais APIs vieillottes ... Module Plateforme Java 76
    89. 89. OSGiPlateforme modulaire et dynamique pour JavaTrès stable et puissante mais APIs vieillottes ... Lifecycle Module Plateforme Java 76
    90. 90. OSGiPlateforme modulaire et dynamique pour JavaTrès stable et puissante mais APIs vieillottes ... Service Lifecycle Module Plateforme Java 76
    91. 91. OSGiPlateforme modulaire et dynamique pour JavaTrès stable et puissante mais APIs vieillottes ... Bundles Service Lifecycle Module Plateforme Java 76
    92. 92. Modules / Bundles 77
    93. 93. Modules / Bundles manifest manifest 77
    94. 94. Modules / Bundles Bundle-SymbolicName: com.sample.appBundle-SymbolicName: com.foo.bar manifest manifest 77
    95. 95. Modules / Bundles Bundle-SymbolicName: com.sample.appBundle-SymbolicName: com.foo.bar manifest manifest Export-Package: com.sample.app.api; version=1.2.0 77
    96. 96. Modules / Bundles Bundle-SymbolicName: com.sample.appBundle-SymbolicName: com.foo.bar manifest manifest Export-Package: com.sample.app.api; version=1.2.0 Import-Package: com.sample.app.api; version=[1.2.0-2.0.0) 77
    97. 97. Modules / Bundles Bundle-SymbolicName: com.sample.appBundle-SymbolicName: com.foo.bar manifest manifest Export-Package: com.sample.app.api; version=1.2.0 Import-Package: com.sample.app.api; version=[1.2.0-2.0.0) 77
    98. 98. Cycle de vie 78
    99. 99. Cycle de vieinstall 78
    100. 100. Cycle de vieinstallInstalled 78
    101. 101. Cycle de vie install Installedresolve 78
    102. 102. Cycle de vie install Installedresolve Resolved 78
    103. 103. Cycle de vie update refresh install Installed updateresolve refresh Resolved 78
    104. 104. Cycle de vie update refresh install Installed update startresolve refresh Resolved 78
    105. 105. Cycle de vie update refresh install Installed Starting update startresolve refresh Active Resolved 78
    106. 106. Cycle de vie update refresh install Installed Starting update startresolve refresh Active Resolved stop 78
    107. 107. Cycle de vie update refresh install Installed Starting update startresolve refresh Active Resolved stop Stopping 78
    108. 108. Cycle de vie update refresh install Installed Starting update startresolve refresh Active Resolved stop uninstall Stopping 78
    109. 109. Cycle de vie update refresh install Installed Starting update startresolve refresh Active Resolved stop uninstall Stopping Uninstalled 78
    110. 110. Cycle de vie update refresh install Installed Starting update start resolve refreshuninstall Active Resolved stop uninstall Stopping Uninstalled 78
    111. 111. Services listener OSGIBundle A service Bundle B registry 79
    112. 112. Services listener register OSGIBundle A service Bundle B registry 79
    113. 113. Services listener register OSGI lookupBundle A service Bundle B registry 79
    114. 114. Services listener register OSGIBundle A service Bundle B registry 79
    115. 115. Services notify listener register OSGIBundle A service Bundle B registry 79
    116. 116. Services notify listener register OSGI lookupBundle A service Bundle B registry 79
    117. 117. Weld-OSGi 80
    118. 118. Weld-OSGi(Essaye d’être) le meilleur des deux mondes dynamique, typesafe, utilisation d’annotations, etc ...Extension CDI permettant d’utiliser le modèle de programmation CDI dans OSGiPas besoin de connaître OSGi faire disparaitre le modèle de programmation OSGi en faveur de celui de CDI modèle de programmation standard ... mais reste compatible 81
    119. 119. Weld-OSGiUn projet JBoss Weld besoin de démarrer Weld dans un environnement OSGi expérimentations à faire sur la compatibilité des modèles de programmationDéveloppé par l’équipe R&D SERLI Mathieu ANCELIN & Matthieu CLOCHARD 82
    120. 120. Mais, comment ça marche ? Plateforme OSGi Plateforme Java 83
    121. 121. Mais, comment ça marche ? Weld- OSGi Plateforme OSGi Plateforme Java 83
    122. 122. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi Plateforme OSGi Plateforme Java 83
    123. 123. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi beans .xml Plateforme OSGi Plateforme Java 83
    124. 124. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi beans beans .xml .xml Plateforme OSGi Plateforme Java 83
    125. 125. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi beans beans .xml .xml Plateforme OSGi Plateforme Java 83
    126. 126. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi beans beans .xml .xml Plateforme OSGi Plateforme Java 83
    127. 127. Mais, comment ça marche ? Weld- bundle 1 bundle2 bundle3 OSGi beans beans .xml .xml Plateforme OSGi Plateforme Java 83
    128. 128. Modulariser ‘Socializer’ Socializer.war seam-social-api seam-social-core Jackson, Scribe, Solder seam-social- twitter seam-social- seam-social- linkedin facebook 84
    129. 129. Modulariser ‘Socializer’seam-social-api seam-social- twitterseam-social-core seam-social- Socializer.war linkedinJackson, Scribe, Solder seam-social- facebook 85
    130. 130. Modulariser ‘Socializer’ module-twitter social-api module-linkedin Socializer.warmodule-facebook 86
    131. 131. Modulariser ‘Socializer’ Registresocial-api Socializer.war OSGi 87
    132. 132. Modulariser ‘Socializer’ Registresocial-api Socializer.war OSGi 87
    133. 133. Modulariser ‘Socializer’ module-twitter Registresocial-api Socializer.war OSGi 87
    134. 134. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi 87
    135. 135. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook 87
    136. 136. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook Service OSGi 87
    137. 137. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook Service OSGi 87
    138. 138. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook Service OSGi 87
    139. 139. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook Service OSGi 87
    140. 140. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook Service OSGi 87
    141. 141. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi module-facebook 88
    142. 142. Modulariser ‘Socializer’ module-twitter Registresocial-api module-linkedin Socializer.war OSGi le O SGi module-facebook B und 88
    143. 143. Modulariser ‘Socializer’ module-twitter le O SGi Registresocial-api module-linkedin B und Socializer.war OSGi le O SGi module-facebook B und 88
    144. 144. Modulariser ‘Socializer’ le O SGi module-twitter B und le O SGi Registresocial-api module-linkedin B und Socializer.war OSGi le O SGi module-facebook B und 88
    145. 145. Modulariser ‘Socializer’ le O SGi SGi module-twitter B und und le OB le O SGi Registre social-api module-linkedin B und Socializer.war OSGi le O SGi module-facebook B und 88
    146. 146. Modulariser ‘Socializer’ le O SGi SGi module-twitter B und EB und le O p pli. WB A le O SGi Registre social-api module-linkedin B und Socializer.war OSGi le O SGi module-facebook B und 88
    147. 147. API communepublic interface SocialProvider { String getName();    UserProfile getUserProfile();    OAuthService getOAuthService();    List<Post> getTimeline();    void post(Post post);} 89
    148. 148. API communeExport-Package fr.devoxx.social.api;version=1.0.0 90
    149. 149. Construire les modules sociauxModule OSGi pour wrapper la librairie cible (twitter, facebook, etc ...) ajout de quelques classes pour permettre l’intégration via Weld-OSGi aucun export de package nécessaire nous allons exposer un service via un type de l’API commune import des packages des librairies utilisées ainsi que de l’API commune 91
    150. 150. Exposer les modulesChaque module ‘Social’ va se charger d’exposer un Service type‘SocialProvider’ à travers le registre de services OSGi à disposition des autres bundles Weld-OSGi à disposition des autres bundles OSGi utilisable par d’autres applications 92
    151. 151. Publication des SocialProviders• Publication par déclaration @Publish @ApplicationScoped public class TwitterSocialProvider implements SocialProvider {     ... } 93
    152. 152. Publication des SocialProviders• Publication par déclaration @Publish @ApplicationScoped public class TwitterSocialProvider implements SocialProvider {     ... }• Publication dynamique @Inject Instance<SocialProvider> instance; @Inject ServiceRegistry registry; SocialProvider service = instance.get(); Registration< SocialProvider > reg = registry.register(service); ... reg.unregister(); 94
    153. 153. Récupération des Posts depuis ‘Socializer’Chaque module ‘Social’ expose un service OSGi permettant d’accéder auPosts qu’il manipule‘Socializer’ doit consommer ces Posts pour les afficher dans son interface différentes méthodes possibles privilégions une approche générique 95
    154. 154. Injection de servicesInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible 96
    155. 155. Le rôle de l’extensionVraisemblablement, le bean correspondant à ‘@OSGiService SocialProviderprovider’ n’existe pas dans l’application clienteAu démarrage de l’extension CDI, Weld-OSGi va scanner tous les pointsd’injection recherche tous les PI utilisant @OSGiService et créé des beans correspondant cependant n’écrase pas les beans existant pour que l’application continue à fonctionner comme doit, tout n’est pas censé être OSGi-ifié 97
    156. 156. Le rôle de l’extensionInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible@Inject @OSGiServiceMyService service; 98
    157. 157. Le rôle de l’extensionInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible@Inject @OSGiService InjectionPointMyService service; 98
    158. 158. Le rôle de l’extensionInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible create()@Inject @OSGiServiceMyService service; Provider InjectionPoint 98
    159. 159. Le rôle de l’extensionInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible P get() create() R@Inject @OSGiServiceMyService service; O Provider InjectionPoint X Y 98
    160. 160. Le rôle de l’extensionInjection de service dynamique@Inject @OSGiService SocialProvider provider;provider.getTimeline(); // échoue si aucun service disponible Extension CDI P get() create() R@Inject @OSGiServiceMyService service; O Provider InjectionPoint X Y 98
    161. 161. Le rôle de l’extensionprovider.getTimeline() P R O registre de X services Y OSGI 99
    162. 162. Le rôle de l’extensionprovider.getTimeline() P R O registre de X services Y OSGI 99
    163. 163. Le rôle de l’extensionprovider.getTimeline() get() P R O registre de X services Y OSGI 99
    164. 164. Le rôle de l’extensionprovider.getTimeline() get() P R O registre de service X réel services Y OSGI 99
    165. 165. Le rôle de l’extensionprovider.getTimeline() get() P R O getTimeline() registre de service X réel services Y OSGI 99
    166. 166. Le rôle de l’extensionprovider.getTimeline() get() P R O getTimeline() registre de service X réel services Y OSGI unget() 99
    167. 167. Injection de servicesInjection programmatique - whiteboard pattern (comme Instance<T>)@Inject Service<SocialProvider> providers;for (SocialProvider provider : providers.first()) {    provider.getTimeline(); // appel sur 0-1 service}for (SocialProvider provider : providers) {    provider.getTimeline(); // appel sur 0-n service(s)}providers.get().getTimeline(); // peut échoué car non dynamiqueproviders.size();providers.isUnsatisfied();providers.isAmbiguous(); 100
    168. 168. Injection de services@Inject Service<SocialProvider> providers;public List<Post> getTimeline() {    List<Post> timeline = new ArrayList<Post>();    for (SocialProvider provider : providers) {    timeline.addAll(provider.getTimeline());    }    Collections.sort(timeline, new Comparator<Post>() {        public int compare(Post post1, Post post2) {            return post1.timestamp().compare(post2.timestamp());        }    });    return timeline;} 101
    169. 169. Et si on souhaite un service en particuliers ?@Publish@Twitterpublic class TwitterSocialProvider implements SocialProvider {    ...} 102
    170. 170. Et si on souhaite un service en particuliers ?@Publish@Twitterpublic class TwitterSocialProvider implements SocialProvider {    ...}@Inject @OSGiService  @Filter("(twitter=true)") SocialProvider service; 103
    171. 171. Et si on souhaite un service en particuliers ?@Publish@Twitterpublic class TwitterSocialProvider implements SocialProvider {    ...}@Inject @Filter("(twitter=true)")  Service<SocialProvider> service; 104
    172. 172. Et si on souhaite un service en particuliers ?@Publish@Twitterpublic class TwitterSocialProvider implements SocialProvider {    ...}@Inject @Filter("(twitter=true)")  Service<SocialProvider> service;@Inject @OSGiService @Twitter SocialProvider service; 105
    173. 173. Et si on souhaite un service en particuliers ?@Publish@Twitterpublic class TwitterSocialProvider implements SocialProvider {    ...}@Inject @Filter("(twitter=true)")  Service<SocialProvider> service;@Inject @Twitter Service<SocialProvider> service; 106
    174. 174. Des services requis ...Avoir une application dynamique est intéressant, mais parfois il estabsolument nécessaire d’avoir un certain service pour que tout fonctionneWeld-OSGi vous prévient lorsque des services requis sont disponibles peut fonctionner de manière globale pour tous les services requis du bundle peut cibler des services requis en particulier 107
    175. 175. Des services requis ... Bean A Bean Bservice validation de dépendances Weld-OSGi registre de services OSGi 108
    176. 176. Des services requis ... Bean A Bean Benregistrement d’un service requis service validation de dépendances Weld-OSGi registre de services OSGi 108
    177. 177. Des services requis ... Bean A Bean B enregistrement d’un service requis service validationExtension CDI de dépendances Weld-OSGi registre de services OSGi 108
    178. 178. Des services requis ... Bean A Bean B enregistrement d’un service requis service validationExtension CDI de dépendances enregistrements/ Weld-OSGi désenregistrements registre de de services services OSGi 108
    179. 179. Des services requis ... Bean A Bean B enregistrement d’un service requis service validationExtension CDI de dépendances notifications enregistrements/ Weld-OSGi désenregistrements registre de de services services OSGi 108
    180. 180. Des services requis ... Bean A Bean B enregistrement d’un service requis évènements de validation des dépendances service validationExtension CDI de dépendances notifications enregistrements/ Weld-OSGi désenregistrements registre de de services services OSGi 108
    181. 181. Des services requis ... Bean A Bean B enregistrement d’un service requis évènements de validation des dépendances service validationExtension CDI de dépendances notifications enregistrements/ Weld-OSGi désenregistrements registre de de services services OSGi 108
    182. 182. Des services requis ...@Inject @OSGiService @Required @Twitter SocialProvider twitter;@Inject @OSGiService @Required @Facebook SocialProvider facebook;public void start(@Observes Valid evt) {    System.out.println("Les SocialProviders sont disponibles");    twitter.getOAuthService().connect(); facebook.getOAuthService().connect();}public void stop(@Observes Invalid evt) { twitter.getOAuthService().disconnect(); facebook.getOAuthService().disconnect();    System.out.println("Les SocialProviders sont indisponibles");} 109
    183. 183. Des services requis ...@Inject @Required @Twitter Service<SocialProvider> twitter;@Inject @Required @Facebook Service<SocialProvider> facebook;public void start(@Observes Valid evt) {    System.out.println("Les SocialProviders sont disponibles");    twitter.get().getOAuthService().connect(); facebook.get().getOAuthService().connect();}public void stop(@Observes Invalid evt) { twitter.get().getOAuthService().disconnect(); facebook.get().getOAuthService().disconnect();    System.out.println("Les SocialProviders sont indisponibles");} 110
    184. 184. Des services requis ... let@Inject @Required @Twitter Service<SocialProvider> twitter; p@Inject @Required @Facebook Service<SocialProvider> facebook; o mpublic void start(@Observes Valid evt) {    System.out.println("Les SocialProviders sont disponibles"); c    twitter.get().getOAuthService().connect(); e facebook.get().getOAuthService().connect(); l} ndpublic void stop(@Observes Invalid evt) { u twitter.get().getOAuthService().disconnect(); b facebook.get().getOAuthService().disconnect();    System.out.println("Les SocialProviders sont indisponibles");} 111
    185. 185. Des services requis ...@Inject @OSGiService @Required SocialProvider provider;public void start(@Observes @Specification(SocialProvider.class) ServiceAvailable evt) {    System.out.println("Au moins un SocialProvider est disponible");    provider.getOAuthService().connect();}public void stop(@Observes @Specification(SocialProvider.class) ServiceUnavailable evt) {    System.out.println("Aucun SocialProvider disponible");} 112
    186. 186. Des services requis ...@Inject @OSGiService @Required Service<SocialProvider> provider;public void start(@Observes @Specification(SocialProvider.class) ServiceAvailable evt) {    System.out.println("Au moins un SocialProvider est disponible");    provider.get().getOAuthService().connect();}public void stop(@Observes @Specification(SocialProvider.class) ServiceUnavailable evt) {    System.out.println("Aucun SocialProvider disponible");} 113
    187. 187. Les notifications OSGiOSGi génère de nombreuse évènements pour pouvoir interagir avec lescouches bundle et services meilleur moyen de gérer le côté dynamique du frameworkEvènements disponibles : bundle events service events 114
    188. 188. Les notifications OSGiVa permettre à notre application de savoir lorsqu’un nouveau serviceest disponible géré de manière asynchrone, pas besoin de vérifier ‘à la main’ permet d’afficher une notification à l’utilisateur lui demandant de se connecter utilisation des servlets asynchrones ? 115
    189. 189. Evènements liés aux bundles OSGiEvènements possibles update refresh BundleInstalled install BundleResolved Installed Starting BundleStarting update start resolve refresh BundleStarted uninstall Active Resolved BundleStopping stop uninstall BundleStopped Stopping Uninstalled BundleUninstalled BundleUpdated BundleUnresolved 116
    190. 190. Evènements liés aux bundles OSGipublic void bindBundle(@Observes BundleInstalled evt) {} 117
    191. 191. Evènements liés aux bundles OSGipublic void bindBundle(@Observes @BundleVersion("1.2.3") BundleInstalled evt) {} 118
    192. 192. Evènements liés aux bundles OSGipublic void bindBundle(@Observes @BundleName("org.jboss.seam.social.twitter") BundleInstalled evt) {} 119
    193. 193. Evènements liés aux bundles OSGipublic void bindBundle(@Observes @BundleName("org.jboss.seam.social.twitter") @BundleVersion("1.2.3") BundleInstalled evt) {} 120
    194. 194. Evènements liés aux services OSGi• Available events • ServiceArrival • ServiceDeparture • ServiceChanged 121
    195. 195. Evènements liés aux services OSGi Available events ServiceArrival ServiceDeparture ServiceChangedvoid bindService(@Observes ServiceArrival evt) {} 122
    196. 196. Evènements liés aux services OSGi • Available events • ServiceArrival • ServiceDeparture • ServiceChangedvoid bindService(@Observes @Filter("(twitter=true)") ServiceArrival evt) {} 123
    197. 197. Evènements liés aux services OSGi • Available events • ServiceArrival • ServiceDeparture • ServiceChangedvoid bindService(@Observes @Specification(SocialProvider.class) ServiceArrival evt) {} 124
    198. 198. Evènements liés aux services OSGi • Available events • ServiceArrival • ServiceDeparture • ServiceChangedvoid bindService(@Observes @Specification(SocialProvider.class) @Filter("(twitter=true)") ServiceArrival evt) {} 125
    199. 199. Inter-bundles eventsCommunication entre les bundles OSGi gérés par Weld-OSGi Bundle B Weld-OSGi Bundle C Bundle A 126
    200. 200. Inter-bundles eventsCommunication entre les bundles OSGi gérés par Weld-OSGi Bundle B Weld-OSGi Bundle C fire() Bundle A 126
    201. 201. Inter-bundles eventsCommunication entre les bundles OSGi gérés par Weld-OSGi Bundle B broadcast() broadcast() Weld-OSGi Bundle C fire() Bundle A 126
    202. 202. Inter-bundles eventsSynchronisation des timelines de manière planifiée Appelé depuis un EJB avec @Schedule Récupération des timelines de manière asynchrone Mise en cache pour des raisons de performancesEnvoi des nouveaux ‘Post’ vers l’application cliente pour une mise à jour entemps réel 127
    203. 203. Inter-bundles events@Inject Event<InterBundleEvent> event;event.fire(new InterBundleEvent(new SynchronizeTimeline())); 128
    204. 204. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline())); 128
    205. 205. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline())); 129
    206. 206. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline()));public void synchronizeTimeline(@Observes InterBundleEvent event) {} 130
    207. 207. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline()));public void synchronizeTimeline(@Observes @Sent InterBundleEvent event) {} 131
    208. 208. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline()));public void synchronizeTimeline(@Observes @Specification(SynchronizeTimeline.class) InterBundleEvent event) {} 132
    209. 209. Inter-bundles events depuis un EJB@Inject Event<InterBundleEvent> event; @Scheduleevent.fire(new InterBundleEvent(new SynchronizeTimeline()));public void synchronizeTimeline(@Observes @Specification(SynchronizeTimeline.class) @Sent InterBundleEvent event) {} 133
    210. 210. Démo : ‘Modular Socializer’ 134
    211. 211. Le futur de Weld-OSGiIntégration dans Weld core (en cours)Plugin ForgeCDI Extension pour les serveurs Java EE hybrides utiliser Weld-OSGi dans une application Java EE en cours ;-)Intégration avec les spécifications entreprise une future spécification OSGi entreprise ? 135
    212. 212. Informations sur le projetCode du projet https://github.com/mathieuancelin/core/tree/weld-osgi/environments/osgiDocumentation du projet http://mathieuancelin.github.com/weld-osgi/ 136
    213. 213. Seam Social et son futurSeam Social est forkable sur github : http://github.com/seam/socialSi vous êtes intéressés par Socializer (branche ‘Twitter Bootstrap’ incluse) : https://github.com/antoinesd/SocializerSeam Social dépasse le simple cadre d’un module CDIUne tentative de JSR a été conduite mais rejetéeUn projet « Java Social » est en cours de constitutionUne communauté s’est constituée. Pour ceux que ça intéresse suivez@antoine_sd ou @Java_social 137
    214. 214. Le mot de la finCDI c’est bien mangez-enOSGi est beaucoup plus sympathique que vous ne le pensez Surtout avec Weld-OSGiSeam Social c’est cool mais le sera encore plus avec vous commecontributeur. 138
    215. 215. Questions 139

    ×