Fais ce que tu veux avec Java EE - Devoxx France 2014

2 329 vues

Publié le

Slides de la conférence donnée par Alexis Hassler et Antoine Sabot-Durand à Devoxx France 2014 sur les possibilités d'extensions de Java EE. Y sont évoqués l'utilisation de CDI et de son système d'extension ainsi que de JCA à travers le développement d'un connecteur MQTT.

Publié dans : Ingénierie
0 commentaire
4 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
2 329
Sur SlideShare
0
Issues des intégrations
0
Intégrations
446
Actions
Partages
0
Téléchargements
39
Commentaires
0
J’aime
4
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Fais ce que tu veux avec Java EE - Devoxx France 2014

  1. 1. @AlexisHassler @Antoine_SD#J3E Avec JavaEE, fais ce que tu veux… @Antoine_SD RedHat Senior Software Developer @AlexisHassler Sewatech Développeur, Formateur
  2. 2. @AlexisHassler @Antoine_SD#J3E Antoine Sabot-Durand •Senior Software Developer @Red Hat ! •Java & OSS : •CDI co-spec lead •CDI eco-system development •Tech Lead on Agorava ! •@antoine_sd •@cdispec
  3. 3. @AlexisHassler @Antoine_SD#J3E Alexis Hassler •Développeur, formateur Java •Indépendant ! ! •Co-leader du ! ! •@AlexisHassler
  4. 4. @AlexisHassler @Antoine_SD#J3E Plan CDI JCA Java EE Synthèse
  5. 5. @YourTwitterHandle#DVXFR14{session hashtag} @AlexisHassler @Antoine_SD#J3E Java EE
  6. 6. @AlexisHassler @Antoine_SD#J3E JavaEE ApplicationServer Java EE Java SE Containers (Servlet, EJB, CDI) Connectors Transactions Security Messaging Persistence … Outils
  7. 7. @AlexisHassler @Antoine_SD#J3E Java EE Front End Business Logic PersistenceJPA EJB 3 JSF
  8. 8. @AlexisHassler @Antoine_SD#J3E CDI Java EE JSF EJB 3 JPA
  9. 9. @AlexisHassler @Antoine_SD#J3E Java EE JSF JAX-RS WebSocket
  10. 10. @AlexisHassler @Antoine_SD#J3E Java EE Servlet JSP JSP debugging JSTL EL WebSocket JSF Managed
 Beans CDI Beans 
 Validation Commons
 Annotations JAX-RS JSON-P JASPIC JACC JAX-WS JAXB JAXM Web Services Metadata Enterprise Web Services Batch JMS JCA Java Mail EJB remote EJB entity JAX-RPC JAXR Application Deployment Concurrency Utilities EJB Lite JPA DI Interceptor JTA Management State Management
  11. 11. @AlexisHassler @Antoine_SD#J3E Java EE J2EE 1.2 Servlet / JSP EJB JMS RMI / IIOP J2EE 1.3 ! … ! EJB CMP JCA J2EE 1.4 ! … ! Web Services Management Deployment Java EE 5 ! … ! Annotations EJB 3 JPA WS-* JSF Java EE 6 … JPA 2 JSF 2 JAX-RS CDI @Inject BeanValidation Web Profile Managed Beans Java EE 7 ! … ! Batch Web Socket JSON-P @Transaction JMS 2 Web Profile Managed Beans 1999 10 specs 2001 13 specs 2003 20 specs 2006 23 specs 2009 28 specs 2013 30 specs
  12. 12. @AlexisHassler @Antoine_SD#J3E ! ! CDI JCA
  13. 13. @YourTwitterHandle#DVXFR14{session hashtag} @AlexisHassler @Antoine_SD#J3E Les bases de CDI
  14. 14. @AlexisHassler @Antoine_SD#J3E •CDI c’est beaucoup de choses •Un standard de l’IoC pour Java EE et Java SE •Un standard pour la gestion des contexts •Un Système de gestion d’événements •Un liant pour la plupart des spec Java EE •Le moteur pour faire évoluer Java EE grace aux extensions potables •Le tout tirant partie du typage fort de Java. Context & Dependency Injection
  15. 15. @AlexisHassler @Antoine_SD#J3E Les principaux jalons de CDI •Dates clés : •Décembre 2009 : CDI 1.0 •Juin 2013 : CDI 1.1 •Avril 2014 : CDI 1.2 •été 2014 : début du développement sur CDI 2.0 •Toutes les infos sur : http://cdi-spec.org •Implémentations : •JBoss Weld (RI) : WildFly, JBoss EAP, Glassfish, Weblogic •Apache OpenWebBeans : TomEE, Websphere
  16. 16. @AlexisHassler @Antoine_SD#J3E CDI est activé par défaut dans Java EE 7 •Dans Java EE 6, il faut ajouter le fichier beans.xml au déploiement •Le fichier est optionnel dans EE 7 mais permet d’assurer un fonctionnement compatible EE 6 beans.xml
  17. 17. @AlexisHassler @Antoine_SD#J3E Bean •En Java EE 6 et 7 tout est Managed Bean •le managed bean est le composant de base •il a un cycle de vie géré par le conteneur CDI •il est injectable •il supporte l’AOP via les intercepteur et les décorateurs •accessible depuis des environnements non CDI
  18. 18. @AlexisHassler @Antoine_SD#J3E Dependency Injection @Inject
  19. 19. @AlexisHassler @Antoine_SD#J3E public class HelloService {!     public String hello() {!         return "Hello World!";!     }! } Dependency Injection
  20. 20. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     private HelloService service;! !     @Inject!     public MyBean(HelloService service) {!         this.service = service;!     }!     public void displayHello() {!         display( service.hello();!     }! } Dependency Injection in constructor
  21. 21. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     private HelloService service;! !     @Inject!     public void setService(HelloService service) {!         this.service = service;!     }!     public void displayHello() {!         display( service.hello();!     }! } Dependency Injection in setter
  22. 22. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     @Inject HelloService service;! !     public void displayHello() {!         display( service.hello();!     }! } Dependency Injection in field
  23. 23. @AlexisHassler @Antoine_SD#J3E 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!";!     }! } Qualifiers
  24. 24. @AlexisHassler @Antoine_SD#J3E @Qualifier! @Retention(RUNTIME)! @Target({FIELD, TYPE, METHOD, PARAMETER}) ! public @interface French {}! ! @Qualifier! @Retention(RUNTIME)! @Target({FIELD, TYPE, METHOD, PARAMETER}) ! public @interface English {} Qualifiers
  25. 25. @AlexisHassler @Antoine_SD#J3E @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!";!     }! } Qualifiers
  26. 26. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @French HelloService service;!     public void displayHello() {!         display( service.hello();!     }! }! public class MyBean {!     @Inject @English HelloService service;!     public void displayHello() {!         display( service.hello();!     }! } Qualifiers
  27. 27. @AlexisHassler @Antoine_SD#J3E @Qualifier! @Retention(RUNTIME)! @Target({FIELD, TYPE, METHOD, PARAMETER}) ! public @interface Language {! !     Languages value();! ! @Nonbinding String description() default "";! !     public enum Languages { !         FRENCH, ENGLISH!     }! } Qualifiers avec membres
  28. 28. @AlexisHassler @Antoine_SD#J3E @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!";!     }! } Qualifiers
  29. 29. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @Language(ENGLISH) HelloService service;!     public void displayHello() {!         display( service.hello();!     }! }! ! public class MyBean {!     @Inject @Language(FRENCH) HelloService service;!     public void displayHello() {!         display( service.hello();!     }! } Qualifiers
  30. 30. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @French ! HelloService service;! }! ! @French @Console @Secured! public class FrenchHelloService implements HelloService {! ! } Qualifiers
  31. 31. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @French @Console! HelloService service;! }! ! @French @Console @Secured! public class FrenchHelloService implements HelloService {! ! } Qualifiers
  32. 32. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @French @Console @Secured ! HelloService service;! }! ! @French @Console @Secured! public class FrenchHelloService implements HelloService {! ! } Qualifiers
  33. 33. @AlexisHassler @Antoine_SD#J3E public class MyBean {!     @Inject @French @Console @Secured ! HelloService service;! }! ! @French @Secured! public class FrenchHelloService implements HelloService {! ! } Qualifiers
  34. 34. @AlexisHassler @Antoine_SD#J3E Qualifiers réservés @Default! @Any! @Named
  35. 35. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     @Inject Instance<HelloService> service;! !     public void displayHello() {!         display( service.get().hello() );!     }! } Programmatic lookup
  36. 36. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     @Inject Instance<HelloService> service;! !     public void displayHello() {!         if (!service.isUnsatisfied()) {!             display( service.get().hello() );!         }!     }! } Programmatic lookup
  37. 37. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     @Inject @Any Instance<HelloService> services;! !     public void displayHello() {!         for (HelloService service : services) {!             display( service.hello() );!         }!     }! } Programmatic lookup
  38. 38. @AlexisHassler @Antoine_SD#J3E public class MyBean {! !     @Inject @Any Instance<HelloService> services;! !     public void displayHello() {!         display( !             service.select(! new AnnotationLiteral()<French> {})!                 .get() );!     }! } Programmatic lookup
  39. 39. @AlexisHassler @Antoine_SD#J3E Programmatic lookup •L’injection programmatique permet de sélectionner un bean au runtime en fonction de son type et de ses qualifiers •Comme les qualifiers sont des annotations (donc non instantiables), il faut utiliser la classe AnnotationLiteral pour créer une instance de l’annotation •De même, pour palier au phénomène de type erasure on pourra utiliser la classe TypeLiteral pour rechercher un type paramétré
  40. 40. @AlexisHassler @Antoine_SD#J3E Contexts •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é’ •Possibilité de créer des scopes personnalisés •via les extensions •CDI contexts fournis dans la specification: •@Dependent (default) •@RequestScoped! •@SessionScoped! •@ConversationScoped! •@ApplicationScoped
  41. 41. @AlexisHassler @Antoine_SD#J3E @SessionScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts
  42. 42. @AlexisHassler @Antoine_SD#J3E @ApplicationScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts FAIL !!!
  43. 43. @AlexisHassler @Antoine_SD#J3E @ConversationScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts
  44. 44. @AlexisHassler @Antoine_SD#J3E @ThreadScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts
  45. 45. @AlexisHassler @Antoine_SD#J3E @HourScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts
  46. 46. @AlexisHassler @Antoine_SD#J3E @RandomScoped! public class CartBean {! !     public void addItem(Item item) {! ...!     } ! } Contexts
  47. 47. @AlexisHassler @Antoine_SD#J3E @Produces! public MyNonCDIClass myProducer() {! return new MyNonCdiClass();! }! ...! @Inject! MyNonCDIClass bean;! Producers
  48. 48. @AlexisHassler @Antoine_SD#J3E @Produces! @RequestScoped! public FacesContext produceFacesContext() {! return FacesContext.getCurrentInstance();! } Producers
  49. 49. @AlexisHassler @Antoine_SD#J3E @Produces! public Logger produceLog(InjectionPoint injectionPoint) {! return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());! } Producers
  50. 50. @AlexisHassler @Antoine_SD#J3E @Decorator! @Priority(Interceptor.Priority.APPLICATION)! public class HelloDecorator implements HelloService {! !     @Inject @Delegate HelloService service;! !     public String hello() {!         return service.hello() + "-decorated";!     }! } Decorators @Inject HelloService service;
  51. 51. @AlexisHassler @Antoine_SD#J3E @InterceptorBinding! @Target({METHOD, TYPE}) ! @Retention(RUNTIME)! public @interface Loggable {} Interceptors
  52. 52. @AlexisHassler @Antoine_SD#J3E @Interceptor @Loggable ! public class LogInterceptor {!   @AroundInvoke!   public Object log(InvocationContext ic) throws Exception {!    System.out.println("Entering " + ic.getMethod().getName());!         try {!             return ic.proceed(); !         } finally {!             System.out.println("Exiting " + ic.getMethod().getName());!         }!     } ! } Interceptors
  53. 53. @AlexisHassler @Antoine_SD#J3E @Loggable! public class MyBean {! !     @Inject HelloService service;! !     public void displayHello() {!         display( service.hello();!     }! } Interceptors
  54. 54. @AlexisHassler @Antoine_SD#J3E @Inject Event<Post> evt;! ! …! ! evt.fire(new Post("John Doe ", "Hello", ));! ! …! ! public void receiveEvt(@Observes Post evt) {!     System.out.println("Received : " + evt.message());! } Events
  55. 55. @YourTwitterHandle#DVXFR14{session hashtag} @AlexisHassler @Antoine_SD#J3E CDI extension
  56. 56. @AlexisHassler @Antoine_SD#J3E Extension pourquoi, comment ? •Pour manipuler les meta données du container : •AnnotatedType •InjectionPoint / InjectionTarget •BeanAttributes/Beans •Producer •Observer ! •En observant les événements déclenchés par CDI lors de l’initialisation du container
  57. 57. @AlexisHassler @Antoine_SD#J3E Créer une extension CDI •implémenter l’interface de marquage javax.enterprise.inject.spi.Extension ! •Ajouter une ou plusieurs methotdes qui « observent » les événements déclenchés par le conteneur au démarrage. ! •Déclarer le service provider en ajoutant le fichier:
 META-INF/services/javax.enterprise.inject.spi.Extension
 contenant le nom de la classe d’extension
  58. 58. @AlexisHassler @Antoine_SD#J3E public interface ProcessAnnotatedType<X> {
 ! public AnnotatedType<X> getAnnotatedType();
 
 public void setAnnotatedType(AnnotatedType<X> type);
 
 public void veto();
 } ! public interface AnnotatedType<X> extends Annotated {
 
 public Class<X> getJavaClass();
 
 public Set<AnnotatedConstructor<X>> getConstructors();
 
 public Set<AnnotatedMethod<? super X>> getMethods();
 
 public Set<AnnotatedField<? super X>> getFields();
 }
 Par exemple •On peut observer l’événement ProcessAnnotatedType pour changer les informations d’un type ou forcer le container à ignorer un type
  59. 59. @AlexisHassler @Antoine_SD#J3E public class VetoEntity implements Extension {
 /**
 * Version CDI 1.0
 */
 public void vetoEntityLegacy(@Observes ProcessAnnotatedType<?> pat) {
 AnnotatedType at = pat.getAnnotatedType();
 if (at.isAnnotationPresent(Entity.class))
 pat.veto(); 
 } /**
 * Version CDI 1.1+
 */
 public void vetoEntity(@Observes @WithAnnotations({Entity.class})ProcessAnnotatedType<?> pat) {
 pat.veto(); 
 } } Ignorer les entités •Une bonne pratique est d’éviter d’utiliser les entités JPA comme bean CDI (sauf utilisation avancée). •Cette extension montre comment exclure les entités JPA de l’ensemble des beans découverts.
  60. 60. @AlexisHassler @Antoine_SD#J3E Les choses à savoir… •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 ! •Les extensions peuvent aussi devenir des Beans (avec quelques restrictions)
  61. 61. @AlexisHassler @Antoine_SD#J3E Ajouter un Bean au container •Il existe plusieurs façon d’ajouter un bean à ceux découverts automatiquement au démarrage du container CDI. ! •La méthode la plus simple reste d’ajouter un AnnotatedType à l’ensemble de ceux découverts par CDI.
  62. 62. @AlexisHassler @Antoine_SD#J3E public class HashMapAsBeanExtension implements Extension{
 
 public void addHashMapAsAnnotatedType(@Observes BeforeBeanDiscovery bbd,BeanManager beanManager)
 {
 bbd.addAnnotatedType(beanManager.createAnnotatedType(HashMap.class));
 } 
 } Ajouter d’un Bean HashMap 1/2 •Il suffit d’observer l’événement BeforeBeanDiscovery et ajouter un AnnotatedType créé à partir de la classe HashMap. •En CDI 1.1+ on peut également observer AfterTypeDiscovery pour décider l’ajout après que tous les types aient été inspectés
  63. 63. @AlexisHassler @Antoine_SD#J3E @Decorator
 @Priority(Interceptor.Priority.APPLICATION)
 public abstract class MapDecorator implements Map{
 
 @Inject
 @Delegate
 Map delegate;
 
 @Override
 public Object put(Object key, Object value) {
 System.out.println("------- Putting Something in the Map -----------");
 if ("key".equals(key)) {
 System.out.println("==== Not adding key key ======");
 return null;
 } 
 return delegate.put(key,value);
 }
 } Ajouter d’un Bean HashMap 2/2 •Une fois que la HashMap est un bean on peut appliquer les services CDI sur celui-ci comme un décorateur.
  64. 64. @AlexisHassler @Antoine_SD#J3E CDI 1.1 Lifecycle Before Bean Discovery Process Bean Process Annotated Type Scan Archive Application Running After Deployment Validation Before Shutdown Undeploy Application Process Producer After Bean Discovery Process Injection Target Process Observer Method Process Injection Point Process Bean Attributes After Type Discovery événement unique événements multiples étape interne Deployment starts Bean eligibility check
  65. 65. @AlexisHassler @Antoine_SD#J3E Extension scheduler 1/4 •Cet exemple d’extension vient du projet Apache Deltaspike. Le code présenté est une version simplifiée du code d’origine. •Il s’agit de pouvoir planifier des tâches à partir d’une annotation @Schedule
  66. 66. @AlexisHassler @Antoine_SD#J3E public class SchedulerExtension implements Extension {
 private List<Class> foundManagedJobClasses = new ArrayList<Class>();
 private Scheduler scheduler;
 
 public <X> void findScheduledJobs(@Observes @WithAnnotations({ Scheduled.class }) ProcessAnnotatedType<X> pat) {
 Class<X> beanClass = pat.getAnnotatedType().getJavaClass();
 this.foundManagedJobClasses.add(beanClass);
 }
 
 public <X> void scheduleJobs(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
 initScheduler(afterBeanDiscovery)
 List<String> foundJobNames = new ArrayList<String>();
 for (Class jobClass : this.foundManagedJobClasses) {
 foundJobNames.add(jobClass.getSimpleName());
 this.scheduler.registerNewJob(jobClass);
 }
 }
 
 public <X> void stopScheduler(@Observes BeforeShutdown beforeShutdown) {
 if (this.scheduler != null) {
 this.scheduler.stop();
 this.scheduler = null;
 }
 } private void initScheduler(AfterBeanDiscovery afterBeanDiscovery) {
 this.scheduler = new QuartzScheduler();
 this.scheduler.start();
 } } Extension scheduler 2/4 (extension code)
  67. 67. @AlexisHassler @Antoine_SD#J3E CDI 1.1 Lifecycle Before Bean Discovery Process Bean Process Annotated Type Scan Archive Application Running After Deployment Validation Before Shutdown Undeploy Application Process Producer After Bean Discovery Process Injection Target Process Observer Method Process Injection Point Process Bean Attributes After Type Discovery événement unique événements multiples étape interne Deployment starts Bean eligibility check
  68. 68. @AlexisHassler @Antoine_SD#J3E public interface Scheduler<T>
 {
 void start();
 
 void stop();
 
 void pauseJob(Class<? extends T> jobClass);
 
 void resumeJob(Class<? extends T> jobClass);
 
 void interruptJob(Class<? extends T> jobClass);
 
 boolean isExecutingJob(Class<? extends T> jobClass);
 
 void registerNewJob(Class<? extends T> jobClass);
 
 void startJobManually(Class<? extends T> jobClass);
 
 <S> S unwrap(Class<? extends S> schedulerClass);
 } Extension scheduler 3/4 (scheduler interface)
  69. 69. @AlexisHassler @Antoine_SD#J3E @ApplicationScoped
 public class SchedulerProducer
 {
 @Inject
 private SchedulerExtension schedulerExtension;
 
 @Produces
 @ApplicationScoped
 protected Scheduler produceScheduler()
 {
 return this.schedulerExtension.getScheduler();
 }
 } Extension scheduler 4/4 (scheduler producer)
  70. 70. @YourTwitterHandle#DVXFR14{session hashtag} @AlexisHassler @Antoine_SD#J3E JCA
  71. 71. @AlexisHassler @Antoine_SD#J3E Java Connector Architecture
  72. 72. @AlexisHassler @Antoine_SD#J3E Java EE EISApp Connector Java EE
  73. 73. @AlexisHassler @Antoine_SD#J3E Java EE MQTT BrokerApp Connector Java EE / IoT
  74. 74. @AlexisHassler @Antoine_SD#J3E Outbound !
  75. 75. @AlexisHassler @Antoine_SD#J3E Java EE App Connector
  76. 76. @AlexisHassler @Antoine_SD#J3E Resources • Relational Databases • Transaction Processing System (CICS,Tuxedo,…) • Enterprise Resource Planning (SAP, Oracle Applications,…) • …
  77. 77. @AlexisHassler @Antoine_SD#J3E Java EE App DataSource
  78. 78. @AlexisHassler @Antoine_SD#J3E public class SomeNiceBean {
 
 @Resource
 DataSource dataSource;
 
 public void doTheJob() {
 Connection connection = dataSource.getConnection(); ...
 }
 }
  79. 79. @AlexisHassler @Antoine_SD#J3E Services communs •Pooling •Transactions (Local / XA) •Sécurité •…
  80. 80. @AlexisHassler @Antoine_SD#J3E public class SomeNiceBean {
 
 @Resource(name="mqtt/AnswerCF")
 ConnectionFactory connectionFactory;
 
 public void doTheJob() {
 Connection connection = connectionFactory.getConnection(); ...
 }
 }
  81. 81. @AlexisHassler @Antoine_SD#J3E Inbound !
  82. 82. @AlexisHassler @Antoine_SD#J3E Java EE App Connector
  83. 83. @AlexisHassler @Antoine_SD#J3E Message Driven Bean
  84. 84. @AlexisHassler @Antoine_SD#J3E Java EE MDB JMS Destination Connector
  85. 85. @AlexisHassler @Antoine_SD#J3E JMS Message Driven Bean @MessageDriven(activationConfig = {
 @ActivationConfigProperty(propertyName="destinationLookup",
 propertyValue="swt/Question"),
 @ActivationConfigProperty(propertyName="destinationType",
 propertyValue="javax.jms.Queue"),
 }) public class MyJmsBean implements MessageListener {
 @Override
 public void onMessage(Message message) { ...
 }
 }
  86. 86. @AlexisHassler @Antoine_SD#J3E Java EE MDB JMS Destination Connector
  87. 87. @AlexisHassler @Antoine_SD#J3E @MessageDriven(activationConfig = {
 @ActivationConfigProperty(propertyName="destinationType",
 propertyValue="javax.jms.Queue"),
 @ActivationConfigProperty(propertyName="destination",
 propertyValue="/queue/source"),
 @ActivationConfigProperty(propertyName="jndiParameters",
 propertyValue="java.naming.factory.initial=..."),
 @ActivationConfigProperty(propertyName="connectionFactory",
 propertyValue="XAConnectionFactory")
 })
 @ResourceAdapter("generic-jms-ra.rar")
 public class MyJmsBean implements MessageListener {
 @Override
 public void onMessage(Message message) { ...
 }
 } Generic JMS Message Driven Bean https://github.com/jms-ra/generic-jms-ra
  88. 88. @AlexisHassler @Antoine_SD#J3E Java EE MDB ! $ Telnet $ Console Connector https://github.com/dblevins/mdb-improvements
  89. 89. @AlexisHassler @Antoine_SD#J3E Java EE MDB ! ! Topic Connector https://github.com/hasalex/mqtt-ra
  90. 90. @AlexisHassler @Antoine_SD#J3E @MessageDriven(
 activationConfig = {
 @ActivationConfigProperty(propertyName="topicName", propertyValue="swt/Question")
 }
 )
 public class MyMqttBean implements MqttListener {
 @Override
 public void onMessage(Message message) { ...
 }
 } MQTT Message Driven Bean
  91. 91. @AlexisHassler @Antoine_SD#J3E http://pixabay.com/fr/des-animaux-asie-bleu-sombre-18719/
  92. 92. @AlexisHassler @Antoine_SD#J3E
  93. 93. @AlexisHassler @Antoine_SD#J3E MQTT •MQ Telemetry Transport Broker Consumer Consumer Consumer Producer Producer Producer Topic Topic Topic Topic SubscribePublish
  94. 94. @AlexisHassler @Antoine_SD#J3E MQTT 1999 2013
  95. 95. @AlexisHassler @Antoine_SD#J3E MQTT http://www.galuzzi.it/
  96. 96. @AlexisHassler @Antoine_SD#J3E MQTT http://commons.wikimedia.org/wiki/File:St_Jude_Medical_pacemaker_with_ruler.jpg
  97. 97. @AlexisHassler @Antoine_SD#J3E MQTT
  98. 98. @AlexisHassler @Antoine_SD#J3E MQTT / IoT •Embedded device •limited processor •limited memory resources •energy saving ! •Network •Limited bandwidth •Unreliable network
  99. 99. @AlexisHassler @Antoine_SD#J3E MQTT QoS •0 = At most once •Fire and forget •Message loss can occur •1 = At least once •Acknowledged delivery •Duplicates may occur •2 = Exactly once •Assured delivery
  100. 100. @AlexisHassler @Antoine_SD#J3E MQTT Client - Subscribe MQTT mqtt = new MQTT();
 mqtt.setHost(Settings.SERVER_URL);
 
 CallbackConnection connection = mqtt.callbackConnection();
 connection.listener(new Listener() { public void onPublish(UTF8Buffer topic, Buffer message, 
 Runnable ack) {
 System.out.println("Message arrived on topic " + …);
 ack.run();
 } });
 
 connection.connect(new Callback<Void>() {
 public void onSuccess(Void value) {
 connection.subscribe( new Topic[]{new Topic(Settings.TOPIC_NAME, QoS.AT_MOST_ONCE)},
 new Callback<byte[]>() {…}
 });
  101. 101. @AlexisHassler @Antoine_SD#J3E MQTT Client - Publish MQTT mqtt = new MQTT();
 mqtt.setHost(Settings.SERVER_URL);
 
 CallbackConnection connection = mqtt.callbackConnection();
 ! connection.connect(new Callback<Void>() {
 public void onSuccess(Void value) { connection.publish(Settings.TOPIC_NAME, "Message".getBytes(), QoS.AT_MOST_ONCE, false, new Callback<Void>(){…}
 });
  102. 102. @AlexisHassler @Antoine_SD#J3E M Q T T Outbound Connector
  103. 103. @AlexisHassler @Antoine_SD#J3E MQTT Connection Factory public class SomeNiceBean {
 
 @Resource(name="mqtt/QuestionCF")
 ConnectionFactory connectionFactory;
 
 public void doTheJob() {
 connectionFactory.getConnection() .publish(message);
 }
 }
  104. 104. @AlexisHassler @Antoine_SD#J3E Implémentation API ManagedConnection
 Factory ConnectionFactory ManagedConnection Connection Resource Adapter
  105. 105. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory @ConnectionDefinition (connectionFactory = MqttConnectionFactoryImpl.class, connectionFactoryImpl = MqttConnectionFactoryImpl.class,
 connection = BlockingConnection.class, connectionImpl = BlockingConnection.class)
 public class MqttManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation, Serializable {
 ... 
 }
  106. 106. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory @Override
 public ManagedConnection createManagedConnection (Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
 return new MqttManagedConnection(cxRequestInfo);
 }
  107. 107. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory @Override
 public ManagedConnection matchManagedConnections (Set connectionSet, Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
 ... } Connection Pool Management
  108. 108. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory ... public void setServerUrl(String serverUrl) {
 this.serverUrl = serverUrl;
 }
 public void setDefaultQosLevel(int qosLevel) {
 this.qosLevel = qosLevel;
 }
 public void setDefaultTopic(String defaultTopic) {
 this.defaultTopic = defaultTopic;
 } Configuration
  109. 109. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory ... @Override
 public Object createConnectionFactory (ConnectionManager cxManager) throws ResourceException {
 return new MqttConnectionFactoryImpl(this, cxManager);
 } ... ConnectionFactory
 Factory
  110. 110. @AlexisHassler @Antoine_SD#J3E Connection Factory public class MqttConnectionFactoryImpl implements Referenceable, MqttConnectionFactory { // fields : cxManager, managedConnectionFactory
 @Override
 public MqttConnection getConnection() {
 try { return (MqttConnection) cxManager
 .allocateConnection(managedConnectionFactory, null);
 } catch (ResourceException e) {
 throw new RuntimeException(e);
 }
 } ... 
 }
  111. 111. @AlexisHassler @Antoine_SD#J3E ManagedConnection
 Factory ConnectionFactory new ManagedConnection new ConnectionManager Connection ResourceAdapter new ConnectionEvent
 Listener XAResource LocalTransaction ManagedConnection
 MetaData
  112. 112. @AlexisHassler @Antoine_SD#J3E M Q T T Inbound Connector
  113. 113. @AlexisHassler @Antoine_SD#J3E @MessageDriven(
 activationConfig = {
 @ActivationConfigProperty(propertyName = "topicName", propertyValue = "swt/Question")
 }
 )
 public class MyMqttBean implements MqttListener {
 @Override
 public void onMessage(Message message) { ...
 }
 } MQTT Message Driven Bean
  114. 114. @AlexisHassler @Antoine_SD#J3E ResourceAdapterListener ActivationSpec Message XAResource WorkerManager BootstrapContext
  115. 115. @AlexisHassler @Antoine_SD#J3E Connector API public interface MqttListener {
 void onMessage(Message message);
 } public class Message {
 private byte[] payload;
 
 public Message(byte[] payload) {
 this.payload = payload;
 }
 // + Getter
 }
  116. 116. @AlexisHassler @Antoine_SD#J3E Connector Implementation @Connector(
 vendorName = "sewatech", version = "0.1", eisType = "MQTT Inbound Adapter",
 transactionSupport = NoTransaction) public class MqttAdapter implements ResourceAdapter {
 
 ... 
 }
  117. 117. Lifecycle http://commons.wikimedia.org/wiki/File:Drohnenpuppen_81b.jpg
  118. 118. @AlexisHassler @Antoine_SD#J3E Endpoint Started Stopped start()stop() Activated Deactivated endpointActivation() endpointDeactivation() Lifecycle
  119. 119. @AlexisHassler @Antoine_SD#J3E Lifecycle public class MqttAdapter implements ResourceAdapter {
 ! public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
 ... } ! public void stop() {
 ... }
 ... 
 }
  120. 120. @AlexisHassler @Antoine_SD#J3E Connector / Endpoints public class MqttAdapter implements ResourceAdapter {
 ... public void endpointActivation(MessageEndpointFactory factory, ActivationSpec activationSpec) throws ResourceException { ... } public void endpointDeactivation(MessageEndpointFactory factory, ActivationSpec activationSpec) { ... }
 }
  121. 121. @AlexisHassler @Antoine_SD#J3E Endpoint Activation public void endpointActivation (MessageEndpointFactory mdbFactory, ActivationSpec activationSpec) throws ResourceException {
 ActivationSpecBean spec = (ActivationSpecBean) activationSpec;
 MqttListener mdb = (MqttListener) mdbFactory.createEndpoint(null);
 ! MQTT mqtt = new MQTT();
 // Connexion via le client MQTT... }
  122. 122. Pool http://www.flickr.com/photos/gingerfuhrer/2883491950/
  123. 123. @AlexisHassler @Antoine_SD#J3E Pool Java EE ! ! Topic MDB Connector
  124. 124. @AlexisHassler @Antoine_SD#J3E @MessageDriven(
 activationConfig = {
 @ActivationConfigProperty(propertyName = "topicName", propertyValue = "swt/Question"),
 @ActivationConfigProperty(propertyName = "poolSize", propertyValue = "10")
 }
 )
 public class MyMqttBean implements MqttListener {
 @Override
 public void onMessage(Message message) { ...
 }
 } Pool
  125. 125. @AlexisHassler @Antoine_SD#J3E Pool public void endpointActivation (MessageEndpointFactory mdbFactory, ActivationSpec activationSpec) throws ResourceException { BlockingQueue<MqttMessageListener> pool = new ArrayBlockingQueue<>(poolSize);
 for (int i = 0; i < poolSize; i++) {
 pool.add(mdbFactory.createEndpoint(null)));
 } ... }
  126. 126. Threads https://www.flickr.com/photos/mckaysavage/6491930649/
  127. 127. @AlexisHassler @Antoine_SD#J3E Threads public void endpointActivation (MessageEndpointFactory mdbFactory, ActivationSpec activationSpec) throws ResourceException { ... WorkManager workManager = bootstrapContext.getWorkManager() workManager.startWork(new Work() {
 @Override
 public void run() {
 }
 
 @Override
 public void release() {
 }
 }); ... }
  128. 128. @AlexisHassler @Antoine_SD#J3E MQTT Broker WS Connector ! mqtt-ra.rar Application (w. MDB) mqtt-ra-example.war MQTT Client JS
  129. 129. @AlexisHassler @Antoine_SD#J3E @MessageDriven
 public class MyMqttBean implements MqttListener { 
 @TopicName("swt/Question")
 public void onQuestion(Message message) { ...
 }
 ! @TopicName("swt/Answer")
 public void onAnswer(Message message) { ...
 }
 ! } Message Driven Bean ++
  130. 130. @AlexisHassler @Antoine_SD#J3E Connector ! mqtt-ra.rar Application (w. MDB) mqtt-ra-example.war MQTT Broker (mosquitto) MQTT Client mosquitto 
 pub/sub
  131. 131. @YourTwitterHandle#DVXFR14{session hashtag} @AlexisHassler @Antoine_SD#J3E JCA
 // CDI
  132. 132. @AlexisHassler @Antoine_SD#J3E CDI JCA
  133. 133. @AlexisHassler @Antoine_SD#J3E Managed Connection Factory @ConnectionDefinition (connectionFactory = MqttConnectionFactoryImpl.class, connectionFactoryImpl = MqttConnectionFactoryImpl.class,
 connection = BlockingConnection.class, connectionImpl = BlockingConnection.class)
 public class MqttManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation, Serializable {
 @Inject
 ResourceAdapter ra;
 ! }
  134. 134. @AlexisHassler @Antoine_SD#J3E JCA CDI
  135. 135. @AlexisHassler @Antoine_SD#J3E public class SomeNiceBean {
 
 @Inject
 MqttConnectionFactory connectionFactory;
 
 public void doTheJob() {
 Connection connection = connectionFactory.getConnection(); ...
 }
 } ! javax.enterprise.inject.
 UnsatisfiedResolutionException
  136. 136. @AlexisHassler @Antoine_SD#J3E public class SomeNiceBean {
 
 @Inject
 MqttConnectionFactory connectionFactory;
 
 public void doTheJob() {
 Connection connection = connectionFactory.getConnection(); ...
 }
 } public class MqttResourceProducer {
 ! @Produces @Resource(name="mqtt/AnswerCF")
 private MqttConnectionFactory answerConnectionFactory;
 
 }
  137. 137. @AlexisHassler @Antoine_SD#J3E Java EE 8 •Implicit Producers ?
 
 
 •Ambiguities ? •Qualifiers ?
  138. 138. @AlexisHassler @Antoine_SD#J3E public class SomeNiceBean {
 
 @Inject @Answer
 MqttConnectionFactory connectionFactory;
 
 public void doTheJob() {
 Connection connection = connectionFactory.getConnection(); ...
 }
 } public class MqttResourceProducer {
 
 @Produces @Answer @Resource(name="mqtt/AnswerCF")
 private MqttConnectionFactory answerConnectionFactory;
 
 }
  139. 139. @AlexisHassler @Antoine_SD#J3E ! JCA // CDI
  140. 140. @AlexisHassler @Antoine_SD#J3E JCA UserTransaction Concurrency Service ManagedConnection
 Factory ConnectionFactory new ManagedConnection new ConnectionManager Connection ResourceAdapter new ConnectionEvent
 Listener XAResource LocalTransaction ManagedConnection
 MetaData WorkerManager
  141. 141. @AlexisHassler @Antoine_SD#J3E CDI UserTransaction ManagedExecutor Service ConnectionFactory Producer ConnectionFactory new Connection LocalTransaction
  142. 142. @AlexisHassler @Antoine_SD#J3E Outbound Connector ! JCA < CDI
  143. 143. @AlexisHassler @Antoine_SD#J3E @MessageDriven(
 activationConfig = {
 @ActivationConfigProperty(propertyName = "topicName", propertyValue = "swt/Question")
 }
 )
 public class MyMqttBean implements MqttListener {
 @Override
 public void onMessage(Message message) { ...
 }
 } Message Driven Bean
  144. 144. @AlexisHassler @Antoine_SD#J3E @MqttDriven
 public class MyMqttBean { 
 @TopicName("swt/Question")
 public void onQuestion(Message message) { ...
 }
 ! @TopicName("swt/Answer")
 public void onAnswer(Message message) { ...
 }
 ! } Message Driven Bean
  145. 145. @AlexisHassler @Antoine_SD#J3E Inbound Connector ! JCA > CDI
  146. 146. @AlexisHassler @Antoine_SD#J3E Java EE Application Server App CDI App CDI App CDI JCA
  147. 147. @AlexisHassler @Antoine_SD#J3E ? http://pixabay.com/fr/point-d-interrogation-boule-demande-65833/
  148. 148. @AlexisHassler @Antoine_SD#J3E Exemples ! ! •https://github.com/antoinesd/cdi-demo ! •https://github.com/hasalex/mqtt-ra

×