osgi für praktiker - web applikationen und verteilte systeme mit osgi

Post on 07-May-2015

2.249 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

OSGi für Praktiker - BegrüssungPatrick Baumgartner

Pax

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

OSGi für Praktiker Vorstellung Ablauf des Workshops Administratives

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi für Praktiker

Praxis Buch OSGi im Enterprise Umfeld Build, Run, Manage Maven basierte Pax Tools

@OSGiBuch http://www.osgi-buch.com/

Vorstellung – Bernd Weber

Senior Consultant (Enterprise Backends) Co-Autor von OSGi für Praktiker

Interessens-Schwerpunkte– Öffentlicher Bereich– OpenSource Software– Infrastruktur-Projekte– IT-Standards (SAGA, V-Modell XT)

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Vorstellung – Oliver Braun

Professor für Programmierung und Verteilte Systeme Co-Autor von OSGi für Praktiker Autor von Scala – Objektfunktionale Programmierung

Interessens-Schwerpunkte– Funktionale Programmierung in Haskell– Objektfunktionale Programmierung in Scala– Entwicklung verteilter Systeme

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Vorstellung – Patrick Baumgartner

Senior Software Consultant @ Swiftmind Co-Autor von OSGi für Praktiker Initiator des OSGi Users' Forum Switzerland

Architektur, Coaching, Workshops, Trainings, Reviews & Entwicklung– Java Web Entwicklung mit Spring– OSGi mit Spring DM & Spring – Agile Software Development

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Ablauf des Workshops – 9:30

Begrüssung & Vorstellung 5' Einführung in OSGi 40' Projekt Setup 30' Bundle Playground 15' Web Console *

Kaffeepause 30'

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Ablauf des Workshops – 11:30

Deklarative Services 40' Blueprint Services 20'

Mittagspause 60'

Web Bundles 20' Fragmente & Integrationstests 40'

Kaffepause 30'

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Ablauf des Workshops – 15:30

Distributed OSGi 45' Outlook Scala Modules 25' Launcher 15' Fragen

Ende

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Administratives

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

EinleitungOliver Braun

Pax

22OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi

JSR 291: „Dynamic Component Support for Java SE“ (= OSGi-Spezifikation 4.1)

Aktuell 4.2– Distributed OSGi– Enterprise Edition– ...

33OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Die ersten Schritte

1999 Gründung OSGi Alliance– Open Service Gateway Initiative

(heute nur OSGi) 2000 Release 1– Fokus: Home Network Gateways

… 2003 Release 3– Fokus auch auf Automotive & Entertainment

44OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

... und die nächsten

2004 Eclipse Release 3 2005 Release 4– Mobile Devices

2009 Release 4.2 2010 Enterprise Edition– Web Applications– Distributed OSGi– JMX– …

55OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Bundles

Entspricht einem Modul JAR + OSGi-Manifest Manifest-Header– Bundle-SymbolicName– Bundle-Version– Bundle-Name– ...

66OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Beispiel-Manifest

Bundle-Name: Hello WorldBundle-SymbolicName: biz.gossipmonger.helloworldBundle-Description: A hello world bundleBundle-ManifestVersion: 2Bundle-Version: 1.0.0Export-Package:

biz.gossimonger.helloworld;version=“1.0.0“Import-Package:

org.osgi.framework;version=“1.3.0“

77OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Sichtbarkeit

Bei einem JAR ist der gesamte Inhalt sichtbar Ein OSGi-Bundle exportiert nur explizit

angegebene Packages Analog muss ein OSGi-Bundle auch explizit

exportieren Dies geschieht im Manifest:

Export-Package:biz.gossimonger.helloworld;version=“1.0.0“

Import-Package: org.osgi.framework;version=“1.3.0“

88OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi-Schichtenmodell

99OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Zustände und Übergänge

1010OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

BundleActivator

OSGi-Framework Bundle→

public interface BundleActivator {public void start(BundleContext context)

throws Exception;public void stop(BundleContext context)

throws Exception;}

1111OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

BundleContext

Bundle → OSGi-Framework

public interface BundleContext {…public Object getService

(ServiceReference ref);public ServiceRegistration registerService

(String[] clazzes, Object service, Dictionary properties);

…}

1212OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Serviceorientierung

Zusammenarbeit von Bundles über Dienste Ein Bundle kann n Dienste bereitstellen Dienst = Java-Objekt Schnittstelle = Java-Interface Ein Objekt kann mehrere Dienste bereitstellen

= mehrere Interfaces implementieren Dienste werden bei der ServiceRegistry– registriert– angefragt

Gekapselt in ServiceReference-Objekt

1313OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Interaktion der Schichten

1414OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GossipMonger

1515OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimerpublic class JobTimer implements BundleActivator { private Thread t = null; public void start(BundleContext context) { Runnable task = new JobTimerRunnable(context); t = new Thread(task); t.start(); } public void stop(BundleContext context) { t.interrupt(); try { t.join(); } catch (InterruptedException e1) { e1.printStackTrace(); } }

1616OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimerRunnableprivate class JobTimerRunnable implements Runnable {

public void run() {ServiceTracker tracker = new

ServiceTracker(context, EventAdmin.class.getName(), null);

tracker.open();try {

// do something → next slide} catch (InterruptedException e) {

Thread.currentThread().interrupt(); } finally { tracker.close(); }

}}

1717OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimerRunnable (2) ...

try {while (true) {

// … time = …EventAdmin ea = (EventAdmin)

tracker.getService(); if (ea != null) { Event ev = new Event("jobtimer", time); ea.sendEvent(ev); } Thread.sleep(10000); } } catch (InterruptedException e) { ...

1818OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GateKeeperpublic class GateKeeper

implements BundleActivator, EventHandler { public void start(BundleContext ctx) throws Exception { String[] topics = new String[]

{"biz/gossipmonger/jobtimer" }; Dictionary<String, Object> dict =

new Hashtable<String, Object>(); dict.put(EventConstants.EVENT_TOPIC, topics); ctx.registerService(EventHandler.class.getName(), this, dict); } public void stop(BundleContext ctx) throws Exception {} // … implements Eventhandler …}

1919OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GateKeeper (2) private File watchedDir = new File("render_input");

public void handleEvent(Event event) { prepareWatchedDir(); String list[] = watchedDir.list(); System.out.println("GateKeeper found " + list.length + " entries in " + watchedDir); } private void prepareWatchedDir() { // … mkdir and stuff like that … }

Projekt SetupBernd Weber

Pax

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Werkzeuge JobTimer Bundle erstellen Projekt GossipMonger aufsetzen GateKeeper Bundle integrieren

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JDK 1.6.2x

2.2.x oder 3.0

3.6 mit Maven-Plugin m2eclipse http://m2eclipse.sonatype.org/sites/m2e

Werkzeuge – Standard

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Werkzeuge – OSGi

>= 2.0.xhttp://felix.apache.org/site/downloads.cgi

1.26.0http://www.aqute.biz/Bnd/Download

alias bnd='$JAVA_HOME/bin/java -jar /path/to/biz.aqute.bnd.jar'

Pax

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Werkzeuge – Pax Construct

Erzeugen und Verwalten von OSGi-Projekten und Bundles

Archetypen & Shell Skripte, z.B.:– pax-create-project– pax-create-bundle– pax-provision

Herunterladen, auspacken,bin-Verzeichnis in Suchpfad

http://wiki.ops4j.org/display/paxconstruct/Download

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Werkzeuge – Pax Runner

Zentrales Pax-Werkzeug Startet die wichtigsten OSGi

Plattformen Konfiguration über Profile Kann als Hintergrunddienst

gestartet werden Herunterladen, auspacken,bin-Verzeichnis in Suchpfad

http://paxrunner.ops4j.org/display/paxrunner/Download

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Werkzeuge – Pax Exam

Framework für Integrationstests Basiert auf JUnit und Pax Runner Konfiguration von Bundles,

Umgebungsparametern, Plattformen

Verwendung über Maven2-Dependencies oder Download

http://wiki.ops4j.org/display/paxexam/Download

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Werkzeuge JobTimer Bundle erstellen Projekt GossipMonger aufsetzen GateKeeper Bundle integrieren

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer – Maven-Struktur

JobTimer ist erstes Bundle mvn generate:archetype Vorschlag (Quickstart) übernehmen Metadaten eingeben:

groupId: biz.gossipmongerartifactId: jobtimerversion: 0.1.0package: biz.gossipmonger.jobtimer

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer – POM anpassen

pom.xml in Eclipse importierenFile Import. . . Maven Existing Maven Project→ → →

Abhängigkeiten zu OSGi-APIs definieren<dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> <version>4.2.0</version></dependency><dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>4.2.0</version></dependency>

Java-Version definieren Automatisiertes Testen konfigurieren

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer.java in Maven-Struktur einbetten JAR erstellen (mvn package) Zum Bundle erweitern mit bnd– Steuerdatei osgi.bnd erstellen

JobTimer – Bundle erstellen

Bundle-Name: GossipMonger JobTimerBundle-SymbolicName: biz.gossipmonger.jobtimerBundle-Version: 0.1.0Bundle-Activator: biz.gossipmonger.jobtimer.JobTimerPrivate-Package: biz.gossipmonger.jobtimer-classpath: target/jobtimer-0.1.0.jar

– Aufruf von bnd osgi.bnd

12OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer-Bundle Manifest

Ergebnis: JAR mit erweiterter Manifest-DateiBundle-ManifestVersion: 2Bundle-Name: GossipMonger JobTimerBundle-SymbolicName: biz.gossipmonger.jobtimerBundle-Version: 0.1.0Bundle-Activator: biz.gossipmonger.jobtimer.JobTimerPrivate-Package: biz.gossipmonger.jobtimerImport-Package: org.osgi.framework,org.osgi.service.event,org.osgi.util.tracker

Übrigens: bnd-Steuerdateien sind– vielseitig durch Variablen, Makros, …– kaskadierbar– gut lesbar

13OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

bnd-Steuerdatei integrieren

Ziel: Automatisierte Bundle-Erstellung Werkzeug: maven-bundle-plugin Verwendet bnd-Steuerdatei

<plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>2.1.0</version> <extensions>true</extensions> <configuration> <instructions> <_include>osgi.bnd</_include> </instructions> </configuration></plugin>

14OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer-POM abrunden

Verpackungsart auf “Bundle” einstellen<packaging>bundle</packaging>

Hübschen Namen vergeben <name>GossipMonger JobTimer</name>

Bundle erstellen und in lokalem Maven-Repository ablegenmvn install

15OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Werkzeuge JobTimer Bundle erstellen Projekt GossipMonger aufsetzen GateKeeper Bundle integrieren

16OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Gesamtprojekt anlegen

Gesamtprojekt heißt “GossipMonger“ Verwendung von Pax Constructpax-create-project

Metadaten angebengroupId: biz.gossipmongerartifactId: gossipmongerversion: 0.1.0

17OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer importieren

JobTimer ist Taktgeber für GossipMonger Autarkes Bundle neben dem Projekt Import => Definition Abhängigkeit

$ cd gossipmonger$ pax-import-bundlegroupId: biz.gossipmongerartifactId: jobtimerversion: 0.1.0

Ergebnis: Erweiterung von provision/pom.xml<dependencies> <dependency> <groupId>biz.gossipmonger</groupId> <artifactId>jobtimer</artifactId> <version>0.1.0</version> </dependency></dependencies>

18OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Abhängigkeiten-Automatik

JobTimer nutzt u.a. EventAdmin=> Laufzeit-Abhängigkeit zu API und Impl.

Ziel: beim Plattformstart mitladen Werkzeuge: maven-pax-plugin, Profile

<plugin> <groupId>org.ops4j</groupId> <artifactId>maven-pax-plugin</artifactId> <version>1.4</version> <configuration> <provision> <param>--platform=felix</param> <param>--profiles=compendium,event</param> </provision> </configuration></plugin>

19OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Werkzeuge JobTimer Bundle erstellen Projekt GossipMonger aufsetzen GateKeeper Bundle integrieren

20OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GateKeeper Bundle

GateKeeper-Bundle ist erstes Projekt-Modul Ziel: Unmittelbare GossipMonger-Integration Werkzeug: pax-create-bundle (Pax Construct)

$ cd gossipmonger$ pax-create-bundlepackage: biz.gossipmonger.gatekeeperbundleName: biz.gossipmonger.gatekeeperbundleGroupId: biz.gossipmongerversion: 0.1.0

<modules> <module>poms</module> <module>provision</module> <module>biz.gossipmonger.gatekeeper </module></modules>

21OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

POM Zuständigkeiten

pom.xmlMaster-POM, allg. Definitionen, Module (Bundles)

biz.gossipmonger.gatekeeper/pom.xmlBundle-Daten

poms/pom.xmlglobale Abhängigkeiten (u.a. OSGi API) und Verweise auf die nachfolgenden POMs

poms/compiled/pom.xmlvordefinierte OSGi-Header, Einbindung osgi.bnd

poms/wrappers/pom.xmlOSGi-Wrapper für Drittbibliotheken

provision/pom.xmlspezifische Abhängigkeiten -> JobTimer

22OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GateKeeper Metadaten

Viele Default-Werte passen bereits Nachziehen von Activator, Sichtbarkeit (, Name) Werkzeug: Erweiterung von osgi.bnd (, POM)

Bundle-Activator: ${bundle.namespace}.GateKeeperPrivate-Package: ${bundle.namespace}Export-Package:Import-Package: *

Überschreibt Standardwerte von Pax Construct GateKeeper ist nun startklar und “unsichtbar“

Bundle PlaygroundPatrick Baumgartner

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix - Installation

Apache Felix Framework Distribution 3.0.7 herunterladen (http://felix.apache.org/site/downloads.cgi)

Entpacken Ins Verzeichnis felix-framework-3.0.7 wechseln

Apache Felix Framework starten java -jar bin/felix.jar

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix – Befehle (1)

Mögliche Befehle auf der Konsole abrfagen g!help

Apache Felix Befehle

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix – Befehle (2)

Apache Gogo Befehle

OBR Befehle

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix - Status

Installierte Bundles und deren Status auf der Gogo Konsole abfragen

g!lb

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer installieren

g!install file:/pathtofile/jobtimer.jar

g!lb

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer starten

g!resolve 4

g!start 4

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

JobTimer deinstallieren

g!stop 4

g!start 4

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix – Befehle (2)

Apache Gogo Befehle

OBR Befehle

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix - Status

Installierte Bundles und deren Status auf der Gogo Konsole abfragen

g!lb

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Pax-Runner - Apache Felix

Apache Felix mit Pax-Runner starten $pax-run

12OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Pax-Runner - Profile

Pax-Runner mit bereits vorbereiteten Profilen starten http://paxrunner.ops4j.org/space/Pax+Runner+profiles+list https://scm.ops4j.org/repos/ops4j/projects/pax/runner-

repository/org/ops4j/pax/runner/profiles/

$pax-run --profiles=log

13OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Pax-Runner - Plattformen

Pax-Runner mit Apache Felix, Equinox, Knopflerfish starten

$pax-run --platform=equinox

14OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Bundles mit URL installieren

osgi>install http://www.osgi-buch.com/tutorial/jobtimer.jar

Status mit osgi>ss prüfen

Apache Felix Web ConsolePatrick Baumgartner

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Apache Felix Web Console

Weitere Informationen abrufbar unter http://felix.apache.org/site/apache-felix-web-console.html

$pax-run –-profiles=web,jsp,felix.webconsole

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Web Console

URL: http://localhost:8080/system/console Benutzername/Passwort: admin/admin

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Web Console - Bundles

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Web Console - Shell

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Web Console – Config (1)

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Web Console – Config (2)

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Security

Konsole unterstützt momentan sehr wenig Security:– Authentifizierung per HTTP Basic– Kein SSL– Standard User/Passwort

Für den sicheren Einsatz in Produktion muss noch einiges getan werden!

Declarative ServicesBernd Weber

Service Component Runtime, OSGi Service Compendium, Kap. 112

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Überblick Enunciator Bundle integrieren Worker Bundle integrieren

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi APIs: mächtig, Verwendung teils schwierig API-Verwendung => Starke Kopplung => Widerspruch zu OSGi-Prinzipien => Maximale Forderung: POJOs ohne API-Bezug

Optimum: Deklaration von Verhalten/Bezügen Verschiedene deklarative Ansätze– Apache iPOJO– OSGi Declarative Services– OSGi Blueprint Container (Spring-DM)

Überblick

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Declarative Services Spec.

Teil des OSGi Standards Ausgereifte Technologie Konfiguration einzelner Komponenten per XML Verweis in Bundle-Header Service-Component

z.B. Service-Component: OSGI-INF/worker.xml

BundleActivator wird nicht benötigt Friedliches Nebeneinander von – Declarative Services (DS),– Blueprint Service Container und– Direkter API-Verwendung (BundleActivator

u.a.)

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Declarative Services Spec.

Komponenten-Deklaration in XML, u.a.– Komponenten-Name– Implementierungsklasse– Deklarieren angebotener Dienste (Interface)– Deklarieren referenzierter Dienste, jeweils• Interface• Kardinalitäten (optional)• bind / unbind-Methoden (optional)

– Laufzeitverhalten: statisch oder dynamisch– Konfigurationsdaten, ...

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Laufzeitumgebung (SCR)

DS-Bundles benötigen Laufzeitumgebung(Service Component Runtime, SCR)– Initialisieren– Herstellen / Aktualisieren von Referenzen– Aktivieren / Deaktivieren

SCR ist ein Bundle – was sonst :-) Manuelle Installation z.B. mittels

install http://archive.apache.org/dist/felix/ org.apache.felix.scr-1.0.8.jar

Verwendung Pax Runner Profil– Ergänzen von gossipmonger/pom.xml um<param>--profiles=[...],ds</param>

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Überblick Enunciator Bundle integrieren Worker Bundle integrieren

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Enunciator Bundle

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Enunciator Bundle

Neues Teilprojekt im gossipmonger-Verzeichnis$ pax-create-bundlepackage: biz.gossipmonger.enunciatorbundleName: biz.gossipmonger.enunciatorbundleGroupId: biz.gossipmongerversion: 0.1.0

In Eclipse importieren, Beispiel-Dateien löschen Schnittstellen-Datei Enunciator.java erstellen in

src/main/java/biz/gossipmonger/enunciator

public interface EnunciatorService { void enunciate(String text);}

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Enunciator Bundle

EnunciatorServiceImpl erstellen– Package biz.gossipmonger.enunciator.internal– Entspricht Pax-Hierarchie der Bundle-Packages

Implementiert die Schnittstelle EnunciatorService Enthält optionale de-/activate-Methoden (DS) Nutzt dynamisch auftretende LogServices– Kein LogService vorhanden => Konsole

Ggf. Master-POM um Compiler-Einstellung >= Java 1.5 ergänzen

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Enunciatorpublic class EnunciatorServiceImpl implements EnunciatorService { List<LogService> logServices = new ArrayList<LogService>(); public void addLogService(LogService ls) { logServices.add(ls); enunciate("Enunciator got a LogService. Now there are " + logServices.size() + " references."); } public void removeLogService(LogService ls) { logServices.remove(ls); enunciate("Enunciator lost a LogService. Now there are " + logServices.size() + " references."); }

// further methods -> next slide}

12OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Enunciator (2)...public void enunciate(String text) { if (logServices.size() > 0) { for (LogService ls : logServices) { ls.log(LogService.LOG_INFO, text); } } else { System.out.println("Enunciator has no LogService; Message is: " + text);}protected void activate(ComponentContext cc) { System.out.println("Enunciator activated.");}protected void deactivate(ComponentContext cc) { System.out.println("Enunciator deactivated.");}...

13OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Dienst deklarieren

Neues Verzeichnis src/main/resources/OSGI-INF Darin Datei EnunciatorServiceImpl.xml anlegen Schema: http://www.osgi.org/xmlns/scr/v1.0.0

14OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Deklaration bekanntgeben

biz.gossipmonger.enunciator/osgi.bnd BundleActivator-Zeile löschen Neue (einzige) Zeile für Service-Component

15OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

GateKeeper 0.2.0

Abhängigkeit in GateKeeper-POM aufnehmen start/stop: ServiceTracker enunciatorTracker

private void enunciate(String text) { if (enunciatorTracker == null) { System.out.println([...]"No EnunciatorService tracker[...]" + text); } else { EnunciatorService enunciator = null; try { Object obj = enunciatorTracker.waitForService(500); enunciator = (EnunciatorService)obj; } catch (InterruptedException e) { System.out.println([...]"interrupted while waiting for Enunciator"); } if (enunciator != null) { enunciator.enunciate(ENUNCIATE_PREFIX+text); } else { System.out.println(ENUNCIATE_PREFIX+"(no EnunciatorService): " + text); } } }

16OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Test der Bundles

Wechsel in gossipmonger-Verzeichnis Aufruf von pax-provision Ergebnis:

Welcome to Felix================-> Bundle is starting...Bundle has started.Enunciator activated.Enunciator has no LogService; Message is: GateKeeper created watched directory [...]/runner/render_inputorg.osgi.service.event.Event [topic=biz/gossipmonger/jobtimer][FelixStartLevel] INFO biz.gossipmonger.enunciator - Enunciator got a LogService. Now there are 1 references.org.osgi.service.event.Event [topic=biz/gossipmonger/jobtimer]

17OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Überblick Enunciator Bundle integrieren Worker Bundle integrieren

18OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker Service

19OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker Service Bundles

Worker-Zweck: XML in Ausgabeformat rendern Je ein Bundle für API und Implementierung Beide: package biz.gossipmonger.worker bundleName biz.gossipmonger.worker-api / -impl -api in biz/gossipmonger/worker -impl in biz/gossipmonger/worker/internal Worker-Service deklarativ anmelden

20OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker API

POM: nur Metadaten, gener. Properties und Name Private-/Export-Package in osgi.bnd anpassen

(Warnungen wegen gelöschtem internal-Verzeichnis)

Service: Schnittstelle für XML-In und File-Outpublic interface WorkerService { File process(File file); File process(File file, String outputDir); File process(InputStream is, String inputFilename); File process(InputStream is, String inputFilename, String outputDir);}

21OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker Implementierungpublic final class WorkerServiceImpl implements WorkerService { ... protected void activate(ComponentContext context) { enunciate("activating..."); configuredOutput = getConfiguredOutput(context); enunciate("activated."); } protected void deactivate(ComponentContext context) { enunciate("deactivated."); } public void setEnunciatorService(EnunciatorService es) { if (es != null) { enunciator = es; enunciate("EnunciatorService set."); } else { enunciate("setEnunciatorService called with null argument."); } } public void unsetEnunciatorService(EnunciatorService es) { enunciate("EnunciatorService unset."); enunciator = null; } ...}

22OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker Implementierung (2)public File process(File file) { return process(file, configuredOutput);}public File process(File file, String outputDir) { enunciate("Render from "+file.getAbsolutePath()); try { return process(new FileInputStream(file), file.getName(), outputDir); } catch (FileNotFoundException e) { enunciate(file.getAbsolutePath() + " is not there!"); return null; }}...public File process(InputStream is, String inputFilename, String outputDir) { enunciate("Rendering..."); try { File output = renderer.render(is, inputFilename, outputDir); enunciate("Rendered to "+output.getAbsolutePath()); return output; } catch (Exception ex) { enunciate("Error while rendering: "+ex.getMessage()); return null; }}

23OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker Implementierung (3)

In-Bundle Properties: nach der Mittagspause

private String getConfiguredOutput(ComponentContext context) { String setBy = "default"; Properties props = getBundleContainedProperties(context); String outputDir = props.getProperty(PROPERTYNAME_OUTPUT_DIR); if (outputDir != null && outputDir.isEmpty() == false) { setBy = "in-bundle properties"; } else { outputDir = (String) context.getProperties().get(PROPERTYNAME_OUTPUT_DIR); if (outputDir != null && outputDir.isEmpty() == false) { setBy = "service properties"; } else { outputDir = DEFAULT_OUTPUT_DIR; } } enunciate("Output Directory is set by "+setBy+" to "+outputDir+"."); return outputDir;}...

24OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

<?xml version="1.0" encoding="UTF-8"?><component name="biz.gossipmonger.worker"> <implementation class="biz.gossipmonger.worker.internal.WorkerServiceImpl"/> <reference name="Enunciator" interface="biz.gossipmonger.enunciator.EnunciatorService" cardinality="0..1" policy="dynamic" bind="setEnunciatorService" unbind="unsetEnunciatorService"/> <service> <provide interface="biz.gossipmonger.worker.WorkerService"/> </service> <property name="worker.outputDir" type="String" value="render_outpdf"/></component>

Komponente deklarieren

java/main/resources/OSGI-INF/WorkerServiceImpl.xml

25OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Sonstige Anpassungen

Worker-Impl POM– Name– Abhängigkeiten (Worker-API, Enunciator, iText)

GateKeeper– ServiceTracker für WorkerService– processFile ruft nächstbesten WorkerService auf– postResult verkündet asynchron per EventAdmin– POM: Abhängigkeiten zu Worker-API und OSGi

Service Compendium wegen EventAdmin

26OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Test der Bundles

Aufruf von pax-provision im gossipmonger-Verz. Ablegen beliebiger XML-Datei in render_input:

GateKeeper: Processing deploy-pom.xmlWorkerServiceImpl: Render from /home/osgi/osgibuch/gossipmonger/runner/render_input/deploy-pom.xmlWorkerServiceImpl: Rendering...WorkerServiceImpl: Rendered to /home/osgi/osgibuch/gossipmonger/runner/render_outpdf/deploy-pom.pdfGateKeeper: Moving processed file to archive dir ./render_archive

Enunciator-Bundle anhalten (stop <bundle-id>):stop 5[...] WorkerServiceImpl: EnunciatorService unset.Enunciator deactivated.Enunciator has no LogService; Message is: Enunciator losta LogService. Now there are 0 references.DEBUG biz.gossipmonger.enunciator - BundleEvent STOPPED

Blueprint ServicesPatrick Baumgartner

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Überblick

Sehr ähnlich zu Declarative Services Standard seit OSGi R4.2 Basiert auf den Ideen von Spring DM 1.0 Spring DM 2.0 ist die Referenzimplementation (RI) Aktuelle Implementationen sind Apache Aries Blueprint

& Eclipse Gemini Blueprint (Incubator)

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Einführung

Verwendung von Legacy Code Keine Abhängigkeit zur OSGi API Konstruktor & Setter Injection Behandlung von OSGI Dynamics XML-Files befinden sich in OSGI-INF/blueprint– Alternativer Pfad im Manifest Header definiert:– Bundle-Blueprint: OSGI-INF/blueprint/config.xml

Verwendung Pax Runner Profil– Ergänzen von gossipmonger/pom.xml um<param>--profiles=[...],blueprint</param>

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Blueprint Idee

Spring Dynamic Modules - OSGi with Spring Framework

Imported Service

Exported Service

Bean

Blueprint Framework

OSGI Framework

JVM

Application Context

Application Context

Application Context

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Blueprint Bundle

Blueprint Bundle

Blueprint Extender

Metadata

XML

Blueprint Bundle

Metadata

XML

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Blueprint Konfiguration (Auszug)

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Skilled Worker Service

Web BundlesPatrick Baumgartner

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Überblick

RFC 66: OSGi Web Container Spezifikation Mächtiger als OSGi HttpService Web Bundle = Web-Applikation mit OSGi WAR + OSGi Metadata + Web-ContextPath Header JEE APIs wie z.B. JPA mit LazyLoading verwendbar Wrapped WAR Support

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Einführung

Unterstützt WAR und WAB Dateien WAB benötigt zusätzlichen Manifest Header– Web-ContextPath: /myServlet

WAR mit URL Handler in ein WAB gewandelt– Webbundle:file:///myWebapp.war?Web-

ContextPath=/myServlet Implementation von Spring DM (RI) und Pax Web Deployment wie jedes andere Bundle

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Applikationsarchitektur

Spring Dynamic Modules - OSGi with Spring Framework

OSGi Framework

JVM

Web Container Bundle 1 Bundle 2

WebApp WebApp

Bundles und WebApps sollen Services teilen!

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Demo

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

WebMonitor

Fragmente & IntegrationstestsBernd Weber

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Fragmente Pax Exam Einfacher Integrationstest Erweiterter Test

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Ergänzen oder erweitern ein Wirts-Bundle Sind selbst ein Bundle, aber– nur mit Wirt lebensfähig– ohne eigenen Class Loader– ohne BundleActivator

Können beliebigen Inhalt haben Werden beim Resolve dem Wirt hinzugefügt Wirt + Fragment = Laufzeit-Bundleinhalt Einsatz: Übersetzungen, Konfigurationen,

Stylesheets, Skins

Fragmente

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker-Konfiguration

Ausgabeordner von WorkerService konfigurierbarpublic final class WorkerServiceImpl implements WorkerService { private static final String BUNDLE_PROPERTIES_FILE = "worker.properties"; private static final String PROPERTYNAME_OUTPUT_DIR = "worker.outputDir"; private static final String DEFAULT_OUTPUT_DIR = "render_output"; String configuredOutput = DEFAULT_OUTPUT_DIR; ... private String getConfiguredOutput(ComponentContext context) { String setBy = "default"; Properties props = getBundleContainedProperties(context); String outputDir = props.getProperty(PROPERTYNAME_OUTPUT_DIR); if (outputDir != null && outputDir.isEmpty() == false) { setBy = "in-bundle properties"; } else { ... } enunciate("Output Directory is set by "+setBy+" to "+outputDir+"."); return outputDir; }}

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Worker-Konfiguration (2)...private Properties getBundleContainedProperties(ComponentContext context) { Properties properties = new Properties(); URL url = context.getBundleContext().getBundle(). getResource(BUNDLE_PROPERTIES_FILE); if (url == null) { enunciate(BUNDLE_PROPERTIES_FILE+" file not found in bundle."); } else { try { InputStream is = url.openStream(); properties.load(is); is.close(); } catch (IOException e) { enunciate("Error reading bundle properties file: "+ e.getMessage()); } } return properties;}...

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erstellen des Fragments

pax-create-bundle im gossipmonger-Verzeichnispackage: biz.gossipmonger.workerbundleName: biz.gossipmonger.worker-configbundleGroupId: biz.gossipmongerversion: 0.1.0

src/main/resources/worker.properties erstellen

osgi.bnd mit Fragment-Header

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Fragment nutzen

worker-config POM– <name>GossipMonger Worker Configuration</name>– Abhängigkeiten löschen

Aufruf von pax-provision lädt Fragment mit =>

WorkerServiceImpl: EnunciatorService set.WorkerServiceImpl: activating...WorkerServiceImpl: Output Directory is set by in-bundleproperties to render_outfragment.WorkerServiceImpl: activated.

Fragment-Bundle bleibt im Status resolved

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Fragmente Pax Exam Einfacher Integrationstest Erweiterter Test

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Integrationstests

Manuelles Bundle-Testen ist ineffizient pax-provision ist kein Testverfahren Bundle-Aktionen sind mit Unit-Tests nicht testbar– Ausgehende JobTimer-Events– Reaktion GateKeeper auf JobTimer-Events– Versand von Nachrichten über den Enunciator– Korrektes WorkerService-Ausgangsverzeichnis– Datei für WorkerService bereitstellen– Renderer-Artefakt (PDF) erstellt

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Pax Exam

Automatisiertes Testen von Bundle-Aktionen Bundle erstellen für Integrationstest-Modul:

$ mvn archetype:generate \ -DarchetypeGroupId=org.ops4j.pax.exam \ -DarchetypeArtifactId=maven-archetype-paxexam-junit \ -DarchetypeVersion=1.2.0

Metadaten angeben:groupId: biz.gossipmongerartifactId: biz.gossipmonger.test.workerversion: 0.1.0package: biz.gossipmonger.test.worker

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

POM anpassen

Parent-Abschnitt wie übrige Bundles ändern Compiler-Plugin, osgi-core und logging-

Dependency entfernen SNAPSHOP-Postfixes von Pax-Exam-Deps

entfernen Alle Projekt-Bundles als Deps eintragen

12OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Generierter Testfall

Verwendung des Pax Exam TestRunners BundleContext wird „injiziert“

13OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Fragmente Pax Exam Einfacher Integrationstest Erweiterter Test

14OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Einfacher Integrationstest

15OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Einfacher Integrationstest

Test für WorkerService Soll PDF-Erstellung anhand InputStream prüfen Bundles im Test: Enunciator, Worker-API, -Impl

und iText als PDF-Renderer JobTimer, GateKeeper, Fragment bleiben außen vor

Inputdatei src/test/resources/test.txt anlegen mit beliebigem Inhalt

SimpleWorkerServiceTest.java im Package biz.gossipmonger.test.worker erstellen

Benötigte Bundles werden „konfiguriert“

16OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

SimpleWorkerServiceTest@RunWith(JUnit4TestRunner.class)public class SimpleWorkerServiceTest { @Configuration public static Option[] configure() { return options( provision( // Infrastructure bundles mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium"), mavenBundle().groupId("org.apache.felix"). artifactId("org.apache.felix.eventadmin"), mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.scr"), // Project bundles mavenBundle().groupId("biz.gossipmonger"). artifactId("biz.gossipmonger.worker-api").versionAsInProject(), mavenBundle().groupId("biz.gossipmonger"). artifactId("biz.gossipmonger.worker-impl").versionAsInProject(), mavenBundle().groupId("biz.gossipmonger"). artifactId("biz.gossipmonger.enunciator").versionAsInProject(), mavenBundle().groupId("biz.gossipmonger.com.itextpdf"). artifactId("biz.gossipmonger.com.itextpdf.itext").versionAsInProject() ) ); } // Test method see next slide}

17OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Inhalt Test-Methode

@Testpublic void workerServiceResultExists(final BundleContext bundleContext) { ServiceReference ref = bundleContext.getServiceReference( biz.gossipmonger.worker.WorkerService.class.getName()); Assert.assertNotNull(ref); WorkerService worker = (WorkerService) bundleContext.getService(ref); Assert.assertNotNull(worker); try { String filename = "test.txt"; URL url = bundleContext.getBundle().getResource(filename); InputStream is = url.openStream(); File file = worker.process(is, filename); Assert.assertNotNull(file); String filePath = file.getAbsolutePath(); Assert.assertTrue(filePath + " does not exist", file.exists()); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); }}

18OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Integrationstest ausführen

Ggf. Bundles in lokalem Maven-Repo installieren(mvn install)

Wechsel in Verz. biz.gossipmonger.test.worker Aufruf von mvn test

Oder: Eclipse -> Run As -> JUnit Test

19OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Fragmente Pax Exam Einfacher Integrationstest Erweiterter Test

20OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erweiterter Test

21OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erweiterter Test

Test der automatisierten Verarbeitung Input-Datei in Eingangsverzeichnis erzeugen Nach spätestens 12 Sekunden muss Ergebnisdatei

in konfig. Verzeichnis da sein!

ExtendedWorkerServiceTest.java im Package biz.gossipmonger.test.worker erstellen

Bundles: wie vorher, zudem JobTimer, GateKeeper, Worker-Config

Log-Profil Test auf Felix und Equinox

22OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erweiterter Test: Beteiligte@RunWith(JUnit4TestRunner.class)public class ExtendedWorkerServiceTest { @Configuration public static Option[] configure() { return options( felix(), equinox(), logProfile(), provision( ... mavenBundle().groupId("biz.gossipmonger"). artifactId("jobtimer").versionAsInProject(), mavenBundle().groupId("biz.gossipmonger"). artifactId("biz.gossipmonger.gatekeeper").versionAsInProject(), mavenBundle().groupId("biz.gossipmonger"). artifactId("biz.gossipmonger.workerconfig"). versionAsInProject().noStart(), ... ) ); } // See next slides}

23OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erweiterter Test: Setup

private class TestEventHandler implements EventHandler { public void handleEvent(Event event) { System.out.println(event.toString()); resultPath = (String) event.getProperty("output"); }}

@Beforepublic void setup(final BundleContext context) { ... // clean or create input dir String[] top = new String[] { "biz/gossipmonger/gatekeeper" }; Map<String, Object> map = new Hashtable<String, Object>(); map.put(EventConstants.EVENT_TOPIC, top); context.registerService(EventHandler.class.getName(), new TestEventHandler(), (Dictionary<String, Object>) map); ... // create test file from scratch in input dir}

resultPath = Ausgabepfad der gerenderten Datei Event kommt vom GateKeeper.postResult

24OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Test-Methode

@Test(timeout=12000) klappt leider nicht wegen Laden der Plattform und Bundles

=> Eigener Sekundenzähler bis 12 (sollte für JobTimer und zum Rendern reichen)

Zu jeder Sekunde wird resultPath auf Inhalt geprüft Steht was drin:– Pfad-Existenz prüfen– Prüfen, ob Datei– Prüfen, ob Verzeichnis der Fragment-

Konfiguration entspricht

25OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Test-Methode@Testpublic void workerServiceResultEventOccurs(final BundleContext bundleContext) { synchronized (this) { int i = 0; while (i < 12 && resultPath == null) { try { System.out.println("Wait a second (" + ++i + ")"); wait(1000); } catch (InterruptedException e) { assertTrue("Testcase was interrupted", false); } } if (i == 12) { assertTrue("Testcase has timed out", false); } } File file = new File(resultPath); assertTrue("Result path doesn't exist.", file.exists()); assertTrue("Result path is no file.", file.isFile()); String parentName = file.getParentFile().getName(); assertEquals("Result path is not configured by in-bundle properties file", "render_outfragment", parentName);}

26OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Erweiterten Test ausführen

Ggf. Bundles in lokalem Maven-Repo installieren Wechsel in Verz. biz.gossipmonger.test.worker Aufruf von mvn test

Oder: Eclipse -> Run As -> JUnit Test

Distributed OSGiPatrick Baumgartner

OSGi Compendium Spezifikation Kapitel 13

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Überblick

RFC 119: Remote Services

Services einer Remote Maschine benutzen– Andere Maschine, verbunden über ein Netzwerk– Andere JVM, andere Adresse oder Sprache

ProduziertService A

KonsumiertService A

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Einführung

Sehr dynamisches System Implementiert durch Eclipse ECF und Apache CXF (RI) RFC übernimmt die Spezifikation der Schnittstelle Transport ist Sache des Frameworks– z.B. Apache CXF → WebServices

Zusätzliche Schritte im vergleich zu lokalen Services– Registration / Security– Lookup (Network Discovery)– Aufräumen

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Konfiguration (Service und Konsument)

service.exported.interfaces– *– org.example.BarService,org.example.FooService

service.exported.configs– org.apache.cxf.ws – org.apache.cxf.rs– ecf.generic.server

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Konfiguration (Apache CXF WS)

org.apache.cxf.ws.httpservice– http://localhost:9090/myRemoteService

org.apache.cxf.ws.httpservice.contex– /myRemoteService

org.apache.cxf.ws.frontend – jaxws

org.apache.cxf.ws.databinding– jaxb / aegis

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Konfiguration (Apache CXF RS)

org.apache.cxf.ws.httpservice– http://localhost:9090/myRemoteService

org.apache.cxf.ws.httpservice.contex– /myRemoteService

org.apache.cxf.rs.provider – true / false

org.apache.cxf.rs.provider.expected – true / false

org.apache.cxf.rs.provider.globalquery – true / false

org.apache.cxf.ws.databinding– jaxb / aegis

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Remote LogServer (Standalone)

LogServer implementiert mit Spring DM META-INF/spring/bundle-context-osgi.xml

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Remote LogClient (enunciator-remote)

Declarative Services– Default: OSGI-INF/remote-service/remote-services.xml – Manifest: Remote-Service: META-INF/osgi

Z.B.: Fragment für Enunciator

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Protokoll - Test

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Lab - DOSGi

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

DOSGi Discovery

RFC 119 beschreibt einen Weg um Metadata eines Remote Services zu publizieren/beziehen

Protokolle: Zeroconf/Bonjour, ServiceLocation Protocol (SLP), Apache Zookeper, Files

ProduziertService A

KonsumiertService A

11OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Outlook

Aliens - Bundles from Outer (Java) Space

Oliver Braun

22OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Scala

Vielversprechende Sprache auf der JVM Hybridsprache OOP + FP– Objektfunktional / Postfunktional

Natürliche Integration mit Java Interfaces mit Implementierung -> Traits Funktionale Programmierung– Funktionen– Higher Order Functions– Pattern Matching („verallgemeinertes switch“)

(fast) Alles kann Alles enthalten

33OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Reine Objektorientierung Alles ist ein Objekt– Keine Primitives in der Sprache (aber auf der JVM)

Int, Float, ...– Keine besondere Behandlung von Arrays– Keine static Member => Singleton Objekte

class Example { ...}object Example { ...}

44OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Typsystem

55OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Statisch typisiert

Lokaler Typinferenzmechanismus– Statt in Java:Map<Integer,String> myMap =

new Map<Integer,String>();– In Scalaval myMap: Map[Int,String] = Map()

– Oderval myMap = Map[Int,String]()

– Oder sogarval myMap = Map(1 -> “eins“, 2 -> “zwei“)

66OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Klassenparameter und „Operatoren“// Javaclass Rational {

final int x;final int y;Rational(int x, int y) {

this.x = x;this.y = y;

}public Rational add(Rational other) {

return new Rational(x+other.x,y+other.y);}

}// Scalaclass Rational(x: Int, y: Int) {

def +(other: Rational) =Rational(x+other.x, y+other.y)

} // a + b

Rational a = new Rational(1,2);Rational a = new Rational(2,3);Rational c = a.add(b)

val a = new Rational(1,2);val b = new Rational(2,3);val c = a + b

77OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

ScalaModules – DSL für OSGi// JavaServiceReference reference = context.getServiceReference(Greeting.class.getName());if (reference != null) { try { Object service = context.getService(reference); Greeting greeting = (Greeting) service; if (greeting != null) { System.out.println(greeting.welcome()); } else { System.out.println("No Greeting service available!"); } } finally { context.ungetService(reference); }} else { System.out.println("No Greeting service available!");}// Scalacontext findService withInterface[Greeting] andApply { _.welcome } match { case None => println("No Greeting service available!") case Some(welcome) => println(welcome)}

88OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi-Bundle in Scalapackage biz.gossipmonger.chirp

import org.osgi.service.log.LogServiceimport org.osgi.framework.{ BundleActivator, BundleContext, ServiceReference }import org.eclipse.scalamodules._

import com.tedneward.scitter._

class Chirp extends BundleActivator {

override def start(context: BundleContext) { // → next Slide }

override def stop(context: BundleContext) {}

}

99OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

OSGi-Bundle in Scala… override def start(context: BundleContext) { val chirp = new LogService { override def log(level: Int, message: String) { log(null, level, message, null) } override def log(level: Int, message: String, exception: Throwable) { log(null, level, message, exception) } override def log(sr: ServiceReference, level: Int, message: String) { log(sr, level, message, null) } override def log(sr: ServiceReference, level: Int, message: String, exception: Throwable) { val twitter = new Scitter("enunciator","geheim") twitter update message } } context createService chirp }…

1010OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

... und wie geht's weiter

Anpassen des POM– Abhängigkeiten zur Scala-Bibliothek, ...

Übersetzen mit Maven ScalaModules und ScalaBibliothek-Bundles in die

Datei für den Pax Runner Wegen Scitter noch zusätzliche Abhängigkeiten Pax Runner starten und los geht's

LauncherBernd Weber

2OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Agenda

Ziele Spezifikation Implementierung Konfiguration

3OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Java-Applikation Kein Pax Runner o.ä. notwendig Selbständiges Laden/Starten der Bundles Verschiedene Bundle-Quellen nutzbar Erweiterbar Wahl der OSGi-Plattform Debug-Unterstützung WebStart – Analogie

Launcher - Ziele

4OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Launcher – Spezifikation

OSGi Framework Launching APIOSGi Core Specification, Kap. 4.2 Frameworks und 6.2 org.osgi.framework.launch

FrameworkFactory erzeugt System Bundle Framework-Interface = Bundle-Methoden +

init/start/stop/... BundleContext nach init() vorhanden Bundles installieren nach init() möglich Bundles starten nach start() möglich waitForStop() blockiert bis Framework-Ende

5OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Implementierung

Launcher ist eigenständiges Projekt Keine Abhängigkeit zum GossipMonger Neues Verzeichnis, darin Aufruf von

$ mvn archetype:generateChoose a number: (...): <default Quickstart>groupId: biz.gossipmongerartifactId: biz.gossipmonger.launcherversion: 0.1.0package: biz.gossipmonger.launcher

6OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

POM Abhängigkeiten

Framework-Klasse sollte im ClassPath liegen => Framework-Abhängigkeit definieren<dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.framework</artifactId> <version>2.0.2</version></dependency>

Infrastruktur-Abhängigkeiten definieren– Maven-Dependencies mit scope „runtime“– org.ops4j.pax.url / pax-url-mvn (URL-Handler)– org.ops4j.pax.url / pax-url-obr (URL-Handler)– org.apache.felix / org.osgi.service.obr (OBR API)– org.apache.felix / org.apache.felix.bundlerepository (OBR Admin)

7OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Der Launcher im Groben

System Bundle erzeugen und starten Bundle-Locations ermitteln und Bundles

aktivieren (installieren und starten) für– Infrastruktur-Bundles– Ggf. Debug-Bundles– Applikations-Bundles

Auf Framework-Ende warten

8OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Implementierung Framework Factory erzeugenprivate FrameworkFactory getFrameworkFactory() throws Exception { String filename = "META-INF/services/org.osgi.framework.launch. FrameworkFactory"; List<String> content = getResourceContent(filename); ... // check for exactly one entry return (FrameworkFactory) Class.forName(content.get(0)).newInstance();}– Class.forName für Java < 6– ServiceLoader.load für Java >= 6

FrameworkFactory factory = getFrameworkFactory();Map<String, String> map = getFrameworkSettings(args);Framework framework = factory.newFramework(map);framework.start();

System Bundle erzeugen und starten

9OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Implementierung

Locations der Infrastruktur-Bundles ermitteln– Methode getInfrastructureBundles– liefert List<String> mit Bundle Locations– Ergebnis: JARs aus „lib“ außer System Bundle

Bundles starten– Methode activate(context, locations)– 1. Schleife installiert Bundles:

Bundle b = context.installBundle(location);– 2. Schleife startet Bundles (Fragmente nicht)

bundle.start(); Analog für Debug und Application Bundles

10OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun

Launcher – Konfiguration

# The bundle cache shall be cleaned at every startorg.osgi.framework.storage.clean = onFirstInit...

Framework / Umgebung konfigurierenMETA-INF/settings/FrameworkSettings

Debug-Bundles konfigurierenMETA-INF/settings/DebugBundles

Applikations-Bundles konfigurierenMETA-INF/settings/ApplicationBundles# Install Apache SCR and Event Admin Service from OBRobr:org.apache.felix.scr/1.4obr:org.apache.felix.eventadmin/1# Install PAX Logging from Mavenmvn:org.ops4j.pax.logging/pax-logging-api/1.4mvn:org.ops4j.pax.logging/pax-logging-service/1.4# Install the GossipMonger Bundles from Mavenmvn:biz.gossipmonger/jobtimer/0.2.0...

top related