Sviluppare su OSGi con Camel e GWT
-
Upload
cristiano-costantini -
Category
Technology
-
view
367 -
download
1
description
Transcript of 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
Chi Siamo
Cristiano
Giuseppe
Michele
Sergio
Stefano
Aperitivo Osgi, Camel e GWT 3/108
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
Introduzione a OSGi e ServiceMixOvvero un approccio modulare per backend SOA
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
Una Metafora:Pensate ai servizi di Windows o demoni Unix ma completamente Java
Aperitivo Osgi, Camel e GWT 7/108
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
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
Implementazioni OSGi
Esistono diverse implementazioni di OSGi. Quelle più complete sono:
Aperitivo Osgi, Camel e GWT
Apache Felix
Eclipse Equinox
Knopflerfish
·
·
·
10/108
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
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
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
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
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
Il “Lifecycle layer”Il lifecycle layer ha due scopi:
Esternamente gestisce il ciclo di vita del bundle.
Aperitivo Osgi, Camel e GWT 16/108
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
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
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
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
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
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
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
Introduzione ad Apache CamelOvvero un modo agile per integrare sistemi eterogenei
“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
Enterprise Integration Patterns
Gli Enterprise Integration Patters offrono soluzioni per affrontare il precedenteproblema.
Cosa sono gli EIP?
Aperitivo Osgi, Camel e GWT 26/108
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
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
Soluzioni con EIP
Aperitivo Osgi, Camel e GWT 31/108
Soluzioni con EIP
Aperitivo Osgi, Camel e GWT 32/108
Soluzioni con EIP
Attenti a questa qui!
Aperitivo Osgi, Camel e GWT 33/108
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
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
Esempio: Content Based Router
from newOrder choice when isWidget to widget otherwise to gadget
Aperitivo Osgi, Camel e GWT 36/108
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
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
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
Camel in ServiceMix
Una volta attivati i bundle di Camel su Karaf-ServiceMix...
Aperitivo Osgi, Camel e GWT 40/108
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
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
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
Utilizzare GWT su ServiceMixOvvero un modo diverso per fare Web Application
Framework Web per SOFEA
Aperitivo Osgi, Camel e GWT
http://raibledesigns.com/
46/108
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
La nostra SOFEA
Aperitivo Osgi, Camel e GWT 48/108
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
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
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
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
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
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
SensorMixEsempio di architettura basata su ServiceMix, Camel e GWT
Come è composto SensorMixArchitettura esterna
Aperitivo Osgi, Camel e GWT 56/108
Come è composto SensorMixArchitettura interna
Aperitivo Osgi, Camel e GWT 57/108
DemoAperitivo Osgi, Camel e GWT 58/108
Aperitivo Osgi, Camel e GWT
Data Model Bundle
59/108
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
Il Canonical Data Model EIP
Aperitivo Osgi, Camel e GWT 61/108
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
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
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
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
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
Aperitivo Osgi, Camel e GWT
Data Service Bundle
67/108
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
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
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
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
Aperitivo Osgi, Camel e GWT
Integration Bundle
72/108
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
Rivediamo le interfacce SensorMix
Aperitivo Osgi, Camel e GWT 74/108
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
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
La rotta TCP + ProtoBuf
Aperitivo Osgi, Camel e GWT
<route> <from uri="netty:tcp://0.0.0.0:10082/?decoders=#length-decoder&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
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
Aperitivo Osgi, Camel e GWT
Admin WebApp Bundle
79/108
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
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
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
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
GWT RPC Plumbing diagramSiamo partiti da qui...
Aperitivo Osgi, Camel e GWT 84/108
Sensormix RPC Plumbing diagram...per arrivare qui
Aperitivo Osgi, Camel e GWT 85/108
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
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
Cool FactsOvvero perchè ci piace questa architettura
Integrazione di Arduino
Aperitivo Osgi, Camel e GWT 89/108
Integrazione di Arduino
Aperitivo Osgi, Camel e GWT 90/108
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
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
Installiamo ServiceMix
Aperitivo Osgi, Camel e GWT 93/108
Creare una distribuzione della applicazione
Aperitivo Osgi, Camel e GWT 94/108
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
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
Installiamo SensorMix
Aperitivo Osgi, Camel e GWT 97/108
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
ServiceMix: Quanto overhead?Il pacchetto ServiceMix occupa circa 65MB sul filesystem
Aperitivo Osgi, Camel e GWT 99/108
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
ConclusioniConsiderazioni finali e riferimenti bibliografici
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-
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
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
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
Q&AAperitivo Osgi, Camel e GWT 106/108
<Thank You!>
Cristiano Costantini [email protected]
Giuseppe Gerla [email protected]
Michele Ficarra [email protected]
Sergio Ciampi [email protected]
Stefano Cigheri [email protected]