aqute osgi bootcamp workshop exercise by peter kriens ceo aqute osgi technology officer and osgi...

104
aQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

Upload: landon-doyle

Post on 27-Mar-2015

232 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

aQuteOSGi Bootcamp

Workshop Exercise

By Peter KriensCEO aQute

OSGi Technology Officer andOSGi Fellow

Page 2: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

Setting Up The Environment

• The CD contains all the tools you need:– Java 1.4.1– Eclipse 2.0.2– Exercise projects with source (ex dir)– Framework fwx.exe

• Also available on the network \\ziggy\fwx

• Install Java 1.4.1, Install Eclipse

• Copy the workshop dir to c:\fwx

Page 3: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

What Will We Do?

• These exercises take a step by step approach to make a larger program

• This program is a “See your buddies” Web page viewer

• Each participant will make a Web page

• This web page is automatically registered with all participants portal's

• With Zero Administration …

Page 4: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

Overview

app2

app3 app1

app4

Browser

app 1app 2app 3app 4

SP 2

SP 3

SP 4

SP 1

multicast

Page 5: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

Architecture: Classes

ActivatorDistributor

Link

HttpTrackerTracks httpservers

findsbuddies

<<interface>>Http Service

ServiceTracker

Thread<<interface>>BundleActivator

Tracks buddies Registers page

Portal Tracks portal entries

Registers /portal page

LogService

Logs messages

HttpContext

Page 6: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

What Will We Learn?

• Using Eclipse

• Constructing an OSGi bundle

• Class path management

• Using the Log service

• Tracking of the Http Services

• Registering a servlet

• Using the demo portal

• Networking code

Page 7: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Hello World Bundle

• Create a simple bundle printing "Hello World" and "Goodbye World" at start and stop

• What will you learn?– Construct a BundleActivator class– Add a correct Manifest– Place it all in a JAR file– Starting the Framework– Install/Uninstall a bundle

Page 8: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Back to Basics: Hello World

Activator

The Activator class will print “Hello World” when the bundle is started and “Goodbye World” when it stops.

<<interface>>BundleActivator

Page 9: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Getting Started

• Assumptions– Eclipse 2.0.2 (check in Help:About, 2.0.0 does not

work!) installed– Started Eclipse

Page 10: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Eclipse

Page 11: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Getting Started

• Create new Java Project– File:New:Project– Java Project, Next– Name is “ws”– Default location, Next– Libraries, Add external jars,

• servlet.jar, osgi.jar (from where you copied the files. c:\fwx\osgi.jar)

– Attach source (select osgi.jar), Finish

Page 12: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Add External Jar

Page 13: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Setup Activator class

• Add Package– File:New:Package– Name, aQute.world.congress

Page 14: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Setup Activator

• Add new class

• File:New:Class– Package, aQute.world.congress– Name, Activator– Interfaces

• Add BundleActivator

• Finish

• Eclipse will open a generated source file

Page 15: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Activator class setup

Page 16: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Write Hello/Goodbye World

• Fill in the System.out.println(“...”) in the appropriate places

• Save the file (File:Save or control-S)– This automatically compiles, so correct any errors

Page 17: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create The Manifest

• We only define what class to start: Activator

• File:New:File, name it Manifest.mf – Store in aQute.world.congress package/folder

• Manifest MUST end with 2 empty lines!!• Fill in (and save):

Manifest-Version: 1.0Bundle-Activator: aQute.world.congress.Activator

Page 18: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create Manifest

Page 19: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create Bundle JAR file!

• Select “ws” in left pane

• Press right mouse button

• Select Export

• Select JAR File

• Next

Page 20: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create JAR File

• Export Destination– Name it ws.jar– Save the JAR in the load directory

where you copied fwx,e.g. c:\fwx\load

• Next

Page 21: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create JAR file

• Deselect “with compile errors”

• Save the description in the “ws” workspace, under the name bundle.jardesc

• Next

Page 22: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Create JAR file

• Set to use existing Manifest– Select Manifest.mf

• Finish

• (It is OK to create theload directory)

Page 23: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Starting A Framework

• The fwx.jar is the OSGi Reference Framework with all the R3 services reference implementations– This Framework is not optimized, nor industrialized– It expires in 60 days– Contact a vendor for a real framework

• To start it, open a window on its directory and double click it

• It will automatically start all bundles in the load directory– This is not standard but implemented in a bundle

Page 24: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Starting the Framework

Page 25: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 Restarting

• You can restart the bundle by – select the bundle.jardesc– Right mouse: Create Jar

• This works because the fileinstall bundle on the Framework will detect that the JAR file is modified in the load directory

• This will automatically update the bundle in the Framework (look at the console)

Page 26: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.1 What Did We Learn?

• We learned how to create a real bundle

• This bundle needed– An Activator class– A Manifest

• These components were packed in a JAR file

• This JAR file was installed and started on an OSGi Framework with the fileinstaller bundle

• The console was used to see the start and stop methods

Page 27: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Using the Log Service

• Instead of using the console, change the code to use the Log Service from the registry

• What will you learn in this exercise?– Use a service from another bundle– Import packages from another bundle– Get a service from the registry– Use the log service– Find out the methods of a service

Page 28: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Using The Log Service

Activator

We will now use a service: The Log Service

<<interface>>BundleActivator

LogService

Logs messages

Page 29: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

org.osgi.service.log v1.1Log Service

• Simple and small Log service for operator

• 4 Levels– INFO, DEBUG, WARNING, ERROR

• Automatically logs framework events in a defined way

• Other bundles can access log history– Management bundle– Length implementation dependent

• Used also for accounting, notifications

Page 30: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

org.osgi.service.log v1.1Log Service

a log usera log user a log readera log reader

LogServiceLogService LogEntryLogEntry LogListenerLogListener LogReaderService

LogReaderService

a log service impl.

a log service impl.

A log entryimpl.

A log entryimpl.

A log readerimpl.

A log readerimpl.

Log Service Impl. bundle

Log a message

Store a message for retrieval and broadcast

Message log

Send new log entry

Retrieve log

A loguser bundle

A logreaderusing bundle

Page 31: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Prepare for the Log Service

• Save the BundleContext parameter in a context instance variable

BundleContext context;public void start(BundleContext context) { this.context = context; ...}

Page 32: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 The log() method

• Add a log() method to the Activator class:

void log( String msg, Throwable exception ) { ServiceReference ref = context.getServiceReference( LogService.class.getName() ); LogService log = null; if ( ref != null ) { log =(LogService) context.getService(ref); if ( log != null ) { if ( exception == null ) log.log( LogService.LOG_INFO, msg ); else log.log( LogService.LOG_ERROR, msg, exception ); } context.ungetService(ref); return; } System.out.println( msg + " : " + exception );}

Page 33: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Use the log method

• Replace the calls to System.out with calls to the log() method

public void start(BundleContext context) { this.context = context; log( "Hello world", null );}public void stop(BundleContext context){ log( "Goodbye world", null );}

Page 34: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Organize Imports

• Source:Organize Imports

• This will automatically add the necessary import statements

Page 35: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Contents of LogService

• How can you find out what the LogService can do for you?

– Use the Javadoc (on the CD)– Click on the type, open context menu (right mouse

button) and select "Open Declaration"– Use the Ctrl-Space function in Eclipse

Page 36: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Finding The Methods

Type Ctrl-Space

Page 37: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Importing

• We use the Log Service, this requires the import of the org.osgi.service.log package

• This is indicated in the Manifest file with the Import-Package manifest header

• This header may contain any number of packages, separated with a comma, and optionally with a specification-version modifier

Page 38: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Modify The Manifest

• Edit Manifest.mf

• Add Import-Package for– org.osgi.service.log

Manifest-Version: 1.0Bundle-Activator: aQute.world.congress.ActivatorImport-Package: org.osgi.framework, org.osgi.service.log;specification-version=1.0

Page 39: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Using the Log Service

• Save the source file (correct compile errors)

• Select bundle.jardesc, right menu, Create JAR

• Check the console of fwx:– Goodbye world– But no Hello world … This is now in the log– Where is the log????

Page 40: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Viewing the Log Service

• Open a telnet session– Start:Run:telnet localhost 2011

• This opens a simple OSGi console/debugger

• Type– log

Page 41: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 The console

• The console bundle has many functions– exports - shows package export/import– lsb - list bundles– lss - list services (can use filter)– install <uri> - install– uninstall <id>– update bundle <id>– help

• Can be extended by other bundles, see org.osgi.tools.command.CommandProvider

Page 42: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 Changing the version

• Verify what happens when the specfication version is modified

• Set the version to 1.8 and create the JAR file

Page 43: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2 What Did We Learn?

• Using the Log Service

• Importing a package, with version specification

• Getting a service from the registry

• Using the OSGi console bundle

Page 44: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2a Using the Service Tracker

• Track the OSGi Log Service with a Service Tracker

• What will we learn?

• How to efficiently track a service

• Assure that a temporary absence of a service does not disrupt our program

• The org.osgi.util.tracker.ServiceTracker utility

Page 45: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2a Use the ServiceTracker

• Create a ServiceTracker for the log

ServiceTracker tracker;

public void start(BundleContext context) { this.context = context; tracker = new ServiceTracker( context,

LogService.class.getName(), null ); tracker.open();}

Page 46: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2a Use The ServiceTracker

• Change the log() method to use the tracker

void log( String msg, Throwable exception ) { try { LogService log =(LogService) tracker.waitForService(15000); if ( exception == null ) log.log( LogService.LOG_INFO, msg ); else log.log( LogService.LOG_ERROR, msg, exception ); return; } catch ( InterruptedException ie ) {} System.out.println( msg + " : " + exception );}

Page 47: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.2a What Did We Learn?

• We now correctly handling the coming and going of services

• Using a ServiceTracker simplifies the coding of services that are obtained from the registry

• The use of the log is now robust

Page 48: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Using the Http Service

• Register a static HTML page with the local Http Service

• What will we learn?

• Use the ServiceTracker more extensively

• How to register a static HTML page with the Http Service

• How to implement the HttpContext

Page 49: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Publishing a page

HttpTrackerTracks httpservers

<<interface>>Http Service

ServiceTracker

Registers page

Registers /portal page

Activator

<<interface>>BundleActivator

LogService

Logs messages

HttpContext

Page 50: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

org.osgi.service.http v1.1Http Service

• Provides web access to bundles

• A powerful servlet runner– Supports Servlets Version 2.1

• Very simple to export static pages and files (like images)

• Automatically unregisters servlets when bundle is stopped

Page 51: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

org.osgi.service.http v1.1Http Service

Impl. Of Httpcontext

Impl. Of Httpcontext

Impl. Of servlet

Impl. Of servlet

HttpContextHttpContext NameSpaceException

NameSpaceException HttpServiceHttpService

javax.servlet.Servlet

javax.servlet.Servlet

Default impl.HttpContext

Default impl.HttpContext

Resourceregistration

Resourceregistration

Servletregistration

Servletregistration

Bundles main code

Bundles main code

javax.servlet.Request/Response

javax.servlet.Request/Response

NameSpacealias

NameSpacealias

An Http Serviceimpl.

An Http Serviceimpl.

Page 52: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Create An Html Page

• File:New:File– Directory, aQute/world/congress– Call it page.html

• Edit it (select page.html, Open With:Text Editor)

<html> <head> <title>My Demo HTML page</title> </head> <body> <h1>My Demo</h1> This is aQute's (use your own name!) demo page </body></html>

Page 53: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Create an HTML Page

Page 54: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Create HttpTracker

• HttpTracker tracks Http Service objects and adds a “page.html” to every Http Service

• It extends ServiceTracker to simplify tracking– Object addingService(ServiceReference)– void modifiedService(ServiceReference,Object)– void removedService(ServiceReference,Object)

• Create new class aQute.world.congress.HttpTracker that extends ServiceTracker, implements HttpContext

Page 55: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

Page 56: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• And it needs a variable, constructor, add:

Activator activator;

public HttpTracker( Activator activator, BundleContext context ) { super( context, HttpService.class.getName(),null); this.activator = activator;}

Page 57: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• addingService

public Object addingService( ServiceReference reference ) { HttpService http = (HttpService)super.addingService(reference); try { http.registerResources("/mydemo", "", this ); } catch( NamespaceException e ) { activator.log( "Cannot register because “

+ “name is already in use: /mydemo", e ); } return http;}

Page 58: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• Modify the getResource method to return resources from the package

public URL getResource(String name) { try { URL url = getClass().getResource( name.substring(1) ); return url; } catch( Exception e ) { e.printStackTrace(); } return null;}

Page 59: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• handlSecurity returns false. This means deny access, change it to return true.

public boolean handleSecurity( HttpServletRequest request, HttpServletResponse response) throws IOException { return true;}

Page 60: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• Organize Imports

• Save it

• Add an instance variable for the Http Tracker to Activator class

• And add the following lines to the start() method http = new HttpTracker( this, context );http.open();

HttpTracker http;

Page 61: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Clean-up

// Add to stop methodhttp.close();

Page 62: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Modify The Manifest

• Add Import-Package for– org.osgi.util.tracker– org.osgi.service.http– javax.servlet.http, javax.servlet

Manifest-Version: 1.0Bundle-Activator: aQute.world.congress.ActivatorImport-Package: org.osgi.framework, org.osgi.service.log,org.osgi.util.tracker, org.osgi.service.http,javax.servlet.http, javax.servlet

Page 63: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 Add HttpTracker class

• Save open files

• Select bundle.jardesc– Create JAR

• Open a browser and surf into– http://localhost/mydemo/page.html

• Ensure that your HTTP proxy is off!– IE : Tools : Internet Options : Connections : Lan

settings

Page 64: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3 What Did We Learn?

• Understanding how the ServiceTracker can be used to track services and execute a task for the registration and un-registration of a service

• Understanding the HttpContext

• Serving static pages from the local web server

Page 65: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a Use The Portal

• Register our page with a local portal bundle using the white board approach

• What will we learn?

• Using the White Board approach

• Using the provided portal with our page

• Understand service registration properties

Page 66: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a Use The Portal

Activator HttpTrackerTracks httpservers

<<interface>>Http Service

ServiceTracker

<<interface>>BundleActivator

Registers page

Portal

Registers /portal page

LogService

Logs messages

HttpContext

Page 67: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a The Nursery Portal

• Not an official OSGi specification (Nursery)

• Uses the White Board approach to collect pages

• Properties are used to convey the information

• The portal is not a service in the registry

• Clients should register any service with the right properties

• Minimizes dependencies

Page 68: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a Portal Mechanism

Registry

Bundle A{ }

register

Portalbundle

Events: register, unregister

Bundle C{ }

Bundle B{ }

Any objectget

urltitledescription

http://...My PageA demonst...

properties

Filter (url=*)

Properties

Page 69: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a Portal

• In the start() method, add the following code:

String host= InetAddress.getLocalHost().getHostName();if ( System.getProperty( "org.osgi.service.http.port" ) != null ) host += ":" + System.getProperty( "org.osgi.service.http.port" );

Dictionary properties = new Hashtable();properties.put( "title", "Local Demo Page" ); properties.put( "description", "This page demonstrates my skills!" );properties.put( "url", "http://" + host + "/mydemo/page.html" );context.registerService( String.class.getName(), "dummy", properties );

Page 70: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a Portal

• Verify that your page is registered at the portal– http://localhost:8000/portal

Page 71: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.3a What Did We Learn

• How to register a service

• The ideas behind the white board– Use the Framework registry as a private registry– Minimized dependencies

• Use of the portal

Page 72: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Finding Your Buddies

• Announce the page URL with a multicast on the network and register the received URLs with the portal

• What will you learn?

• How to register a service

• How send out multicast packages

• Using a background thread to receive packages

• Minimize consequences in the light of errors

Page 73: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Finding Your Buddies

HttpTrackerTracks httpservers

<<interface>>Http Service

ServiceTracker

Registers page

Portal

Registers /portal page

Activator

<<interface>>BundleActivator

LogService

Logs messages

Distributor

Link

findsbuddies

Thread

Tracks buddies

Tracks portal entries

HttpContext

Page 74: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

• Add a new class Distributor– Package aQute.world.congress– Extends Thread

• This class will open a UDP socket

• Will listen to all Datagram’s on port 2014

• Forwards all datagrams to the activator

• Sends an announce datagram every 5 seconds

• Simple mechanism to dynamically discover others

Page 75: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

• Add Instance variable declarations

boolean active = true;DatagramSocket socket;byte outgoing[];Activator activator;

Page 76: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

• Add Constructor

Distributor( Activator activator, String outgoing ) { super("distributor"); this.activator = activator; this.outgoing = outgoing.getBytes();}

Page 77: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

public void run() { while ( active ) try { socket = new DatagramSocket( 2014 ); socket.setSoTimeout( 5000 ); activator.log("Discovery starts.", null); … inner loop … see next slide socket.close(); socket = null; } catch(Exception e) { activator.log( "Main discover loop exit", e ); if ( active ) try { Thread.currentThread().sleep(1000); } catch( Exception x) {} } activator.log("Discovery quits.", null);}

• The run() method is the body of the thread. It will loop until the active flag becomes false. It uses the socket timeout to regularly send an announce

Page 78: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

• The inner loop of the run() method receives the package and handles errors

1.4 Add Distributor class

while ( active ) try { DatagramPacket packet = new DatagramPacket(new byte[256], 256); socket.receive(packet); String incoming = new String( packet.getData(), 0, packet.getLength()); activator.process( new Link(incoming) ); }catch(InterruptedIOException e) { announce();} catch(Exception e) { if ( active ) activator.log( "Receving remote “ + “service packets, ignoring ", e );}

Page 79: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

• The announce method is called on the timeout

void announce() throws IOException { DatagramSocket announce = new DatagramSocket(); DatagramPacket packet = new DatagramPacket( outgoing, outgoing.length, InetAddress.getByName("255.255.255.255"), 2014 ); announce.send(packet); }

Page 80: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Distributor class

• And the last close method resets the active flag and closes the port.

• Organize imports

• Save– Unresolved method in Activator: process

void close() { active = false; socket.close();}

Page 81: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Link class

• Add a Link class

• The Link class just holds the buddy info together.Hashtable properties = new Hashtable();ServiceRegistration registration;

Link( String msg ) { StringTokenizer tz =

new StringTokenizer( msg, "|" ); properties.put( "title", tz.nextToken() ); properties.put( "description",tz.nextToken()); properties.put( "url", tz.nextToken() ); }

Page 82: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Link class

• Register method, for a new discovered buddy

• Modify method, when old buddy, new message

void register( BundleContext context ) { registration = context.registerService( Link.class.getName(), this, properties );}

void modify( Link link ) { registration.setProperties(link.properties);}

Page 83: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add Link class

• Unregister when link is gone

• To get the unique key

void unregister() { registration.unregister();}

Object getUrl(){ return properties.get( "url" ); }

Page 84: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Process method in Activator

• The process method adds a buddy to the portal

• The portal tracks “url” service property.

• Edit Activator, add process methodHashtable links = new Hashtable();void process( Link link ) { Link existing = (Link) links.get( link.getUrl() ); if ( existing != null ) existing.modify( link ); else { link.register( context ); links.put( link.getUrl(), link ); existing = link; }}

Page 85: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Add and Start the Distributor

// Add to start methodString host= InetAddress.getLocalHost().getHostAddress();if ( System.getProperty(

"org.osgi.service.http.port" ) != null )host += ":" + System.getProperty(

"org.osgi.service.http.port" );

distributor = new Distributor( this, "My Title|My Own Description|http://" + host +

"/mydemo/page.html" );distributor.start();

Page 86: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Clean-up (stop method)

// Add to stop methoddistributor.close();

Page 87: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

1.4 Find the buddies

• Organize imports for all files

• Build JAR

• Browse to:– http://localhost:8000/portal

• You should see your own page, and with any luck pages from your buddies

Page 88: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 OSGi Management

• Make a web based management application

• What will we learn?– Create a servlet– Register a servlet with the Http Service– How to find out about the configuration of the

Framework– Start/Stop/Uninstall/Update bundles– Install bundles– Using XML, XSLT and HTML (a bit :-)

Page 89: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 Management Agent

• Implemented as a servlet that generates XML with all the bundle information

<top> <error>message</error> <!-- optional --> <bundle id="…" location="…" name="…" state="…"> … description … </bundle></top>

• Accepts the following parameters:– action: start/stop/update/uninstall/install– uri:<uri for installing a bundle> (only present with

install)– bundleId: <id>

Page 90: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 Management Agent

• Create a new project called "ma" (management agent)

• Add the osgi.jar and servlet.jar libraries (Properties:libraries)

Page 91: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 Creating the Activator

• Copy the Activator from the previous exercise to the "ma" project– Notice the automatic package renaming!

• Modify the Activator:– The portal registration (but keep it, it is handy)– Remove the distributor related code

• Ignore the errors for the moment

Page 92: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 Management Agent

• Copy the HttpTracker from the previous exercise• Modify the HttpTracker.addingService method,

we must register a servlet now:

public Object addingService( ServiceReference reference ) { HttpService http = (HttpService)super.addingService(reference); try { http.registerResources("/agent", "", this ); http.registerServlet("/agent/servlet", new AgentServlet(activator,context), null, this ); } catch( NamespaceException e ) { activator.log( "Name is already in use /agent", e ); } catch( Exception e ) { activator.log( "Unexpected exception ", e ); } return http;}

Page 93: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• Create an AgentServlet class, it extends the HttpServlet class

BundleContextcontext;Activatoractivator;

AgentServlet( Activator activator, BundleContext context ) { this.context = context; this.activator = activator;}

Page 94: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• The doGet method is called for an HTTP GET request:

public void doGet( HttpServletRequest rq, HttpServletResponse rsp ) throws IOException { String bundleId = rq.getParameter("bundle"); String action = rq.getParameter("action"); String uri = rq.getParameter("uri");// if install rsp.setContentType("text/xml");

PrintWriter pw = new PrintWriter( rsp.getWriter()); prolog(pw); pw.println( "<top>" ); doAction(bundleId, action, uri, pw); listBundles(pw); pw.println( "</top>" ); pw.close();}

Page 95: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• List all the existing bundles as XML

public void listBundles(PrintWriter pw) { Bundle bundles[] = context.getBundles(); for ( int i=0; i<bundles.length; i++ ) { Bundle bundle = bundles[i]; Dictionary p = bundle.getHeaders(); String name = get(p,"Bundle-Name", "?" ); String description = get(p,"Bundle-Description", "?" ); pw.println( "<bundle" +" location='" + bundle.getLocation() + "'" +" name='" + name + "'" +" id='" + bundle.getBundleId() + "'" +" state='" + bundle.getState() + "'" +">"); pw.println( escape( description ) ); pw.println( "</bundle>"); }}

Page 96: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• Perform the actual action indicated in the "action" parameter:

public void doAction(String bid,Stringaction,String uri,PrintWriter pw){ Bundle bundle = null; try { if (bid!= null ) bundle = context.getBundle( Long.parseLong(bid)); if ( action!= null ) { if ( action.equals("start") ) bundle.start(); else if ( action.equals("stop") ) bundle.stop(); else if ( action.equals("update") ) bundle.update(); else if ( action.equals("uninstall") ) bundle.uninstall(); else if ( action.equals("install") ) context.installBundle( uri ); }} catch( BundleException e ) { error(action, pw, bundle, e, e.getNestedException()); } catch( Exception e ) { error(action, pw, bundle, e, null );}}

Page 97: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• Support methods:

public void error(String action, PrintWriter pw, Bundle bundle, Exception e, Throwable nested) { pw.println( "<error class='" + e.getClass().getName() + "' action='" + action+ "' bundle='" + bundle + "'>" ); pw.println( escape(e.getMessage()) ); pw.println( "</error>" );}public void prolog(PrintWriter pw) { pw.println("<?xml version='1.0' encoding='UTF-8'?>" ); pw.println( "<?xml-stylesheet type='text/xsl' title='Compact' href='agent.xsl'?>" );}String get( Dictionary p, String key, String dflt ) { String result = (String) p.get( key ); if ( result != null ) return result; return dflt; }

Page 98: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 AgentServlet

• The escape() method is needed to prevent <&> from ending up in an attribute or text, confusing the XML parser.

String escape( String source ) { // Should escape the entities like <, >, & StringBuffer sb = new StringBuffer(); for ( int i=0; i<source.length(); i++ ) { char c = source.charAt(i); switch(c) { case '&': sb.append( "&amp;" ); break; case '<': sb.append( "&lt;" ); break; case '>': sb.append( "&gt;" ); break; default: sb.append( c ); }} return sb.toString(); }

Page 99: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 XSL

• Notice the second line in the prolog:

<?xml-stylesheet type='text/xsl' title='Compact' href='agent.xsl'?>

• This is an instruction to the browser to use XML StyLe Transformation. XSL transforms the XML to HTML. This requires an XSL file called agent.xsl

• Copy this file from the CD (this is not an XSL course!)

• This page is served in our getResource in the HttpTracker

Page 100: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 Management Agent

• Create the Manifest

• Create the JAR file (Export:Jar)

• Surf to http://localhost:8000/agent/servlet

• Or to http://localhost:8000/portal and select the management agent

• Simple isn't it?

Page 101: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

2 What did we learn?

• We created a servlet that generates XML

• The XML was derived from the actual bundle configuration

• Servlet parameters were used to start/stop/install/uninstall/update bundles

• XSL was used to make XML

Page 102: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

Conclusion

• Surprisingly little code is necessary to perform interesting functions

• Coupling to other parts is minimal because OSGi specified interfaces are intermediates

• Tools are available to simplify creation of manifest and bundle files

• This is only the beginning ...

Page 103: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

Vendors With Tools & Courses

• Acunia - www.acunia.com

• aQute - www.aQute.se

• IBM - www.ibm.com/embedded

• Gatespace - www.gatespace.com

• ProSyst - www.prosyst.com

• Atinav - www.atinav.com

• Espial - www.espial.com

• See for more www.osgi.org

Page 104: AQute OSGi Bootcamp Workshop Exercise By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow

©1999-2003 aQute, All Rights Reserved

aQute

www.aQute.biz

+46 300 39800, [email protected]

z