Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CDI par la pratique avec Seam Social et Weld OSGi

CDI par la pratique avec Seam Social et Weld OSGi

Présentation de l'université CDI par la pratique faite à Devoxx France 2012

Antoine Sabot-Durand

April 22, 2012
Tweet

More Decks by Antoine Sabot-Durand

Other Decks in Programming

Transcript

  1. CDI mis en pratique avec Seam Social et Weld OSGI

    par Mathieu Ancelin @TrevorReznik et Antoine Sabot-Durand @antoine_sd 1 1 jeudi 19 avril 12
  2. Antoine Sabot-Durand Expert Java EE 16 ans d’expérience Java &

    OSS : Leader sur Seam Social Commiter Apache Deltaspike Membre de l’EG CDI 1.1(JSR 346) @antoine_sd 2 2 jeudi 19 avril 12
  3. Ippon technologies SSII parisienne spécialisée en Java Domaines de compétence

    Java EE Portail SOA RIA e-commerce Mobilité Partenaire Devoxx. Venez sur notre Stand ! 3 3 jeudi 19 avril 12
  4. Mathieu ANCELIN Développeur @SERLI Java & 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 4 jeudi 19 avril 12
  5. SERLI Société de conseil et d’ingénierie du système d’information 65

    employés 80% de business Java Contribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346 www.serli.com @SerliFr 5 5 jeudi 19 avril 12
  6. SERLI Société de conseil et d’ingénierie du système d’information 65

    employés 80% de business Java Contribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346 www.serli.com @SerliFr 5 5 jeudi 19 avril 12
  7. Abstract La plupart des présentations CDI restent théoriques Nous allons

    vous montrer comment CDI a été mis en pratique à travers le fonctionnement du module Seam Social Vous verrez également comment CDI peut être modularisé grâce à Weld OSGI Nous profiterons également de ces 3 heures pour monter une petite application sociale en CDI et JSF / Primefaces et la même utilisant Twitter Bootstrap 7 7 jeudi 19 avril 12
  8. 10 Serveur Java EE 6 Web Tier Service Tier CDI

    EJB Container Managed Bean (POJO) Servlet 3.0 JSF 2.0 Client Tier Application Client Container Web Browser JTA JPA JMS JAX-WS JAX-RS Messaging SOA JCA JAXB JAAS CDI est une technologie d’intégration qui enrichi aussi bien des POJO que des EJB Il a vocation à servir de «glue» entre les différentes parties de la stack Java EE C’est la première technologie qui permet d’étendre Java EE de manière portable et naturelle CDI dans Java EE 10 jeudi 19 avril 12
  9. Seam Social Seam Social est un module CDI pour faciliter

    l’utilisation des réseaux sociaux Inspiré par Spring Social, il propose un noyau très différent tirant parti des spécificités CDI Les binding des API des réseaux sociaux, en revanche sont pour l’instant des forks de ceux de Spring Social Connecteurs out of the box 11 11 jeudi 19 avril 12
  10. 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 12 jeudi 19 avril 12
  11. Jackson L’un des frameworks les plus performants pour parser du

    JSON Jackson permet également de mapper du JSON sur des classes java Pour ça il peut utiliser des annotations JAXB ou ses propres annotations En plus Jackson propose la notion de Mixin qui permet de déporter les annotations sur une classe dédiée et de laisser la classe d’origine propre. 13 @JsonIgnoreProperties(ignoreUnknown = true) @SuppressWarnings("unused") abstract class TwitterProfileMixin { @JsonCreator TwitterProfileMixin(@JsonProperty("id") String id, @JsonProperty("screen_name") String screenName, @JsonProperty("name") String name, @JsonProperty("url") String url, @JsonProperty("profile_image_url") String profileImageUrl, @JsonProperty("description") String description, @JsonProperty("location") String location, @JsonProperty("created_at") @JsonDeserialize(using = TimelineDateDeserializer.class) Date createdDate) { } @JsonProperty("notifications") private boolean notificationsEnabled; @JsonProperty("lang") private String language; @JsonProperty("statuses_count") private int statusesCount; ... 13 jeudi 19 avril 12
  12. Jackson : Utilisation d’un Mixin 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 Un module Jackson est nécessaire pour créer l’association 14 Texte Pojo PojoMixin Module Jackson 14 jeudi 19 avril 12
  13. La big picture 16 Tous les réseaux sociaux reposent sur

    REST comme protocole d’échange Les données transmises sont au format JSON et certains proposent XML en option Enfin, la sécurisation (encryption et authentification) passe par le protocole OAuth. 16 jeudi 19 avril 12
  14. OAuth OAuth est un protocole pour déléguer une autorisation à

    l’utilisation d’un service donné (autoriser sans partager ses données d’accès avec l’entité à qui on délègue l’accès au service) Développé par Twitter, Magnolia puis Google, il est normalisé par l’IETF en avril 2010 via la RFC 5849 La 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.0 Pour utiliser OAuth on doit commencer par déclarer une application sur le service concerné. Celui-ci vous délivrera une Consumer_Key (clé asymétrique) 17 17 jeudi 19 avril 12
  15. Le cycle OAuth 1.0a 18 1 Le client demande une

    ressource sur le service tiers Serveur de l’application Service tiers (OAuth) Client 18 jeudi 19 avril 12
  16. Le cycle OAuth 1.0a 18 1 2 Le client demande

    une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
  17. Le cycle OAuth 1.0a 18 1 2 3 Le client

    demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) Le service retourne le token L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
  18. Le cycle OAuth 1.0a 18 1 2 3 Le client

    demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
  19. Le cycle OAuth 1.0a 18 1 2 3 Le client

    demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification Client 18 jeudi 19 avril 12
  20. Le cycle OAuth 1.0a 18 1 2 3 Le client

    demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification 6 A l’aide du code et du Token, le service demande un Access Token Client 18 jeudi 19 avril 12
  21. Le cycle OAuth 1.0a 18 1 2 3 Le client

    demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification 6 A l’aide du code et du Token, le service demande un Access Token 7 Le service retourne l’access token Client 18 jeudi 19 avril 12
  22. JSON Javascript Object Notation : format de structuration de données

    provenant de Javascript et adopté comme standard d’échange dans la quasi totalités des services en ligne Comparable à XML mais sans XSD Tous les langages disposent de bibliothèques pour exploiter / générer du JSon 19 1: { 2: "firstName": "John", 3: "lastName" : "Smith", 4: "age" : 25, 5: "address" : 6: { 7: "streetAddress": "21 2nd Street", 8: "city" : "New York", 9: "state" : "NY", 10: "postalCode" : "10021" 11: }, 12: "phoneNumber": 13: [ 14: { 15: "type" : "home", 16: "number": "212 555-1234" 17: }, 18: { 19: "type" : "fax", 20: "number": "646 555-4567" 21: } 22: ] 23: } 19 jeudi 19 avril 12
  23. Objectifs de Seam Social 21 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 jeudi 19 avril 12
  24. Les classes principales 22 +buildUri(String, String, String) +buildUri(String, Map) +getApiRootUrl()

    +buildUri(String) +buildUri(String, Object) AbstractSocialNetworkService +getAccessToken() +getAuthorizationUrl() +getVerifier() +initAccessToken() +sendSignedRequest(RestVerb, String) +sendSignedRequest(RestVerb, String, Map) +sendSignedRequest(RestVerb, String, String, Object) +setVerifier(String) +setAccessToken(String, String) +setAccessToken(OAuthToken) +sendSignedXmlRequest(RestVerb, String, String) +getSession() +requireAuthorization() +sendSignedRequest(OAuthRequest) «interface» OAuthService +getRequestToken() +getAccessToken(OAuthToken, String) +signRequest(OAuthToken, OAuthRequest) +getVersion() +getAuthorizationUrl(OAuthToken) +requestFactory(RestVerb, String) +tokenFactory(String, String) «interface» OAuthProvider +getRequestToken() +setRequestToken(OAuthToken) +getAccessToken() +setAccessToken(OAuthToken) +getVerifier() +setVerifier(String) +setUserProfile(UserProfile) +getUserProfile() +getServiceQualifier() +isConnected() +getName() «interface» OAuthSession +getMyProfile() +getSession() +resetConnection() +isConnected() +configureService(OAuthService) +getVerifierParamName() «interface» SocialNetworkServicesHub «interface» SocialNetworkServicesHub 22 jeudi 19 avril 12
  25. Bootstraping Social 23 @Twitter @ApplicationScoped @OAuthApplication(apiKey = "FQzlQC49UhvbMZoxUIvHTQ", apiSecret =

    "VQ5CZHG4qUoAkUUmckPn4iN4yyjBKcORTW0wnok4r1k", callback = "http://localhost:8080/social-web-client/callback.jsf") @Produces public TwitterServicesHub twitterProducer(TwitterServicesHub service) { return service; } +getAccessToken() +getAuthorizationUrl() +getVerifier() +initAccessToken() +sendSignedRequest(RestVerb, String) +sendSignedRequest(RestVerb, String, Map) +sendSignedRequest(RestVerb, String, String, Object) +setVerifier(String) +setAccessToken(String, String) +setAccessToken(OAuthToken) +sendSignedXmlRequest(RestVerb, String, String) +getSession() +requireAuthorization() +sendSignedRequest(OAuthRequest) «interface» OAuthService +getRequestToken() +setRequestToken(OAuthToken) +getAccessToken() +setAccessToken(OAuthToken) +getVerifier() +setVerifier(String) +setUserProfile(UserProfile) +getUserProfile() +getServiceQualifier() +isConnected() +getName() «interface» OAuthSession +getRequestToken() +getAccessToken(OAuthToken, String) +signRequest(OAuthToken, OAuthRequest) +getVersion() +getAuthorizationUrl(OAuthToken) +requestFactory(RestVerb, String) +tokenFactory(String, String) «interface» OAuthProvider @Twitter @ApplicationScoped @Twitter @ApplicationScoped @Twitter @SessionScoped Grace à une extension CDI incluse dans Solder, on créé 4 beans portant le même qualifier et le scope de son choix lié à celui du producer 23 jeudi 19 avril 12
  26. Etendre Seam Social 24 Pour 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 jeudi 19 avril 12
  27. CDI La meilleur spec. de Java EE 6 (la plus

    cool) #annotationsEverywhere #noXml Typesafe Aucune 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 Candi Limité à Java EE 6 ? et bien, pas forcément ... 27 27 jeudi 19 avril 12
  28. Environnements for CDI/Weld Il est possible de bootstraper Weld très

    simplement en dehors de Java EE 6 à priori, vous pouvez le bootstraper n’importe où :-) Weld-Servlet Jetty Tomcat 6/7 Weld-SE Bonne vieilles applications desktop 28 28 jeudi 19 avril 12
  29. Le Bean En 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 31 jeudi 19 avril 12
  30. 33 Injection de dépendance public class HelloService { public String

    hello() { return "Hello World!"; } } 33 jeudi 19 avril 12
  31. 34 public class MyBean extends Application { private HelloService service;

    @Inject public MyBean(HelloService service) { this.service = service; } public void displayHello() { display( service.hello(); } } Injection de dépendance 34 jeudi 19 avril 12
  32. 35 public class MyBean extends Application { private HelloService service;

    @Inject public void setService(HelloService service) { this.service = service; } public void displayHello() { display( service.hello(); } } Injection de dépendance 35 jeudi 19 avril 12
  33. 36 public class MyBean extends Application { @Inject HelloService service;

    public void displayHello() { display( service.hello(); } } Injection de dépendance 36 jeudi 19 avril 12
  34. 37 Injection de dépendance public 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 jeudi 19 avril 12
  35. Les qualifiers 38 public 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 jeudi 19 avril 12
  36. Les qualifiers 39 @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public

    @interface French {} @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface English {} 39 jeudi 19 avril 12
  37. Les qualifiers 40 @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public

    @interface French {} @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface English {} 40 jeudi 19 avril 12
  38. Les qualifiers 41 @French public class FrenchHelloService implements HelloService {

    public String hello() { return "Bonjour tout le monde!"; } } @English public class EnglishHelloService implements HelloService{ public String hello() { return "Hello World!"; } } 41 jeudi 19 avril 12
  39. Les qualifiers 42 @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public

    @interface Language { Languages value(); @Nonbinding String description() default ""; public enum Languages { FRENCH, ENGLISH } } 42 jeudi 19 avril 12
  40. Les qualifiers 43 @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 jeudi 19 avril 12
  41. Les qualifiers 44 public 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 jeudi 19 avril 12
  42. Les qualifiers 45 public class MyBean extends Application { @Inject

    @French HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { } 45 jeudi 19 avril 12
  43. Les qualifiers 46 public class MyBean extends Application { @Inject

    @French @Console HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { } 46 jeudi 19 avril 12
  44. Les qualifiers 47 public class MyBean extends Application { @Inject

    @French @Console @Secured HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { } 47 jeudi 19 avril 12
  45. Les qualifiers 48 public class MyBean extends Application { @Inject

    @French @Console @Secured HelloService service; } @French @Secured public class FrenchHelloService implements HelloService { } 48 jeudi 19 avril 12
  46. Les qualifiers 48 public class MyBean extends Application { @Inject

    @French @Console @Secured HelloService service; } @French @Secured public class FrenchHelloService implements HelloService { } 48 jeudi 19 avril 12
  47. Injection programmatique 49 public class MyBean extends Application { @Inject

    Instance<HelloService> service; public void displayHello() { display( service.get().hello() ); } } 49 jeudi 19 avril 12
  48. Injection programmatique 50 public class MyBean extends Application { @Inject

    Instance<HelloService> service; public void displayHello() { if (!service.isUnsatisfied()) { display( service.get().hello() ); } } } 50 jeudi 19 avril 12
  49. Injection programmatique 51 public class MyBean extends Application { @Any

    @Inject Instance<HelloService> services; public void displayHello() { display( service.select( new AnnotationLiteral()<French> {}) .get() ); } } 51 jeudi 19 avril 12
  50. Les contextes Gestion 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, singleton Possibilité de créer des scopes personnalisés via les extensions 52 52 jeudi 19 avril 12
  51. Les contextes 53 @SessionScoped public class CartBean { public void

    addItem(Item item) { ... } } 53 jeudi 19 avril 12
  52. Les contextes 54 @ApplicationScoped public class CartBean { public void

    addItem(Item item) { ... } } 54 jeudi 19 avril 12
  53. Les contextes 54 @ApplicationScoped public class CartBean { public void

    addItem(Item item) { ... } } FAIL !!! 54 jeudi 19 avril 12
  54. Les contextes 55 @ConversationScoped public class CartBean { public void

    addItem(Item item) { ... } } 55 jeudi 19 avril 12
  55. Les contextes 56 @ThreadScoped public class CartBean { public void

    addItem(Item item) { ... } } 56 jeudi 19 avril 12
  56. Les contextes 57 @HourScoped public class CartBean { public void

    addItem(Item item) { ... } } 57 jeudi 19 avril 12
  57. Les contextes 58 @RandomScoped public class CartBean { public void

    addItem(Item item) { ... } } 58 jeudi 19 avril 12
  58. Les décorateurs 59 @Decorator public class HelloDecorator implements HelloService {

    @Inject @Delegate HelloService service; public String hello() { return service.hello() + "-decorated"; } } @Inject HelloService service; 59 jeudi 19 avril 12
  59. Les décorateurs 60 @Decorator public abstract class HelloDecorator implements HelloService

    { @Inject @Delegate HelloService service; public String hello() { return service.hello() + "-decorated"; } } @Inject HelloService service; 60 jeudi 19 avril 12
  60. Les décorateurs 61 <?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 jeudi 19 avril 12
  61. Les évènements 62 @Inject Event<String> evt; ... evt.fire("Bonjour"); @Inject Event<Post>

    evt; ... evt.fire( new Post( "Mathieu ANCELIN ", "Bonjour", )); 62 jeudi 19 avril 12
  62. Les évènements 63 public 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 jeudi 19 avril 12
  63. Les évènements 65 @Inject @English Event<String> evt; ... evt.fire("Hello"); public

    void receiveEvt(@Observes @English String evt) { System.out.println("Received : " + evt); } 65 jeudi 19 avril 12
  64. 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 beans D’une manière générale inventorier l’ensembles de l'écosystème CDI de l’application, le modifier ou l’enrichir. 68 68 jeudi 19 avril 12
  65. Pour comprendre les extensions 69 Une fois l’application lancée le

    BeanManager est en lecture seule (pas de création de Bean au runtime) Ne pas confondre Bean (définition) avec Instance de Bean Nos extensions seront donc exécutées au démarrage de l’application et devront influer sur le contenu du BeanManager et des futurs beans Les extensions peuvent aussi devenir des Beans (avec quelques restrictions) 69 jeudi 19 avril 12
  66. Cycle de vie CDI 70 Deploy Application Before Bean Discovery

    Process Producers Process Anotated Types Scan Archive Application Running After Deployment Validation Before Shutdown Undeploy Application Process Beans After Bean Discovery Process Injection Taget Process Observer Methods 70 jeudi 19 avril 12
  67. Pour Faire une Extension CDI 71 Créer une classe qui

    implémente Extension avec un constructeur sans paramètres Y placer une ou plusieurs méthodes avec un observer sur les événements du cycle de vie CDI pour intervenir sur le contenu du bean manager Ajouter dans le classpath le fichier META-INF/services/javax.enterprise.inject.spi.Extension dans lequel on ajoutera le nom qualifié de la classe d’extension 71 jeudi 19 avril 12
  68. Exemple simple : @Veto 72 <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 jeudi 19 avril 12
  69. Exemple simple : @Veto 72 <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 jeudi 19 avril 12
  70. Et OSGi ? 74 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 jeudi 19 avril 12
  71. OSGi Plateforme modulaire et dynamique pour Java Très stable et

    puissante mais APIs vieillottes ... Plateforme Java 76 76 jeudi 19 avril 12
  72. OSGi Plateforme modulaire et dynamique pour Java Très stable et

    puissante mais APIs vieillottes ... Module Plateforme Java 76 76 jeudi 19 avril 12
  73. OSGi Plateforme modulaire et dynamique pour Java Très stable et

    puissante mais APIs vieillottes ... Module Lifecycle Plateforme Java 76 76 jeudi 19 avril 12
  74. OSGi Plateforme modulaire et dynamique pour Java Très stable et

    puissante mais APIs vieillottes ... Module Lifecycle Service Plateforme Java 76 76 jeudi 19 avril 12
  75. OSGi Plateforme modulaire et dynamique pour Java Très stable et

    puissante mais APIs vieillottes ... Module Lifecycle Service Plateforme Java Bundles 76 76 jeudi 19 avril 12
  76. Modules / Bundles manifest manifest Bundle-SymbolicName: com.foo.bar Bundle-SymbolicName: com.sample.app Export-Package:

    com.sample.app.api; version=1.2.0 Import-Package: com.sample.app.api; version=[1.2.0-2.0.0) 77 77 jeudi 19 avril 12
  77. Modules / Bundles manifest manifest Bundle-SymbolicName: com.foo.bar Bundle-SymbolicName: com.sample.app Export-Package:

    com.sample.app.api; version=1.2.0 Import-Package: com.sample.app.api; version=[1.2.0-2.0.0) 77 77 jeudi 19 avril 12
  78. Cycle de vie Installed Resolved Starting Active install update refresh

    start update refresh resolve 78 78 jeudi 19 avril 12
  79. Cycle de vie Installed Resolved Starting Active install update refresh

    stop start update refresh resolve 78 78 jeudi 19 avril 12
  80. Cycle de vie Installed Resolved Starting Active Stopping install update

    refresh stop start update refresh resolve 78 78 jeudi 19 avril 12
  81. Cycle de vie Installed Resolved Starting Active Stopping install update

    refresh stop start update refresh resolve uninstall 78 78 jeudi 19 avril 12
  82. Cycle de vie Installed Resolved Uninstalled Starting Active Stopping install

    update refresh stop start update refresh resolve uninstall 78 78 jeudi 19 avril 12
  83. Cycle de vie Installed Resolved Uninstalled Starting Active Stopping install

    update refresh stop start update refresh resolve uninstall uninstall 78 78 jeudi 19 avril 12
  84. 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 OSGi Pas 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 81 jeudi 19 avril 12
  85. Weld-OSGi Un projet JBoss Weld besoin de démarrer Weld dans

    un environnement OSGi expérimentations à faire sur la compatibilité des modèles de programmation Développé par l’équipe R&D SERLI Mathieu ANCELIN & Matthieu CLOCHARD 82 82 jeudi 19 avril 12
  86. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 83 jeudi 19 avril 12
  87. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 beans .xml 83 jeudi 19 avril 12
  88. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 beans .xml beans .xml 83 jeudi 19 avril 12
  89. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 beans .xml beans .xml 83 jeudi 19 avril 12
  90. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 beans .xml beans .xml 83 jeudi 19 avril 12
  91. Mais, comment ça marche ? 83 Plateforme Java Plateforme OSGi

    Weld- OSGi bundle 1 bundle2 bundle3 beans .xml beans .xml 83 jeudi 19 avril 12
  92. Modulariser ‘Socializer’ 84 Jackson, Scribe, Solder seam-social- twitter seam-social-core seam-social-api

    seam-social- facebook seam-social- linkedin Socializer.war 84 jeudi 19 avril 12
  93. Modulariser ‘Socializer’ 85 Socializer.war Jackson, Scribe, Solder seam-social- twitter seam-social-core

    seam-social-api seam-social- facebook seam-social- linkedin 85 jeudi 19 avril 12
  94. Modulariser ‘Socializer’ 88 Socializer.war module-twitter module-facebook module-linkedin social-api Registre OSGi

    Bundle OSGi Bundle OSGi Bundle OSGi Bundle OSGi Appli. WEB 88 jeudi 19 avril 12
  95. API commune 89 public interface SocialProvider { String getName(); UserProfile

    getUserProfile(); OAuthService getOAuthService(); List<Post> getTimeline(); void post(Post post); } 89 jeudi 19 avril 12
  96. Construire les modules sociaux Module 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 91 jeudi 19 avril 12
  97. Exposer les modules Chaque 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 92 jeudi 19 avril 12
  98. • Publication par déclaration @Publish @ApplicationScoped public class TwitterSocialProvider implements

    SocialProvider { ... } 93 Publication des SocialProviders 93 jeudi 19 avril 12
  99. • Publication dynamique • Publication par déclaration @Inject Instance<SocialProvider> instance;

    @Inject ServiceRegistry registry; SocialProvider service = instance.get(); Registration< SocialProvider > reg = registry.register(service); ... reg.unregister(); 94 @Publish @ApplicationScoped public class TwitterSocialProvider implements SocialProvider { ... } Publication des SocialProviders 94 jeudi 19 avril 12
  100. Récupération des Posts depuis ‘Socializer’ Chaque module ‘Social’ expose un

    service OSGi permettant d’accéder au Posts 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 95 jeudi 19 avril 12
  101. Injection de services Injection de service dynamique @Inject @OSGiService SocialProvider

    provider; provider.getTimeline(); // échoue si aucun service disponible 96 96 jeudi 19 avril 12
  102. Le rôle de l’extension Vraisemblablement, le bean correspondant à ‘@OSGiService

    SocialProvider provider’ n’existe pas dans l’application cliente Au démarrage de l’extension CDI, Weld-OSGi va scanner tous les points d’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 97 jeudi 19 avril 12
  103. Injection de service dynamique @Inject @OSGiService SocialProvider provider; provider.getTimeline(); //

    échoue si aucun service disponible 98 @Inject @OSGiService MyService service; Le rôle de l’extension 98 jeudi 19 avril 12
  104. Injection de service dynamique @Inject @OSGiService SocialProvider provider; provider.getTimeline(); //

    échoue si aucun service disponible 98 @Inject @OSGiService MyService service; InjectionPoint Le rôle de l’extension 98 jeudi 19 avril 12
  105. Injection de service dynamique @Inject @OSGiService SocialProvider provider; provider.getTimeline(); //

    échoue si aucun service disponible 98 @Inject @OSGiService MyService service; Provider InjectionPoint create() Le rôle de l’extension 98 jeudi 19 avril 12
  106. Injection de service dynamique @Inject @OSGiService SocialProvider provider; provider.getTimeline(); //

    échoue si aucun service disponible 98 @Inject @OSGiService MyService service; P R O X Y Provider InjectionPoint create() get() Le rôle de l’extension 98 jeudi 19 avril 12
  107. Injection de service dynamique @Inject @OSGiService SocialProvider provider; provider.getTimeline(); //

    échoue si aucun service disponible 98 @Inject @OSGiService MyService service; P R O X Y Provider InjectionPoint create() get() Le rôle de l’extension Extension CDI 98 jeudi 19 avril 12
  108. provider.getTimeline() P R O X Y registre de services OSGI

    99 Le rôle de l’extension 99 jeudi 19 avril 12
  109. provider.getTimeline() P R O X Y registre de services OSGI

    99 Le rôle de l’extension 99 jeudi 19 avril 12
  110. provider.getTimeline() P R O X Y get() registre de services

    OSGI 99 Le rôle de l’extension 99 jeudi 19 avril 12
  111. provider.getTimeline() P R O X Y get() registre de services

    OSGI service réel 99 Le rôle de l’extension 99 jeudi 19 avril 12
  112. provider.getTimeline() P R O X Y get() registre de services

    OSGI service réel getTimeline() 99 Le rôle de l’extension 99 jeudi 19 avril 12
  113. provider.getTimeline() P R O X Y get() registre de services

    OSGI unget() service réel getTimeline() 99 Le rôle de l’extension 99 jeudi 19 avril 12
  114. Injection 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 dynamique providers.size(); providers.isUnsatisfied(); providers.isAmbiguous(); 100 Injection de services 100 jeudi 19 avril 12
  115. 101 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 jeudi 19 avril 12
  116. Et si on souhaite un service en particuliers ? @Publish

    @Twitter public class TwitterSocialProvider implements SocialProvider { ... } 102 102 jeudi 19 avril 12
  117. @Publish @Twitter public class TwitterSocialProvider implements SocialProvider { ... }

    @Inject @OSGiService @Filter("(twitter=true)") SocialProvider service; 103 Et si on souhaite un service en particuliers ? 103 jeudi 19 avril 12
  118. @Publish @Twitter public class TwitterSocialProvider implements SocialProvider { ... }

    @Inject @Filter("(twitter=true)") Service<SocialProvider> service; 104 Et si on souhaite un service en particuliers ? 104 jeudi 19 avril 12
  119. @Publish @Twitter public class TwitterSocialProvider implements SocialProvider { ... }

    @Inject @Filter("(twitter=true)") Service<SocialProvider> service; @Inject @OSGiService @Twitter SocialProvider service; 105 Et si on souhaite un service en particuliers ? 105 jeudi 19 avril 12
  120. @Publish @Twitter public class TwitterSocialProvider implements SocialProvider { ... }

    @Inject @Filter("(twitter=true)") Service<SocialProvider> service; @Inject @Twitter Service<SocialProvider> service; 106 Et si on souhaite un service en particuliers ? 106 jeudi 19 avril 12
  121. Des services requis ... Avoir une application dynamique est intéressant,

    mais parfois il est absolument nécessaire d’avoir un certain service pour que tout fonctionne Weld-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 107 jeudi 19 avril 12
  122. service validation de dépendances Weld-OSGi registre de services OSGi Bean

    B Bean A 108 Des services requis ... 108 jeudi 19 avril 12
  123. service validation de dépendances Weld-OSGi registre de services OSGi enregistrement

    d’un service requis Bean B Bean A 108 Des services requis ... 108 jeudi 19 avril 12
  124. service validation de dépendances Weld-OSGi registre de services OSGi enregistrement

    d’un service requis Bean B Bean A 108 Des services requis ... Extension CDI 108 jeudi 19 avril 12
  125. service validation de dépendances Weld-OSGi registre de services OSGi enregistrements/

    désenregistrements de services enregistrement d’un service requis Bean B Bean A 108 Des services requis ... Extension CDI 108 jeudi 19 avril 12
  126. service validation de dépendances Weld-OSGi registre de services OSGi enregistrements/

    désenregistrements de services enregistrement d’un service requis Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
  127. service validation de dépendances Weld-OSGi registre de services OSGi enregistrements/

    désenregistrements de services enregistrement d’un service requis évènements de validation des dépendances Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
  128. service validation de dépendances Weld-OSGi registre de services OSGi enregistrements/

    désenregistrements de services enregistrement d’un service requis évènements de validation des dépendances Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
  129. @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 Des services requis ... 109 jeudi 19 avril 12
  130. 110 @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"); } Des services requis ... 110 jeudi 19 avril 12
  131. bundle complet 111 @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"); } Des services requis ... 111 jeudi 19 avril 12
  132. @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 Des services requis ... 112 jeudi 19 avril 12
  133. 113 @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"); } Des services requis ... 113 jeudi 19 avril 12
  134. Les notifications OSGi OSGi génère de nombreuse évènements pour pouvoir

    interagir avec les couches bundle et services meilleur moyen de gérer le côté dynamique du framework Evènements disponibles : bundle events service events 114 114 jeudi 19 avril 12
  135. Les notifications OSGi Va permettre à notre application de savoir

    lorsqu’un nouveau service est 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 115 jeudi 19 avril 12
  136. Evènements possibles BundleInstalled BundleResolved BundleStarting BundleStarted BundleStopping BundleStopped BundleUninstalled BundleUpdated

    BundleUnresolved Installed Resolved Uninstalled Starting Active Stopping install update refresh stop start update refresh resolve uninstall uninstall 116 Evènements liés aux bundles OSGi 116 jeudi 19 avril 12
  137. 121 • Available events • ServiceArrival • ServiceDeparture • ServiceChanged

    Evènements liés aux services OSGi 121 jeudi 19 avril 12
  138. void bindService(@Observes @Filter("(twitter=true)") ServiceArrival evt) {} 123 • Available events

    • ServiceArrival • ServiceDeparture • ServiceChanged Evènements liés aux services OSGi 123 jeudi 19 avril 12
  139. void bindService(@Observes @Specification(SocialProvider.class) ServiceArrival evt) {} 124 • Available events

    • ServiceArrival • ServiceDeparture • ServiceChanged Evènements liés aux services OSGi 124 jeudi 19 avril 12
  140. void bindService(@Observes @Specification(SocialProvider.class) @Filter("(twitter=true)") ServiceArrival evt) {} 125 • Available

    events • ServiceArrival • ServiceDeparture • ServiceChanged Evènements liés aux services OSGi 125 jeudi 19 avril 12
  141. Inter-bundles events Communication entre les bundles OSGi gérés par Weld-OSGi

    Bundle A Bundle C Bundle B Weld-OSGi 126 126 jeudi 19 avril 12
  142. Inter-bundles events Communication entre les bundles OSGi gérés par Weld-OSGi

    Bundle A Bundle C Bundle B Weld-OSGi fire() 126 126 jeudi 19 avril 12
  143. Inter-bundles events Communication entre les bundles OSGi gérés par Weld-OSGi

    Bundle A Bundle C Bundle B Weld-OSGi fire() broadcast() 126 broadcast() 126 jeudi 19 avril 12
  144. Inter-bundles events 127 Synchronisation 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 performances Envoi des nouveaux ‘Post’ vers l’application cliente pour une mise à jour en temps réel 127 jeudi 19 avril 12
  145. Inter-bundles events @Inject Event<InterBundleEvent> event; event.fire(new InterBundleEvent(new SynchronizeTimeline())); public void

    synchronizeTimeline(@Observes InterBundleEvent event) {} 130 depuis un EJB @Schedule 130 jeudi 19 avril 12
  146. Inter-bundles events @Inject Event<InterBundleEvent> event; event.fire(new InterBundleEvent(new SynchronizeTimeline())); public void

    synchronizeTimeline(@Observes @Sent InterBundleEvent event) {} 131 depuis un EJB @Schedule 131 jeudi 19 avril 12
  147. Inter-bundles events @Inject Event<InterBundleEvent> event; event.fire(new InterBundleEvent(new SynchronizeTimeline())); public void

    synchronizeTimeline(@Observes @Specification(SynchronizeTimeline.class) InterBundleEvent event) {} 132 depuis un EJB @Schedule 132 jeudi 19 avril 12
  148. Inter-bundles events @Inject Event<InterBundleEvent> event; event.fire(new InterBundleEvent(new SynchronizeTimeline())); public void

    synchronizeTimeline(@Observes @Specification(SynchronizeTimeline.class) @Sent InterBundleEvent event) {} 133 depuis un EJB @Schedule 133 jeudi 19 avril 12
  149. Le futur de Weld-OSGi Intégration dans Weld core (en cours)

    Plugin Forge CDI 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 135 jeudi 19 avril 12
  150. Seam Social et son futur Seam Social est forkable sur

    github : http://github.com/seam/social Si vous êtes intéressés par Socializer (branche Twitter Bootstrap incluse) : https://github.com/antoinesd/Socializer Seam Social dépasse le simple cadre d’un module CDI Une tentative de JSR a été conduite mais rejetée Un projet « Java Social » est en cours de constitution Une communauté s’est constituée. Pour ceux que ça intéresse suivez @antoine_sd ou @Java_social 137 137 jeudi 19 avril 12
  151. Le mot de la fin CDI c’est bien mangez-en OSGi

    est beaucoup plus sympathique que vous ne le pensez Surtout avec Weld-OSGi Seam Social c’est cool mais le sera encore plus avec vous comme contributeur. 138 138 jeudi 19 avril 12