Sviluppare su OSGi con Camel e GWT

108

description

Slides per l'incontro "Aperitivo tecnologico" del GDG Firenze http://www.gdg-firenze.info/ del 16 dicembre 2013. Argomenti: Introduzione ad OSGi e ServiceMix Introduzione ad Apache Camel Utilizzare GWT su ServiceMix SensorMix: Architettura di esempio Cool Facts: perchè ci piace questa architettura

Transcript of Sviluppare su OSGi con Camel e GWT

Page 1: Sviluppare su OSGi con Camel e GWT
Page 2: Sviluppare su OSGi con Camel e GWT

Sviluppare su OSGIcon Camel e GWTAperitivo tecnologico del GDG Firenzehttp://www.gdg-firenze.info/

Cristiano Costantini - Giuseppe Gerla - Michele Ficarra - Sergio Ciampi - Stefano Cigheri

Page 3: Sviluppare su OSGi con Camel e GWT

Chi Siamo

Cristiano

Giuseppe

Michele

Sergio

Stefano

Aperitivo Osgi, Camel e GWT 3/108

Page 4: Sviluppare su OSGi con Camel e GWT

Sommario

Aperitivo Osgi, Camel e GWT

Introduzione ad OSGi e ServiceMix

Introduzione ad Apache Camel

Utilizzare GWT su ServiceMix

SensorMix: Architettura di esempio

Cool Facts: perchè ci piace questa architettura

·

·

·

·

·

4/108

Page 5: Sviluppare su OSGi con Camel e GWT

Introduzione a OSGi e ServiceMixOvvero un approccio modulare per backend SOA

Page 6: Sviluppare su OSGi con Camel e GWT

OSGi: questo sconosciuto

Il nucleo delle specifiche definisce la gestione del modello del ciclo di vita delsoftware, i moduli (chiamati bundles), un service registry e un ambiente diesecuzione.

Aperitivo Osgi, Camel e GWT

OSGi: Open Service Gateway initiative

OSGi Alliance: organizzazione fondata nel 1999 da Ericsson, IBM, Oracle e altri

OSGi Framework: è un layer di modularità per la piattaforma Java

·

·

·

6/108

Page 7: Sviluppare su OSGi con Camel e GWT

Una Metafora:Pensate ai servizi di Windows o demoni Unix ma completamente Java

Aperitivo Osgi, Camel e GWT 7/108

Page 8: Sviluppare su OSGi con Camel e GWT

Perchè nasce OSGi

OSGi nasce con lo scopo di creare sistemi embedded per mercati residenziali,automotive e M2M. In questi contesti è spesso necessario comunicare con idevices attraverso protocolli differenti.

Il fine, quindi, era quello di fornire un modello di programmazione capace direalizzare servizi end-to-end creando uno strato di astrazione che unificasse idifferenti protocolli.

Aperitivo Osgi, Camel e GWT 8/108

Page 9: Sviluppare su OSGi con Camel e GWT

Perchè si espande

We’ve all used development platforms in the past,such as Java Enterprise Edition (JEE), and eventhough there have been great advances in thisindustry, we’re still building large complex systems,which are hard to develop, maintain, and extend.Alexandre de Castro AlvesOSGi in Depth - Manning, pagina 1, riga 1

Aperitivo Osgi, Camel e GWT

9/108

Page 10: Sviluppare su OSGi con Camel e GWT

Implementazioni OSGi

Esistono diverse implementazioni di OSGi. Quelle più complete sono:

Aperitivo Osgi, Camel e GWT

Apache Felix

Eclipse Equinox

Knopflerfish

·

·

·

10/108

Page 11: Sviluppare su OSGi con Camel e GWT

Service

Lifecycle

Module

Come è fatto un framework OSGi

Il framework può essere rappresentato con trelayer:

Aperitivo Osgi, Camel e GWT

Il module layer definisce il concetto di moduloOSGi: il Bundle

Il lifecycle layer definisce come i bundles sonodinamicamente installati e gestiti nelframework OSGi

Il service layer supporta e promuove unmodello di sviluppo di applicazioni flessibileche incapsula concetti resi di uso comune dalservice-oriented programming

·

·

·

11/108

Page 12: Sviluppare su OSGi con Camel e GWT

Il “Module layer”

Il cuore del module layer è il Bundle.

Un Bundle è un JAR che contiene metadati extra(manifest).

A differenza dei JAR il bundle ha:

Grazie al manifest è possibile estendere lavisibilità del classpath dichiarando esplicitamentele proprie dipendenze

Aperitivo Osgi, Camel e GWT

un classpath “ristretto” al solo bundle

un manifest più ricco

·

·

12/108

Page 13: Sviluppare su OSGi con Camel e GWT

Il manifest OSGi

Nel manifest viene specificato anche:

Esempi:

Aperitivo Osgi, Camel e GWT

L’identificazione e la descrizione

Il classloading

L’attivazione

·

·

·

13/108

Page 14: Sviluppare su OSGi con Camel e GWT

Il manifest OSGiManifest di un semplice JAR compilato con maven

Aperitivo Osgi, Camel e GWT

Manifest-Version: 1.0Build-Jdk: 1.7.0_40Built-By: gdg-firenzeCreated-By: Apache Maven

MANIFEST.MF

14/108

Page 15: Sviluppare su OSGi con Camel e GWT

Il manifest OSGiManifest di un Bundle

Aperitivo Osgi, Camel e GWT

Manifest-Version: 1.0Bnd-LastModified: 1386750447262Build-Jdk: 1.7.0_40Built-By: gdg-firenzeBundle-ManifestVersion: 2Bundle-Name: GDG Firenze :: Sensormix :: Example BundleBundle-SymbolicName: example-bundleBundle-Vendor: GDG Firenze :: Sensormix TeamBundle-Version: 1.0.0.SNAPSHOTBundle-Activator: com.google.developers.gdgfirenze.dataservice.ActivatorCreated-By: Apache Maven Bundle PluginExport-Package: com.google.developers.gdgfirenze.model;version="1.0.0.SNAPSHOT", com.google.developers.gdgfirenze.osgi;version="1.0.0.SNAPSHOT", com.google.developers.gdgfirenze.service;version="1.0.0.SNAPSHOT"Import-Package: javax.jws,javax.jws.soap,javax.xml.bind.annotation,javax.xml.wsTool: Bnd-1.50.0

MANIFEST.MF

15/108

Page 16: Sviluppare su OSGi con Camel e GWT

Il “Lifecycle layer”Il lifecycle layer ha due scopi:

Esternamente gestisce il ciclo di vita del bundle.

Aperitivo Osgi, Camel e GWT 16/108

Page 17: Sviluppare su OSGi con Camel e GWT

Il “Lifecycle layer”Il lifecycle layer ha due scopi:

Internamente definisce Bundle Activator

= public static void main(String[] args)

Aperitivo Osgi, Camel e GWT 17/108

Page 18: Sviluppare su OSGi con Camel e GWT

Il “Service layer”

L’OSGi service layer promuove l’approccio basato su interface ed in particolarela separazione tra interfacce e implementazioni.

I Servizi OSGi sono interfacce Java che rappresentano un contratto tra il serviceprovider e i service clients.

Aperitivo Osgi, Camel e GWT 18/108

Page 19: Sviluppare su OSGi con Camel e GWT

OSGi: la Service Platform

L’OSGi definisce un set minimo di servizi peragevolare lo sviluppo di applicazioni modulari

Aperitivo Osgi, Camel e GWT

Cofiguration Admin (hot configuration)

Event Admin

Console Admin

Log Service

Blueprint component framework

·

·

·

·

·

19/108

Page 20: Sviluppare su OSGi con Camel e GWT

Karaf: un OSGi container

Karaf è un OSGi container in cui sono deployati bundles (e servizi) aggiuntivi perfornire ulteriori funzionalità tra cui Hot deployment, Dynamic configuration,Logging System, Extensible Shell console (SSH)

Karaf è un chiaro esempio di architettura basata su OSGi

Aperitivo Osgi, Camel e GWT 20/108

Page 21: Sviluppare su OSGi con Camel e GWT

ServiceMix: un ESB su OSGi

ServiceMix estende ulteriormente Karaf con funzionalità perimplementare un Enterprise Service Bus.

Le principali funzionalità di ServiceMix sono:

Altre funzionalità offerte da ServiceMix:

Aperitivo Osgi, Camel e GWT

reliable messaging with Apache ActiveMQ

messaging, routing and Enterprise Integration Patterns withApache Camel

WS-\* and RESTful web services with Apache CXF

OSGi-based server runtime powered by Apache Karaf

·

·

·

·

loosely coupled integration between all the other components with Apache ServiceMix NMR includingrich Event, Messaging and Audit API

complete WS-BPEL engine with Apache ODE

·

·

21/108

Page 22: Sviluppare su OSGi con Camel e GWT

OSGi e SpringUso di Spring dentro a Karaf/ServiceMix

Lo springframework fornisce molte features interessanti (dependency injection, ORM, AOP,...)

Lo Spring Deployer riconosce i file Spring all'interno del folder META-INF/spring di un Jar, e ne istanzia ibean che vi sono definiti, senza necessità di utilizzare le API OSGi

Aperitivo Osgi, Camel e GWT

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="consumer" class="com.myapplication.HelloWorldConsumer" destroy-method="osgiDestroy" init-method="osgiInit"/> </beans>

SPRING

22/108

Page 23: Sviluppare su OSGi con Camel e GWT

OSGi e SpringSpring DM

Spring DM permette di utilizzare servizi OSGi da Spring in modo trasparente.

Aperitivo Osgi, Camel e GWT

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">

<osgi:service ref="eventService" interface="com.myapplication.HelloWorldService" />

</beans>

SPRING DM

23/108

Page 24: Sviluppare su OSGi con Camel e GWT

Introduzione ad Apache CamelOvvero un modo agile per integrare sistemi eterogenei

Page 25: Sviluppare su OSGi con Camel e GWT

“Integrare”

Cosa si intende quando parliamo di integrazione?

Trovare una soluzione al seguente problema:

Come posso far funzionare insieme molteplici

applicazioni attraverso lo scambio di

informazioni?

Aperitivo Osgi, Camel e GWT

25/108

Page 26: Sviluppare su OSGi con Camel e GWT

Enterprise Integration Patterns

Gli Enterprise Integration Patters offrono soluzioni per affrontare il precedenteproblema.

Cosa sono gli EIP?

Aperitivo Osgi, Camel e GWT 26/108

Page 27: Sviluppare su OSGi con Camel e GWT

Un libro!

Gregor Hohpe and Bobby WoolfAddison-Wesley 2003

Page 28: Sviluppare su OSGi con Camel e GWT

EIP Importanti

Aperitivo Osgi, Camel e GWT

Message Channel:How does one application communicate with another using messaging?

Message:How can two applications connected by a message channel exchange a piece of information?

Message Router:How can you decouple individual processing steps so that messages can be passed to different filters depending on a set of conditions?

Message Translator:How can systems using different data formats communicate with each other using messaging?

Message Endpoint:How does an application connect to a messaging channel to send and receive messages?

Dead Letter Channel:What will the messaging system do with a message it cannot deliver?

Message Bus:What is an architecture that enables separate applications to work together, but in a decoupled fashion such that applications can be easily added or removed without affectingthe others?

Command Message:How can messaging be used to invoke a procedure in another application?

Document Message:How can messaging be used to transfer data between applications?

Event Message:How can messaging be used to transmit events from one application to another?

Request-Reply:When an application sends a message, how can it get a response from the receiver?

Canonical Data Model:How can you minimize dependencies when integrating applications that use different data formats?

28/108

Page 29: Sviluppare su OSGi con Camel e GWT

Come si può fare integrazione?

I principali metodi tramite cui avviene integrazione sono:

Gli EIP si focalizzano sulla integrazione via “messaging” e definiscono unanotazione per rappresentare le soluzioni di integrazione.

Aperitivo Osgi, Camel e GWT

Scambio di file

Database condiviso

Remote Procedure Invocation

Messaging

·

·

·

·

29/108

Page 30: Sviluppare su OSGi con Camel e GWT

Notazione EIP

http://www.eaipatterns.com/toc.html

Page 31: Sviluppare su OSGi con Camel e GWT

Soluzioni con EIP

Aperitivo Osgi, Camel e GWT 31/108

Page 32: Sviluppare su OSGi con Camel e GWT

Soluzioni con EIP

Aperitivo Osgi, Camel e GWT 32/108

Page 33: Sviluppare su OSGi con Camel e GWT

Soluzioni con EIP

Attenti a questa qui!

Aperitivo Osgi, Camel e GWT 33/108

Page 34: Sviluppare su OSGi con Camel e GWT

Come implementare facilmente EIP?(domanda retorica)

Integrare è però difficile perchè esiste una vasta eterogeneità di protocolli,interfacce e formati.

Come si possono implementare su una piattaforma Java gli EnterpriseIntegration Pattern?

con

Apache CamelConcise Application Messaging Exchange Language

Aperitivo Osgi, Camel e GWT

“ ”

34/108

Page 35: Sviluppare su OSGi con Camel e GWT

Apache Camel

Apache Camel è un framework di integrazione open-sorce versatile basato sugliEnterprise Integration Patterns del libro di Hohpe e Woolf.

Include un vasto insieme di componenti per funzionare con molti protocolli ditrasporto e formati dati e permette di definire regole di instradamento eintermediazione attraverso l’uso di domain-specific language.

...si presta talmente bene alla integrazione che ServiceMix, dalla versione 3 alla4, ha abbandonato la tecnologia JBI per adottare un nuovo approccio allaintegrazione basato su Camel e OSGi.

Aperitivo Osgi, Camel e GWT 35/108

Page 36: Sviluppare su OSGi con Camel e GWT

Esempio: Content Based Router

from newOrder choice when isWidget to widget otherwise to gadget

Aperitivo Osgi, Camel e GWT 36/108

Page 37: Sviluppare su OSGi con Camel e GWT

from newOrder choice when isWidget to widget otherwise to gadget

Content Based Router in Java DSL

Aperitivo Osgi, Camel e GWT

public class MyRoute extends RouteBuilder {

public void configure() throws Exception { from("activemq:queue:newOrder") .choice() .when(xpath("/order/product = 'widget'")) .to("activemq:queue:widget") .otherwise() .to("activemq:queue:gadget") .end(); }}

JAVA DSL

37/108

Page 38: Sviluppare su OSGi con Camel e GWT

from newOrder choice when isWidget to widget otherwise to gadget

Content Based Router in Spring XML

Aperitivo Osgi, Camel e GWT

<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="activemq:queue:newOrder"/> <choice> <when> <xpath>/order/product = 'widget'</xpath> <to uri="activemq:queue:widget"/> </when> <otherwise> <to uri="activemq:queue:gadget"/> </otherwise> </choice> </route></camelContext>

SPRING XML

38/108

Page 39: Sviluppare su OSGi con Camel e GWT

Una applicazione Camel completa:

Aperitivo Osgi, Camel e GWT

import org.apache.camel.CamelContext;import org.apache.camel.builder.RouteBuilder;import org.apache.camel.impl.DefaultCamelContext;

public class CamelExample { public static void main(String[] args) throws Exception {

CamelContext context = new DefaultCamelContext();

context.addRoutes(new RouteBuilder() { public void configure() { from("jetty:http://0.0.0.0:8080/tellMeSomething") .transform(simple("You say ${in.body}")) .to("velocity:response.vm"); } });

context.start(); System.out.println("Press ENTER to exit"); System.in.read();

context.stop(); }}

SPRING XML

39/108

Page 40: Sviluppare su OSGi con Camel e GWT

Camel in ServiceMix

Una volta attivati i bundle di Camel su Karaf-ServiceMix...

Aperitivo Osgi, Camel e GWT 40/108

Page 41: Sviluppare su OSGi con Camel e GWT

Camel in ServiceMix

...è possibile definire rotte direttamente nei file Spring XML, oppure utilizzare dei RouteBuilder in Java peravviare delle applicazioni che usano Camel all’interno di ServiceMix.

Aperitivo Osgi, Camel e GWT

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans">

<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="jetty:http://0.0.0.0:8080/tellMeSomething"/> <convertBodyTo type="java.lang.String"/> <transform> <simple>You say ${in.body}</simple> </transform> <to uri="velocity:response.vm" /> </route>

</camelContext>

</beans>

SPRING XML

41/108

Page 42: Sviluppare su OSGi con Camel e GWT

Camel: componenti162 componenti elencati su camel.apache.org/components.html

ActiveMQ ActiveMQBroker Activiti AHC AMQP APNS Atom Avro

AWS-CW AWS-DDB AWS-S3 AWS-SDB AWS-SES AWS-SNS AWS-SQS Bean

Bean Validation Browse Cache Class CMIS Cometd Context ControlBus

CouchDB Crypto CXF CXF Bean CXFRS DataFormat DataSet Db4o

Direct Direct-VM Disruptor DNS EJB ElasticSearch Esper EventAdmin

Exec Facebook File Flatpack FOP FreeMarker FTP FTPS

GAuth Geocoder GHttp GLogin GMail GTask GuavaEventBus Hazelcast

HBase HDFS Hibernate HL7 HTTP HTTP4 iBATIS IMAP

IMAPS Infinispan IRC JavaSpace JBI JCIFS jclouds JCR

JDBC Jetty JGroups JMS JMX JPA Jsch JT/400

Kestrel Krati Language LDAP Log Lucene MINA MINA2

Mock MongoDB MQTT MSV Mustache MVEL MyBatis Nagios

Netty Netty HTTP NMR OptaPlanner Pax-Logging POP3 POP3S Printer

Properties Quartz Quartz2 Quickfix RabbitMQ RCode Ref Restlet

Aperitivo Osgi, Camel e GWT 42/108

Page 43: Sviluppare su OSGi con Camel e GWT

Camel: data format25+ data format elencati su camel.apache.org/data-format.html

Avro Base64 BeanIO Bindy Castor

Crypto CSV EDI Flatpack DataFormat GZip data format

HL7 DataFormat JAXB JiBX JSON PGP

Protobuf Serialization SOAP String XmlBeans

XmlJson XMLSecurity DataFormat XStream Zip DataFormat Zip File DataFormat

Aperitivo Osgi, Camel e GWT 43/108

Page 44: Sviluppare su OSGi con Camel e GWT

Utilizzare GWT su ServiceMixOvvero un modo diverso per fare Web Application

Page 45: Sviluppare su OSGi con Camel e GWT

SOA e SOFEA

Aperitivo Osgi, Camel e GWT

http://raibledesigns.com/

45/108

Page 46: Sviluppare su OSGi con Camel e GWT

Framework Web per SOFEA

Aperitivo Osgi, Camel e GWT

http://raibledesigns.com/

46/108

Page 47: Sviluppare su OSGi con Camel e GWT

ServiceMix e le Web Application

ServiceMix non nasce come Web Container ma permette lo stesso di deployaredelle web application.

In particolare risulta molto interessante qualora l’applicazione segua l’approccioprecedente.

Aperitivo Osgi, Camel e GWT 47/108

Page 48: Sviluppare su OSGi con Camel e GWT

La nostra SOFEA

Aperitivo Osgi, Camel e GWT 48/108

Page 49: Sviluppare su OSGi con Camel e GWT

Deploy di WAR sotto Karaf/ServiceMixWAR Deployer

Il WAR Deployer è un bundle che si occupa del deploy di Web Application suKaraf/ServiceMix

Cosa fa?

Ma basta?

Aperitivo Osgi, Camel e GWT

Cerca il file /WEB-INF/web.xml

Se lo trova, pubblica i file statici e le Servlet definite nel web.xml via HTTP

·

·

49/108

Page 50: Sviluppare su OSGi con Camel e GWT

Deploy di WAR sotto Karaf/ServiceMixIl WAR ha bisogno di modifiche

É raccomandato fare uno Skinny war e usare dipendenze di Bundle (usando ilmaven-war-plugin e il maven-bundle-plugin)

Abbiamo Finito?

Aperitivo Osgi, Camel e GWT

Deve avere un file /META-INF/MANIFEST.MF nella root del JAR

Il MANIFEST.MF deve contenere:

·

·

L'header Web-ContextPath (l'applicazione verrà pubblicata al contextpath specificato da questo header)

L'header Bundle-ClassPath: .,WEB-INF/classes (informaKaraf/ServiceMix dove sono i bytecode)

-

-

50/108

Page 51: Sviluppare su OSGi con Camel e GWT

Applicazioni GWT sotto Karaf/ServiceMix

Aperitivo Osgi, Camel e GWT

...anche gwt-servlet.jar ha bisogno di modifiche!

GWT non è predisposto per essere usato in OSGi.

Non è un bundle perchè al manifest della gwt-servlet.jar mancano gli header OSGi.

E allora?

51/108

Page 52: Sviluppare su OSGi con Camel e GWT

Come usare GWT con OSGiQuattro strade:

Ci sono 4 strade per ottenere un gwt-servlet.jar OSGi compliant e poterlo deployare su Karaf/ServiceMix.

Aperitivo Osgi, Camel e GWT

Caso 1:

Compilarsi a mano il gwt-servlet.jar con gli header OSGi necessari

Caso 2:

Deployare il Jar non-OSGi configurandolo al momento della installazione su Karaf/ServiceMixpassando come parametro le informazioni che dovrebbero essere contenute nel MANIFEST.MF

Caso 3:

Aspettare che il ServiceMix Team rilasci il Bundle per GWT-Servlet con gli header OSGi per laversione 2.6.0

Caso 4:

Sperare che il GWT Project Team accetti la patch, che abbiamo proposto, nella versione GWT2.6.0 o successive.

52/108

Page 53: Sviluppare su OSGi con Camel e GWT

Come usare GWT con OSGiChe cosa significa?

Aperitivo Osgi, Camel e GWT

Caso 1:git fetch https://gwt.googlesource.com/gwt refs/changes/51/5351/7git checkout FETCH_HEADant distinstall -s mvn:com.google.gwt/gwt-servlet/2.6.0

Caso 2:install -s wrap:mvn:com.google.gwt/gwt-servlet/2.6.0$Bundle-Name=GWT-Servlet&Bundle-SymbolicName=com.google.gwt.gwt-servlet&Bundle-Version=2.6.0&Export-Package=com.google.gwt.user.client.rpc.*,org.hibernate.validator.engine,com.google.web.bindery.requestfactory.vm.impl.*,!javax.validation,!org.hibernate.validator.*,!*.client.*,!*.impl.*,*&Import-Package=javax.servlet.*,javax.validation;resolution:=optional,org.json;resolution:=optional,javax.validation.*;resolution:=optional,org.json.*;resolution:=optional,!com.google.gwt.*,*;resolution:=optional

Caso 3:install -s mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.gwt-servlet/2.6.0_1

Caso 4:install -s mvn:com.google.gwt/gwt-servlet/2.6.0

53/108

Page 54: Sviluppare su OSGi con Camel e GWT

Esempi GWT su ServiceMix

Abbiamo adattato alcuni esempi della distribuzione GWT per funzionare suKaraf/ServiceMix:

https://github.com/cristcost/gwt-karaf-examples

Tra poco faremo vedere un esempio che mette insieme tutte le tecnologieraccontate fino ad ora.

Aperitivo Osgi, Camel e GWT 54/108

Page 55: Sviluppare su OSGi con Camel e GWT

SensorMixEsempio di architettura basata su ServiceMix, Camel e GWT

Page 56: Sviluppare su OSGi con Camel e GWT

Come è composto SensorMixArchitettura esterna

Aperitivo Osgi, Camel e GWT 56/108

Page 57: Sviluppare su OSGi con Camel e GWT

Come è composto SensorMixArchitettura interna

Aperitivo Osgi, Camel e GWT 57/108

Page 58: Sviluppare su OSGi con Camel e GWT

DemoAperitivo Osgi, Camel e GWT 58/108

Page 59: Sviluppare su OSGi con Camel e GWT

Aperitivo Osgi, Camel e GWT

Data Model Bundle

59/108

Page 60: Sviluppare su OSGi con Camel e GWT

Il Canonical Data Model EIP

Dal libro EIP:

“I am designing several applications to work together through Messaging. Eachapplication has its own internal data format.”

“How can you minimize dependencies when integrating applications that usedifferent data formats?”

Aperitivo Osgi, Camel e GWT 60/108

Page 61: Sviluppare su OSGi con Camel e GWT

Il Canonical Data Model EIP

Aperitivo Osgi, Camel e GWT 61/108

Page 62: Sviluppare su OSGi con Camel e GWT

Il nostro approccio al CDM

A noi piace l’approccio Java first:

Usiamo annotazioni JaxB e JaxWS per generare dal nostro modello gli XMLSchema e WSDL.

Troviamo che cominciare dagli oggetti sia più naturale, lineare e agile:

Aperitivo Osgi, Camel e GWT

Modello dati: POJO

Modello servizi: Interfacce Java

·

·

Lo XML Schema finale risulta più pulito

Si può fare a meno della validazione XML

Lavorare sulle classi Java è più veloce (per noi che siamo sviluppatori)

·

·

eccezioni Java = XML non valido-

·

62/108

Page 63: Sviluppare su OSGi con Camel e GWT

Binding Java-XML Schema

Aperitivo Osgi, Camel e GWT

@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "SampleReport")public class SampleReport implements Serializable {

@XmlAttribute(required = true, name = "sensorId") @XmlSchemaType(name = "anyURI") private String sensorId;

@XmlAttribute(required = false, name = "sampleType") private String sampleType;

@XmlElement(required = false, name = "dailySampleReport") private List<DailySampleReport> dailySampleReports;

JAVA

<xs:complexType name="SampleReport"> <xs:attribute name="sensorId" type="xs:anyURI" use="required"/> <xs:attribute name="sampleType" type="xs:string"/> <xs:sequence> <xs:element name="dailySampleReport" type="tns:DailySampleReport" maxOccurs="unbounded" minOccurs="0" /> </xs:sequence></xs:complexType>

XML SCHEMA

63/108

Page 64: Sviluppare su OSGi con Camel e GWT

POJO annotati JaxB

Aperitivo Osgi, Camel e GWT

@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "SampleReport")public class SampleReport implements Serializable {

/** The sensor id. */ @XmlAttribute(required = true, name = "sensorId") @XmlSchemaType(name = "anyURI") private String sensorId;

/** The sample type. */ @XmlAttribute(required = false, name = "sampleType") private String sampleType;

/** The daily sample reports. */ @XmlElement(required = false, name = "dailySampleReport") private List<DailySampleReport> dailySampleReports;

// ...

JAVA

64/108

Page 65: Sviluppare su OSGi con Camel e GWT

Interfaccia annotata JaxWS

Aperitivo Osgi, Camel e GWT

@WebService(name = "SensormixService", targetNamespace = "http://developers.google.com/gdgfirenze/ns/service")@SOAPBinding(parameterStyle = ParameterStyle.WRAPPED, style = Style.DOCUMENT, use = Use.LITERAL)public interface SensormixService {

@WebMethod(action = "urn:#listSensorsIds") @RequestWrapper(localName = "listSensorsIdsIn", targetNamespace = "http://developers.google.com/gdgfirenze/ns/service") @ResponseWrapper(localName = "listSensorsIdsOut", targetNamespace = "http://developers.google.com/gdgfirenze/ns/service") @WebResult(name = "sensorId") List<String> listSensorsIds();

@WebMethod(action = "urn:#listSamplesTypes") @RequestWrapper(localName = "listSamplesTypesIn", targetNamespace = "http://developers.google.com/gdgfirenze/ns/service") @ResponseWrapper(localName = "listSamplesTypesOut", targetNamespace = "http://developers.google.com/gdgfirenze/ns/service") @WebResult(name = "sampleType") List<String> listSamplesTypes();

// ...

JAVA

65/108

Page 66: Sviluppare su OSGi con Camel e GWT

Utilizzo del CDM su GWT

Infine, se si vuole usare il data model anche dentro un progetto GWT, bastaaggiungere un modulo .gwt.xml:

Aperitivo Osgi, Camel e GWT

<?xml version="1.0" encoding="UTF-8"?><!-- When updating your version of GWT, you should also update this DTD reference, so that your app can take advantage of the latest GWT module capabilities. --><!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags /2.5.1/distro-source/core/src/gwt-module.dtd"><module>

<!-- Specify the paths for translatable code --> <source path='model' /> <source path='service' />

</module>

GWT XML

66/108

Page 67: Sviluppare su OSGi con Camel e GWT

Aperitivo Osgi, Camel e GWT

Data Service Bundle

67/108

Page 68: Sviluppare su OSGi con Camel e GWT

Il bundle dataservice

Contiene un servizio che espone funzionalità di memorizzazione e recupero diinformazioni

Il servizio viene registrato in OSGi tramite Spring DM

Aperitivo Osgi, Camel e GWT 68/108

Page 69: Sviluppare su OSGi con Camel e GWT

La registrazione del servizio

Aperitivo Osgi, Camel e GWT

<osgix:cm-properties id="dataSourceProperties" persistent-id="sensormix.jpa.persistenceunit"> <prop key="sensormix_db.driverClassName">org.hsqldb.jdbcDriver</prop> <prop key="sensormix_db.url">jdbc:hsqldb:mem:sensormix_db</prop> <prop key="sensormix_db.username">sa</prop> <prop key="sensormix_db.password"></prop></osgix:cm-properties>

<osgi:service ref="sensormixService"> <osgi:interfaces> <value>com.google.developers.gdgfirenze.service.SensormixService</value> <value>com.google.developers.gdgfirenze.osgi.SensormixAdminInterface</value> </osgi:interfaces></osgi:service>

SPRING DM

69/108

Page 70: Sviluppare su OSGi con Camel e GWT

Il servizio in java

Aperitivo Osgi, Camel e GWT

public class SensormixServiceJpaImpl implements SensormixService, SensormixAdminInterface {

private EntityManagerFactory entityManagerFactory;

@Override public List<String> listSensorsIds() { List<String> result = new ArrayList<String>();

try { EntityManager em = entityManagerFactory.createEntityManager(); TypedQuery<String> q = em.createQuery("SELECT s.id FROM JpaSensor s", String.class);

result.addAll(q.getResultList());

em.close(); } catch (Exception e) { logger.log(Level.SEVERE, "Error during sensors list retrieving", e); }

return result; }

JAVA

70/108

Page 71: Sviluppare su OSGi con Camel e GWT

Spring ORM

Aperitivo Osgi, Camel e GWT

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="sensormix_db" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> <property name="showSql" value="true" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="eclipselink.ddl-generation">create-tables</prop> <prop key="eclipselink.logging.level">INFO</prop> <prop key="eclipselink.weaving">false</prop> <prop key="javax.persistence.jdbc.driver">${sensormix_db.driverClassName}</prop> <prop key="javax.persistence.jdbc.url">${sensormix_db.url}</prop> <prop key="javax.persistence.jdbc.user">${sensormix_db.username}</prop> <prop key="javax.persistence.jdbc.password">${sensormix_db.password}</prop> </props> </property></bean>

<bean id="sensormixService" class="com.google.developers.gdgfirenze.dataservice.SensormixServiceJpaImpl"> <property name="entityManagerFactory" ref="emf" /></bean>

SPRING DM

71/108

Page 72: Sviluppare su OSGi con Camel e GWT

Aperitivo Osgi, Camel e GWT

Integration Bundle

72/108

Page 73: Sviluppare su OSGi con Camel e GWT

Il bundle di integrazione

Definisce le rotte Camel per l'ingresso dei campioni da Android, Arduino e iOS

Utilizza quasi esclusivamente configurazione via Spring XML

Unica eccezione: la classe SampleAdapter che trasforma da protocol buffer alnostro data model tramite codice java

Aperitivo Osgi, Camel e GWT 73/108

Page 74: Sviluppare su OSGi con Camel e GWT

Rivediamo le interfacce SensorMix

Aperitivo Osgi, Camel e GWT 74/108

Page 75: Sviluppare su OSGi con Camel e GWT

Le rotte di ingresso UDP e HTTPUsate da Android e da Arduino

Aperitivo Osgi, Camel e GWT

<route> <from uri="mina2:udp://0.0.0.0:10081" /> <to uri="seda:jsonEntry" /></route>

SPRING XML

<route> <from uri="jetty:http://0.0.0.0:10080/sensormixSamplesEndpoint" /> <to uri="seda:jsonEntry" />

<setHeader headerName="Content-Type"> <constant>application/json</constant> </setHeader> <to uri="velocity:vm_templates/json_response_template.vm" /></route>

SPRING XML

75/108

Page 76: Sviluppare su OSGi con Camel e GWT

La rotta di trasformazione del JSON

Aperitivo Osgi, Camel e GWT

<route> <from uri="seda:jsonEntry" /> <convertBodyTo type="java.lang.String" />

<unmarshal> <xmljson elementName="item" arrayName="list" rootName="root" /> </unmarshal>

<to uri="xslt:xslt_adapters/raw2cdm_adapter.xsl" />

<unmarshal> <jaxb contextPath="com.google.developers.gdgfirenze.service" /> </unmarshal>

<to uri="seda:serviceEntry" /></route>

SPRING XML

76/108

Page 77: Sviluppare su OSGi con Camel e GWT

La rotta TCP + ProtoBuf

Aperitivo Osgi, Camel e GWT

<route> <from uri="netty:tcp://0.0.0.0:10082/?decoders=#length-decoder&amp;sync=false" /> <unmarshal> <protobuf instanceClass="com.google.developers .gdgfirenze.protobuf.SensormixProtos$SampleMessage" /> </unmarshal> <bean ref="sampleAdapter" method="transform" /> <to uri="seda:serviceEntry" /></route>

<bean id="sampleAdapter" class="com.google.developers.gdgfirenze.integration.SampleAdapter" />

SPRING XML

package com.google.developers.gdgfirenze.integration;

public class SampleAdapter { public SamplesPayload transform(SampleMessage message) { SamplesPayload ret = new SamplesPayload(); // process 'SampleMessage' and return the adapted 'SamplesPayload' return ret; }}

JAVA

77/108

Page 78: Sviluppare su OSGi con Camel e GWT

L'output verso il servizio OSGi

Aperitivo Osgi, Camel e GWT

<osgi:reference id="sensormixService" interface="com.google.developers.gdgfirenze.service.SensormixService" timeout="30000" cardinality="1..1" />

<route> <from uri="seda:serviceEntry" /> <to uri="bean:sensormixService?method=recordSamples(${body.samples})" /></route>

SPRING XML

78/108

Page 79: Sviluppare su OSGi con Camel e GWT

Aperitivo Osgi, Camel e GWT

Admin WebApp Bundle

79/108

Page 80: Sviluppare su OSGi con Camel e GWT

SensorMix GWT Web Application

Abbiamo visto che per il deploy di una Web Application GWT suKaraf/ServiceMix dobbiamo garantire che:

Noi cosa abbiamo fatto?

Aperitivo Osgi, Camel e GWT

Il WAR sia un bundle OSGi compliant

Che gwt-servlet.jar sia stata correttamente installata come bundle.

·

·

80/108

Page 81: Sviluppare su OSGi con Camel e GWT

Configuriamo il maven-bundle-plugin

Aperitivo Osgi, Camel e GWT

<instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Description>${project.description}</Bundle-Description>

<Web-ContextPath>/${project.artifactId}</Web-ContextPath>

<Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>

<Import-Package> com.google.gwt.user.client.rpc.*, com.google.gwt.user.client.rpc.core.com.google.gwt.core.shared, com.google.gwt.user.client.rpc.core.java.lang, com.google.gwt.user.client.rpc.core.java.math, com.google.gwt.user.client.rpc.core.java.sql, com.google.gwt.user.client.rpc.core.java.util, com.google.gwt.user.client.rpc.core.java.util.logging, com.google.gwt.user.server.rpc.core.java.lang, com.google.gwt.user.server.rpc.core.java.util, !com.google.gwt.*.client.*, * </Import-Package></instructions>

POM.XML

81/108

Page 82: Sviluppare su OSGi con Camel e GWT

Configuriamo il maven-war-pluginRicordate lo skinny war?

Si tolgono le dipendenze dalla lib:

Si istruisce Maven di copiare il Manifest al posto giusto:

Aperitivo Osgi, Camel e GWT

<packagingExcludes>WEB-INF/lib/, WEB-INF/classes/META-INF/</packagingExcludes>

POM.XML

<archive> <manifestFile> ${project.build.outputDirectory}/META-INF/MANIFEST.MF </manifestFile></archive>

POM.XML

82/108

Page 83: Sviluppare su OSGi con Camel e GWT

Importiamo il Canonical Data Model

Nel file SensormixAdminApp.gwt.xml:

Nel pom.xml:

Aperitivo Osgi, Camel e GWT

<inherits name='com.google.developers.gdgfirenze.Sensormix' /> .GWT.XML

<dependency> <groupId>com.google.developers.gdgfirenze</groupId> <artifactId>sensormix-datamodel-api</artifactId> <version>${project.version}</version></dependency><dependency> <groupId>com.google.developers.gdgfirenze</groupId> <artifactId>sensormix-datamodel-api</artifactId> <version>${project.version}</version> <classifier>sources</classifier></dependency>

POM.XML

83/108

Page 84: Sviluppare su OSGi con Camel e GWT

GWT RPC Plumbing diagramSiamo partiti da qui...

Aperitivo Osgi, Camel e GWT 84/108

Page 85: Sviluppare su OSGi con Camel e GWT

Sensormix RPC Plumbing diagram...per arrivare qui

Aperitivo Osgi, Camel e GWT 85/108

Page 86: Sviluppare su OSGi con Camel e GWT

GWT RPC in SensormixLato Client

Instanziare la service interface usando GWT.create():

Fare la chiamata al servizio:

Aperitivo Osgi, Camel e GWT

GwtSensormixServiceAsync sensormixService = GWT.create(GwtSensormixService.class);

JAVA

sensormixService.listSensorsIds(new AsyncCallback() { @Override public void onFailure(Throwable caught) { // handle the request failure }

@Override public void onSuccess(List result) { // handle the response from the service }});

JAVA

86/108

Page 87: Sviluppare su OSGi con Camel e GWT

GWT RPC in SensormixLato Server

SensormixServiceProxy.java è un servizio GWT che usa un servizio OSGi. Nella inizializazione ottiene deiriferimenti al servizio utilizzando le API del Framework.

Come viene usata l’istanza del servizio OSGi?

Aperitivo Osgi, Camel e GWT

public void init() throws ServletException {

final BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); tracker = new ServiceTracker(context, SensormixService.class.getName(), null); tracker.open();}

JAVA

private SensormixService getService() { return (SensormixService) tracker.waitForService(10000);}

public List<String> listSensorsIds() { return getService().listSensorsIds();}

JAVA

87/108

Page 88: Sviluppare su OSGi con Camel e GWT

Cool FactsOvvero perchè ci piace questa architettura

Page 89: Sviluppare su OSGi con Camel e GWT

Integrazione di Arduino

Aperitivo Osgi, Camel e GWT 89/108

Page 90: Sviluppare su OSGi con Camel e GWT

Integrazione di Arduino

Aperitivo Osgi, Camel e GWT 90/108

Page 91: Sviluppare su OSGi con Camel e GWT

Integrazione di Android

Aperitivo Osgi, Camel e GWT

HttpPost httppost = new HttpPost(url.toString()); httppost.setHeader("Content-type", "application/json");

StringEntity se = new StringEntity(bodyForHttpPostRequest); se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); httppost.setEntity(se);

HttpResponse response = httpclient.execute(httppost); String temp = EntityUtils.toString(response.getEntity()); logger.info("JSON post response: " + temp);

JAVA

91/108

Page 92: Sviluppare su OSGi con Camel e GWT

Integrazione di Android - NFC

Aperitivo Osgi, Camel e GWT

Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); StringBuilder id = new StringBuilder(); byte[] data = tag.getId(); for (int i = 0; i < data.length; i++) { id.append(String.format("%02x", data[i])); if (i < data.length - 1) { id.append(":"); } } JSONObject jsonSamplePacket = new JSONObject(); JSONObject obj = new JSONObject(); jsonSamplePacket.put("sample", obj); obj.put("device_id", "the device id"); obj.put("time", dateFormat.format(new Date())); obj.put("nfc", id); Intent intent = new Intent(this, DataSenderService.class); intent.putExtra(DataSenderService.INTENT_EXTRA, jsonSamplePacket.toString()); startService(intent);

JAVA

92/108

Page 93: Sviluppare su OSGi con Camel e GWT

Installiamo ServiceMix

Aperitivo Osgi, Camel e GWT 93/108

Page 94: Sviluppare su OSGi con Camel e GWT

Creare una distribuzione della applicazione

Aperitivo Osgi, Camel e GWT 94/108

Page 95: Sviluppare su OSGi con Camel e GWT

Le Karaf Features

Aperitivo Osgi, Camel e GWT

<features name='sensormix-1.0.0'> <feature name="sensormix-core" version="1.0.0"> <bundle>mvn:com.google.developers.gdgfirenze/sensormix-datamodel-api/1.0.0</bundle> </feature>

<feature name="sensormix-dataservice" version="1.0.0"> <feature version="1.0.0">sensormix-core</feature> <feature>spring-orm</feature> <!-- ... --> <bundle>mvn:mysql/mysql-connector-java/5.1.26</bundle> <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-dbcp/1.4_3</bundle> <bundle>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2</bundle> <bundle>mvn:org.eclipse.persistence/javax.persistence/2.1.0</bundle> <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.jpa/2.5.0</bundle> <!-- ... --> <bundle>mvn:com.google.developers.gdgfirenze/sensormix-dataservice-bundle/1.0.0</bundle> </feature>

<feature name="sensormix" version="1.0.0"> <feature version="1.0.0">sensormix-dataservice</feature> <feature version="1.0.0">sensormix-webservice</feature> </feature></features>

FEATURES.XML

95/108

Page 96: Sviluppare su OSGi con Camel e GWT

Il Features Maven Plugin di Karaf

Aperitivo Osgi, Camel e GWT

<plugin> <groupId>org.apache.karaf.tooling</groupId> <artifactId>features-maven-plugin</artifactId> <version>${features.plugin.version}</version> <executions> <execution> <id>add-features-to-repo</id> <phase>package</phase> <goals> <goal>add-features-to-repo</goal> </goals> <configuration> <descriptors> <descriptor>com.google.developers.gdgfirenze /sensormix-deploy-features/1.0.0/xml/features</descriptor> </descriptors> <features> <feature>sensormix/1.0.0</feature> </features> <repository>target/local-repo</repository> </configuration> </execution> </executions></plugin>

FEATURES.XML

96/108

Page 97: Sviluppare su OSGi con Camel e GWT

Installiamo SensorMix

Aperitivo Osgi, Camel e GWT 97/108

Page 98: Sviluppare su OSGi con Camel e GWT

Kryo e Benchmark

Si è scelto di utilizzare un’unica classe per tutti i sample (con un campobyte[] che contiene la serializzazione (Kryo) del sample).

Sfruttando l’astrazione di JPA sono stati fatti benchmark di occupazione eperformance per supportare le scelte e validare la soluzione.

Aperitivo Osgi, Camel e GWT 98/108

Page 99: Sviluppare su OSGi con Camel e GWT

ServiceMix: Quanto overhead?Il pacchetto ServiceMix occupa circa 65MB sul filesystem

Aperitivo Osgi, Camel e GWT 99/108

Page 100: Sviluppare su OSGi con Camel e GWT

Maven ed Eclipse

SensorMix è stato sviluppato in Team utilizzando Maven ed Eclipse.

In particolare:

Aperitivo Osgi, Camel e GWT

Sviluppo GWT integrato nello stesso Java IDE

Distribuzione tramite Karaf's Features Maven Plugin

Checkstyle e PMD per migliorare la cooperazione del Team

·

·

·

100/108

Page 101: Sviluppare su OSGi con Camel e GWT

ConclusioniConsiderazioni finali e riferimenti bibliografici

Page 102: Sviluppare su OSGi con Camel e GWT

Issue su GWT

Serve GWT 2.6.0 che sia reso OSGi ready:per favore aiutateci, votate lo issue sulla Osgify di GWT:

oppure lo issue su Jira per avere il bundle rilasciato da ServiceMix il primapossibile:

·

http://goo.gl/GEuVBR-

·

http://goo.gl/jFsVcP-

Page 103: Sviluppare su OSGi con Camel e GWT

Materiali

Aperitivo Osgi, Camel e GWT

Slides:

http://cristcost.github.io/sensormix/

Sensormix:

https://github.com/cristcost/sensormix/

Sensormix Android:

https://github.com/cristcost/sensormix-android/

Sensormix Arduino:

https://github.com/michelefi/sensormix-arduino/

103/108

Page 104: Sviluppare su OSGi con Camel e GWT

Libri

Camel in Action

C. Ibsen, J. Anstey - Manning

Enterprise Integration Patterns

G. Hohpe, B. Woolf - Addison Wesley

Spring DM in Action

A. Cogoluègnes, T. Templier, A. Piper - Manning

OSGi in Action

R. S. Hall, K. Pauls, S. McCulloch, D. Savage - Manning

OSGi In depth

Alexandre de Castro Alves - Manning

Page 105: Sviluppare su OSGi con Camel e GWT

Links

Aperitivo Osgi, Camel e GWT

Apache Camel:

http://camel.apache.org/

Apache ServiceMix:

http://servicemix.apache.org/

Apache Karaf:

http://karaf.apache.org/

GWT:

http://www.gwtproject.org/

105/108

Page 106: Sviluppare su OSGi con Camel e GWT

Q&AAperitivo Osgi, Camel e GWT 106/108

Page 107: Sviluppare su OSGi con Camel e GWT

<Thank You!>

Cristiano Costantini [email protected]

Giuseppe Gerla [email protected]

Michele Ficarra [email protected]

Sergio Ciampi [email protected]

Stefano Cigheri [email protected]

Page 108: Sviluppare su OSGi con Camel e GWT