Subsystems, Repository, Contracts and more...
David Bosschaert
OSGi Application Provisioning
Deep Dive
1 of 41
About me
David Bosschaert (davidb@apache.org)
Works at Adobe R&D Basel
Co-chair OSGi EEG
Apache committer
Open-source and cloud
enthusiast
2 of 41
Topics
A look at the latest Declarative Services
Using Subsystems to package and deploy
OSGi Repository to resolve dependencies
Portable Java Contracts
... demo throughout ...
3 of 41
Running Example
Device Monitor
... a little webapp to monitor all your gadgets ...
4 of 41
Declarative Services
Being updated for Enterprise R6
Improved Configuration Admin
integration
Introspective API
Prototype Service Factory
... other smaller improvements ...
5 of 41
DS Configured Component
iimmppoorrtt javax.servlet.SSeerrvvlleett;
iimmppoorrtt org.osgi.service.component.annotations.*;
iimmppoorrtt org.osgi.service.http.HHttttppSSeerrvviiccee;
@Component
ppuubblliicc ccllaassss DDeevviicceeMMoonniittoorr {
pprriivvaattee HHttttppSSeerrvviiccee httpService;
@Reference
ppuubblliicc vvooiidd setHttpService(HHttttppSSeerrvviiccee svc) {
httpService = svc;
}
@Activate
ppuubblliicc vvooiidd activate(MMoonniittoorrCCoonnffiigg cfg) {
SSttrriinngg rootCtx = cfg.ctxPrefix();
iiff (!rootCtx.endsWith("/"))
rootCtx = rootCtx + "/";
registerServlet(rootCtx + "dmon", nneeww MMoonniittoorrSSeerrvvlleett());
registerServlet(rootCtx + "device", nneeww DDeevviicceeSSeerrvvlleett());
}
pprriivvaattee vvooiidd registerServlet(SSttrriinngg ctx, SSeerrvvlleett servlet) {
httpService.registerServlet(ctx, servlet, nnuullll, nnuullll);
}
}
6 of 41
Configuration using
Annotations
ppuubblliicc @interface MMoonniittoorrCCoonnffiigg {
SSttrriinngg ctxPrefix() ddeeffaauulltt "/";
bboooolleeaann autoRefresh() ddeeffaauulltt ffaallssee;
iinntt interval() ddeeffaauulltt 30;
}
annotation used as an ordinary interface,
with added defaults
... weird but works great ...
7 of 41
Example Bundle Manifest
BBuunnddllee-MMaanniiffeessttVVeerrssiioonn: 2
BBuunnddllee-SSyymmbboolliiccNNaammee: devicemon-ds
BBuunnddllee-VVeerrssiioonn: 0.0.1
SSeerrvviiccee-CCoommppoonneenntt: OSGI-INF/component.xml
IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)",
org.coderthoughts.devicemon.ssh;version="[1.0,2)",
org.osgi.service.http;version="[1.2,2)"
RReeqquuiirree-CCaappaabbiilliittyy:
osgi.extender;filter:="(&(osgi.extender=osgi.component)
(version>=1.2.0)(!(version>=2.0.0)))",
osgi.whiteboard;filter:="(osgi.whiteboard=osgi.http)"
Note that the javax.servlet import should really use
contracts!
8 of 41
Finished app...
2 Bundles
devicemon.jar
depends on DS and HTTP Service
devicemon-ssh.jar
depends on Apache Mina SSHD
9 of 41
Deploy it...
Now I want to easily deploy my app
⟱
create a Subsystem of it!
10 of 41
Subsystems
OSGi Enterprise spec 134
A subsystem...
collection of bundles put together
feature - everything shared
application - isolated, nothing shared out
composite - configurable in-between
a zip file with .esa extension
can be nested
can depend on bundles or other
subsystems
Subsystems can use OSGi Repositories to
resolve dependencies
11 of 41
devicemon-ds.esa
Just a zip file...
$ tar tvf devicemon-ds.esa
-rwxrwxrwx 99 8 JJaann 15:40 OSGI-INF/SUBSYSTEM.MF
-rwxrwxrwx 18184 8 JJaann 16:01 devicemon-ds.jar
-rwxrwxrwx 5968 8 JJaann 16:02 devicemon-ssh.jar
Subsystem Manifest
$ cat OSGI-INF/SUBSYSTEM.MF
SSuubbssyysstteemm-SSyymmbboolliiccNNaammee: devicemon-ds
SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1
SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature
note, I didn't put my dependencies in the .esa file
12 of 41
Feature subsystems
devicemon-ds.esa: a Feature Subsystem
All the bundles inside work just as shared bundles
in OSGi
Subsystem installed/started/stopped as 1 unit
Dependencies pulled in either from .esa or from
repository
as needed
are reference-counted
13 of 41
Apache Felix + Apache Aries Subsystems
14 of 41
Add HTTP subsystem
15 of 41
3 bundles in 1 operation
16 of 41
Our subsystem doesn't install!
NB: a failed subsystem install doesn't
leave any bundles behind...
17 of 41
OSGi Repository
OSGi Enterprise spec 132
Inspired by Felix OBR
Simple but powerful
Actual repo can be remote or local
Find resources
based on their capabilities
any resource
any capability
OSGi has defined:
standard Bundle capabilities
Bundle, Subsystem resource types
some more general capabilities
18 of 41
Add resources using standard XML
Example
<<rreeppoossiittoorryy increment='1389281419631' name='MyRepo' xmlns='http://www.osgi.org/xmlns/repository/v1.0.0'>>
<<rreessoouurrccee>>
<<ccaappaabbiilliittyy namespace='osgi.identity'>>
<<aattttrriibbuuttee name='osgi.identity' value='org.apache.sshd.core'//>>
<<aattttrriibbuuttee name='type' value='osgi.bundle'//>>
<<aattttrriibbuuttee name='version' type='Version' value='0.9.0'//>>
<<//ccaappaabbiilliittyy>>
<<ccaappaabbiilliittyy namespace='osgi.content'>>
<<aattttrriibbuuttee name='osgi.content' value='a1c64578808c38a63cd6563e9936f025638aeaf9de70f36765367db81c0afc38'
<<aattttrriibbuuttee name='url' value='local-repo/sshd-core.jar'//>>
<<aattttrriibbuuttee name='size' type='Long' value='464733'//>>
<<aattttrriibbuuttee name='mime' value='application/vnd.osgi.bundle'//>>
<<//ccaappaabbiilliittyy>>
<<ccaappaabbiilliittyy namespace='osgi.wiring.package'>>
<<aattttrriibbuuttee name='osgi.wiring.package' value='org.apache.sshd'//>>
<<aattttrriibbuuttee name='version' type='Version' value='0.5.0'//>>
<<aattttrriibbuuttee name='bundle-symbolic-name' value='org.apache.sshd.core'//>>
<<aattttrriibbuuttee name='bundle-version' type='Version' value='0.9.0'//>>
<<ddiirreeccttiivvee name='uses' value='org.apache.sshd.client'//>>
<<//ccaappaabbiilliittyy>>
<!-- More capabilities -->
<<rreeqquuiirreemmeenntt namespace='osgi.wiring.package'>>
<<ddiirreeccttiivvee name='filter'
value='(&(osgi.wiring.package=org.slf4j)(version>=1.6.0)(!(version>=2.0.0)))'/>
<<//rreeqquuiirreemmeenntt>>
<!-- More requirements -->
<<//rreessoouurrccee>>
<!-- More resources -->
<<//rreeppoossiittoorryy>>
19 of 41
Repository XML
Format defined by OSGi Repository Spec
Standard way to feed a repository with information
Standard way for repositories to exchange data
Generate it with the bindex/RepoIndex tool:
https://github.com/osgi/bindex
(https://github.com/osgi/bindex)
20 of 41
Repository Service
Obtain resources from the repository
Find a bundle...
RReeppoossiittoorryy repo = ... // from Service Registry ...
RReeqquuiirreemmeennttBBuuiillddeerr rb = nneeww RReeqquuiirreemmeennttBBuuiillddeerr("osgi.wiring.package");
rb.addDirective("filter",
"(&(osgi.wiring.package=org.apache.ssh)(version=0.5.0))");
RReeqquuiirreemmeenntt req = rb.build();
CCoolllleeccttiioonn<RReessoouurrccee> bundleResources = repo.findProviders(req);
... or find some photo's from the North Pole ...
RReeqquuiirreemmeennttBBuuiillddeerr rb = nneeww RReeqquuiirreemmeennttBBuuiillddeerr("com.acme.photo");
rb.addDirective("filter", "(latitude>=66.5622)");
RReeqquuiirreemmeenntt req = rb.build();
CCoolllleeccttiioonn<RReessoouurrccee> photoResources = repo.findProviders(req);
21 of 41
Add and prime a Repository
22 of 41
Our subsystem works!
23 of 41
Descriptor Subsystems
A subsystem can be just a descriptor
... with all resources obtained from a Repository
$ jar tvf generated/devicemon-ds-decl.esa
0 TThhuu JJaann 09 12:37:32 GMT 2014 OSGI-INF/
175 WWeedd JJaann 08 15:50:28 GMT 2014 OSGI-INF/SUBSYSTEM.MF
Subsystem Manifest
$ cat OSGI-INF/SUBSYSTEM.MF
SSuubbssyysstteemm-SSyymmbboolliiccNNaammee: devicemon-ds-decl
SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1
SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature
SSuubbssyysstteemm-CCoonntteenntt: devicemon-ds;version=0.0.1,
devicemon-ssh;version=0.0.1
24 of 41
Start with only
Subsystems + Repository
25 of 41
Dependencies at work
http.esa pulled in automatically
26 of 41
Unpredictable dependency
both 0.9.0 and 0.9.1 satisfy requirement
27 of 41
Subsystem Deployment Descriptor
Once QA-ed, create a DEPLOYMENT.MF to fix
dependencies
$ jar tvf generated/devicemon-ds-decl-dd.esa
283 WWeedd JJaann 15 16:39:34 GMT 2014 OSGI-INF/DEPLOYMENT.MF
175 WWeedd JJaann 08 15:50:28 GMT 2014 OSGI-INF/SUBSYSTEM.MF
it can freeze deployments
$ cat OSGI-INF/DEPLOYMENT.MF
SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1
SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature
DDeeppllooyyeedd-CCoonntteenntt: devicemon-ds;deployed-version=0.0.1,
devicemon-ssh;deployed-version=0.0.1
PPrroovviissiioonn-RReessoouurrccee: org.apache.sshd.core;deployed-version=0.9.1,
org.apache.felix.scr;deployed-version=1.8.2,
http-subsystem;type=osgi.subsystem.feature;deployed-version=1.2.0
note version 0.9.1 for org.apache.sshd.core
Ensures that the runtime deployment is the same as the QA one.
28 of 41
SSHD dependency now as predicted
29 of 41
Portable Contracts
Our bundle contains:
IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)",
This API is defined by the JCP.
but... spot the problem!
30 of 41
Semantic Versioning
... versioning policy for exported packages.
OSGi versions: <major>.<minor>.<micro>.<qualifier>
Updating package versions:
fix/patch (no change to API):
update micro
extend API (affects implementers, not clients):
update minor
API breakage:
update major
Using semantic versioning allows creating components that can
work with future patches and other compatible releases of deps
just Import-Package a range like: [5.3, 6)
31 of 41
javax.servlet Problem
IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)",
Servlet 3.0 is actually compatible with 2.5
JCP specs don't follow semantic versioning
3.0 is more of a marketing version
But what version to use for javax.servlet
in OSGi?
Different providers made different decisions
Some use 2.6 to export javax.servlet
from Servlet 3 spec
Others use 3.0
Some even use 0.0.0
This prohibits creating portable bundles
using these APIs
32 of 41
Portable Java Contracts
osgi.contract capability to the rescue
client bundle requires capability
with single 'marketing' or 'spec' version
and also imports the package
without version
osgi.contract provider binds the
contract version to package versions
IImmppoorrtt-PPaacckkaaggee: javax.servlet, javax.servlet.http
RReeqquuiirree-CCaappaabbiilliittyy: osgi.contract;
filter:="(&(osgi.contract=JavaServlet)(version=2.5))"
Enables creating portable bundles
importing non-semantically versioned
packages.
33 of 41
Our bundle manifest should really be
BBuunnddllee-MMaanniiffeessttVVeerrssiioonn: 2
BBuunnddllee-SSyymmbboolliiccNNaammee: devicemon-ds
BBuunnddllee-VVeerrssiioonn: 0.0.1
IImmppoorrtt-PPaacckkaaggee: javax.servlet,
org.coderthoughts.devicemon.ssh;version="[1.0,2)",
org.osgi.service.http;version="[1.2,2)"
RReeqquuiirree-CCaappaabbiilliittyy:
osgi.extender;filter:="(&(osgi.extender=osgi.component)
(version>=1.2)(!(version>=2.0)))",
osgi.whiteboard;filter:="(osgi.whiteboard=osgi.http)
(version>=1.0)(!(version>=2.0)))",
osgi.contract;filter:="(&(osgi.contract=JavaServlet)
(version=2.5))"
34 of 41
Providing Portable Contracts
The bundle exporting the package should
do this:
EExxppoorrtt-PPaacckkaaggee: javax.servlet;version=2.6,
javax.servlet.http;version=2.6
PPrroovviiddee-CCaappaabbiilliittyy: osgi.contract;
osgi.contract=JJaavvaaSSeerrvvlleett;version:VVeerrssiioonn=2.5;
uses:="javax.servlet, javax.servlet.http",
osgi.contract;osgi.contract=JJaavvaaSSeerrvvlleett;version:VVeerrssiioonn=3;
uses:="javax.servlet, javax.servlet.http"
as it only knows how the mapping is done.
Each marketing version is mapped to a package version.
For more details, see OSGi RFC 180
(https://github.com/osgi/design/raw/master
/rfcs/rfc0180/rfc-0180-portable-
java-contracts.pdf).
35 of 41
For all packages other than
JCP-ones
36 of 41
http://www.bndtools.org
(http://www.bndtools.org)
can help with version
maintenance!
reallybndtools
Use Semantic Versioning!
37 of 41
Where can I get it?
Core R6 spec released this week:
http://www.osgi.org/Specifications/HomePage
(http://www.osgi.org/Specifications/HomePage)
Enterprise R6 draft released this week:
http://www.osgi.org/Specifications/Drafts
(http://www.osgi.org/Specifications/Drafts)
RFCs 189, 190, 208 included in zip
38 of 41
Links
OSGi specs:
http://www.osgi.org/Specifications
(http://www.osgi.org/Specifications)
Apache Felix Project:
http://felix.apache.org (http://felix.apache.org)
OSGi RFC 180
https://github.com/osgi/design/raw/master
/rfcs/rfc0180/rfc-0180-portable-java-contracts.pdf
(https://github.com/osgi/design/raw/master
/rfcs/rfc0180/rfc-0180-portable-java-contracts.pdf)
devicemon project:
https://github.com/bosschaert/devicemon
(https://github.com/bosschaert/devicemon)
Subsystem Gogo command
https://github.com/bosschaert/coderthoughts39 of 41
/tree/master/subsystem-gogo-command
(https://github.com/bosschaert/coderthoughts
/tree/master/subsystem-gogo-command)
40 of 41
Questions?
41 of 41

OSGi provisioning deep dive and demo (Subsystems, Repository, Contracts and more) - D Bosschaert

  • 1.
    Subsystems, Repository, Contractsand more... David Bosschaert OSGi Application Provisioning Deep Dive 1 of 41
  • 2.
    About me David Bosschaert(davidb@apache.org) Works at Adobe R&D Basel Co-chair OSGi EEG Apache committer Open-source and cloud enthusiast 2 of 41
  • 3.
    Topics A look atthe latest Declarative Services Using Subsystems to package and deploy OSGi Repository to resolve dependencies Portable Java Contracts ... demo throughout ... 3 of 41
  • 4.
    Running Example Device Monitor ...a little webapp to monitor all your gadgets ... 4 of 41
  • 5.
    Declarative Services Being updatedfor Enterprise R6 Improved Configuration Admin integration Introspective API Prototype Service Factory ... other smaller improvements ... 5 of 41
  • 6.
    DS Configured Component iimmppoorrttjavax.servlet.SSeerrvvlleett; iimmppoorrtt org.osgi.service.component.annotations.*; iimmppoorrtt org.osgi.service.http.HHttttppSSeerrvviiccee; @Component ppuubblliicc ccllaassss DDeevviicceeMMoonniittoorr { pprriivvaattee HHttttppSSeerrvviiccee httpService; @Reference ppuubblliicc vvooiidd setHttpService(HHttttppSSeerrvviiccee svc) { httpService = svc; } @Activate ppuubblliicc vvooiidd activate(MMoonniittoorrCCoonnffiigg cfg) { SSttrriinngg rootCtx = cfg.ctxPrefix(); iiff (!rootCtx.endsWith("/")) rootCtx = rootCtx + "/"; registerServlet(rootCtx + "dmon", nneeww MMoonniittoorrSSeerrvvlleett()); registerServlet(rootCtx + "device", nneeww DDeevviicceeSSeerrvvlleett()); } pprriivvaattee vvooiidd registerServlet(SSttrriinngg ctx, SSeerrvvlleett servlet) { httpService.registerServlet(ctx, servlet, nnuullll, nnuullll); } } 6 of 41
  • 7.
    Configuration using Annotations ppuubblliicc @interfaceMMoonniittoorrCCoonnffiigg { SSttrriinngg ctxPrefix() ddeeffaauulltt "/"; bboooolleeaann autoRefresh() ddeeffaauulltt ffaallssee; iinntt interval() ddeeffaauulltt 30; } annotation used as an ordinary interface, with added defaults ... weird but works great ... 7 of 41
  • 8.
    Example Bundle Manifest BBuunnddllee-MMaanniiffeessttVVeerrssiioonn:2 BBuunnddllee-SSyymmbboolliiccNNaammee: devicemon-ds BBuunnddllee-VVeerrssiioonn: 0.0.1 SSeerrvviiccee-CCoommppoonneenntt: OSGI-INF/component.xml IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)", org.coderthoughts.devicemon.ssh;version="[1.0,2)", org.osgi.service.http;version="[1.2,2)" RReeqquuiirree-CCaappaabbiilliittyy: osgi.extender;filter:="(&(osgi.extender=osgi.component) (version>=1.2.0)(!(version>=2.0.0)))", osgi.whiteboard;filter:="(osgi.whiteboard=osgi.http)" Note that the javax.servlet import should really use contracts! 8 of 41
  • 9.
    Finished app... 2 Bundles devicemon.jar dependson DS and HTTP Service devicemon-ssh.jar depends on Apache Mina SSHD 9 of 41
  • 10.
    Deploy it... Now Iwant to easily deploy my app ⟱ create a Subsystem of it! 10 of 41
  • 11.
    Subsystems OSGi Enterprise spec134 A subsystem... collection of bundles put together feature - everything shared application - isolated, nothing shared out composite - configurable in-between a zip file with .esa extension can be nested can depend on bundles or other subsystems Subsystems can use OSGi Repositories to resolve dependencies 11 of 41
  • 12.
    devicemon-ds.esa Just a zipfile... $ tar tvf devicemon-ds.esa -rwxrwxrwx 99 8 JJaann 15:40 OSGI-INF/SUBSYSTEM.MF -rwxrwxrwx 18184 8 JJaann 16:01 devicemon-ds.jar -rwxrwxrwx 5968 8 JJaann 16:02 devicemon-ssh.jar Subsystem Manifest $ cat OSGI-INF/SUBSYSTEM.MF SSuubbssyysstteemm-SSyymmbboolliiccNNaammee: devicemon-ds SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1 SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature note, I didn't put my dependencies in the .esa file 12 of 41
  • 13.
    Feature subsystems devicemon-ds.esa: aFeature Subsystem All the bundles inside work just as shared bundles in OSGi Subsystem installed/started/stopped as 1 unit Dependencies pulled in either from .esa or from repository as needed are reference-counted 13 of 41
  • 14.
    Apache Felix +Apache Aries Subsystems 14 of 41
  • 15.
  • 16.
    3 bundles in1 operation 16 of 41
  • 17.
    Our subsystem doesn'tinstall! NB: a failed subsystem install doesn't leave any bundles behind... 17 of 41
  • 18.
    OSGi Repository OSGi Enterprisespec 132 Inspired by Felix OBR Simple but powerful Actual repo can be remote or local Find resources based on their capabilities any resource any capability OSGi has defined: standard Bundle capabilities Bundle, Subsystem resource types some more general capabilities 18 of 41
  • 19.
    Add resources usingstandard XML Example <<rreeppoossiittoorryy increment='1389281419631' name='MyRepo' xmlns='http://www.osgi.org/xmlns/repository/v1.0.0'>> <<rreessoouurrccee>> <<ccaappaabbiilliittyy namespace='osgi.identity'>> <<aattttrriibbuuttee name='osgi.identity' value='org.apache.sshd.core'//>> <<aattttrriibbuuttee name='type' value='osgi.bundle'//>> <<aattttrriibbuuttee name='version' type='Version' value='0.9.0'//>> <<//ccaappaabbiilliittyy>> <<ccaappaabbiilliittyy namespace='osgi.content'>> <<aattttrriibbuuttee name='osgi.content' value='a1c64578808c38a63cd6563e9936f025638aeaf9de70f36765367db81c0afc38' <<aattttrriibbuuttee name='url' value='local-repo/sshd-core.jar'//>> <<aattttrriibbuuttee name='size' type='Long' value='464733'//>> <<aattttrriibbuuttee name='mime' value='application/vnd.osgi.bundle'//>> <<//ccaappaabbiilliittyy>> <<ccaappaabbiilliittyy namespace='osgi.wiring.package'>> <<aattttrriibbuuttee name='osgi.wiring.package' value='org.apache.sshd'//>> <<aattttrriibbuuttee name='version' type='Version' value='0.5.0'//>> <<aattttrriibbuuttee name='bundle-symbolic-name' value='org.apache.sshd.core'//>> <<aattttrriibbuuttee name='bundle-version' type='Version' value='0.9.0'//>> <<ddiirreeccttiivvee name='uses' value='org.apache.sshd.client'//>> <<//ccaappaabbiilliittyy>> <!-- More capabilities --> <<rreeqquuiirreemmeenntt namespace='osgi.wiring.package'>> <<ddiirreeccttiivvee name='filter' value='(&(osgi.wiring.package=org.slf4j)(version>=1.6.0)(!(version>=2.0.0)))'/> <<//rreeqquuiirreemmeenntt>> <!-- More requirements --> <<//rreessoouurrccee>> <!-- More resources --> <<//rreeppoossiittoorryy>> 19 of 41
  • 20.
    Repository XML Format definedby OSGi Repository Spec Standard way to feed a repository with information Standard way for repositories to exchange data Generate it with the bindex/RepoIndex tool: https://github.com/osgi/bindex (https://github.com/osgi/bindex) 20 of 41
  • 21.
    Repository Service Obtain resourcesfrom the repository Find a bundle... RReeppoossiittoorryy repo = ... // from Service Registry ... RReeqquuiirreemmeennttBBuuiillddeerr rb = nneeww RReeqquuiirreemmeennttBBuuiillddeerr("osgi.wiring.package"); rb.addDirective("filter", "(&(osgi.wiring.package=org.apache.ssh)(version=0.5.0))"); RReeqquuiirreemmeenntt req = rb.build(); CCoolllleeccttiioonn<RReessoouurrccee> bundleResources = repo.findProviders(req); ... or find some photo's from the North Pole ... RReeqquuiirreemmeennttBBuuiillddeerr rb = nneeww RReeqquuiirreemmeennttBBuuiillddeerr("com.acme.photo"); rb.addDirective("filter", "(latitude>=66.5622)"); RReeqquuiirreemmeenntt req = rb.build(); CCoolllleeccttiioonn<RReessoouurrccee> photoResources = repo.findProviders(req); 21 of 41
  • 22.
    Add and primea Repository 22 of 41
  • 23.
  • 24.
    Descriptor Subsystems A subsystemcan be just a descriptor ... with all resources obtained from a Repository $ jar tvf generated/devicemon-ds-decl.esa 0 TThhuu JJaann 09 12:37:32 GMT 2014 OSGI-INF/ 175 WWeedd JJaann 08 15:50:28 GMT 2014 OSGI-INF/SUBSYSTEM.MF Subsystem Manifest $ cat OSGI-INF/SUBSYSTEM.MF SSuubbssyysstteemm-SSyymmbboolliiccNNaammee: devicemon-ds-decl SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1 SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature SSuubbssyysstteemm-CCoonntteenntt: devicemon-ds;version=0.0.1, devicemon-ssh;version=0.0.1 24 of 41
  • 25.
    Start with only Subsystems+ Repository 25 of 41
  • 26.
    Dependencies at work http.esapulled in automatically 26 of 41
  • 27.
    Unpredictable dependency both 0.9.0and 0.9.1 satisfy requirement 27 of 41
  • 28.
    Subsystem Deployment Descriptor OnceQA-ed, create a DEPLOYMENT.MF to fix dependencies $ jar tvf generated/devicemon-ds-decl-dd.esa 283 WWeedd JJaann 15 16:39:34 GMT 2014 OSGI-INF/DEPLOYMENT.MF 175 WWeedd JJaann 08 15:50:28 GMT 2014 OSGI-INF/SUBSYSTEM.MF it can freeze deployments $ cat OSGI-INF/DEPLOYMENT.MF SSuubbssyysstteemm-VVeerrssiioonn: 0.0.1 SSuubbssyysstteemm-TTyyppee: osgi.subsystem.feature DDeeppllooyyeedd-CCoonntteenntt: devicemon-ds;deployed-version=0.0.1, devicemon-ssh;deployed-version=0.0.1 PPrroovviissiioonn-RReessoouurrccee: org.apache.sshd.core;deployed-version=0.9.1, org.apache.felix.scr;deployed-version=1.8.2, http-subsystem;type=osgi.subsystem.feature;deployed-version=1.2.0 note version 0.9.1 for org.apache.sshd.core Ensures that the runtime deployment is the same as the QA one. 28 of 41
  • 29.
    SSHD dependency nowas predicted 29 of 41
  • 30.
    Portable Contracts Our bundlecontains: IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)", This API is defined by the JCP. but... spot the problem! 30 of 41
  • 31.
    Semantic Versioning ... versioningpolicy for exported packages. OSGi versions: <major>.<minor>.<micro>.<qualifier> Updating package versions: fix/patch (no change to API): update micro extend API (affects implementers, not clients): update minor API breakage: update major Using semantic versioning allows creating components that can work with future patches and other compatible releases of deps just Import-Package a range like: [5.3, 6) 31 of 41
  • 32.
    javax.servlet Problem IImmppoorrtt-PPaacckkaaggee: javax.servlet;version="[2.5,3)", Servlet3.0 is actually compatible with 2.5 JCP specs don't follow semantic versioning 3.0 is more of a marketing version But what version to use for javax.servlet in OSGi? Different providers made different decisions Some use 2.6 to export javax.servlet from Servlet 3 spec Others use 3.0 Some even use 0.0.0 This prohibits creating portable bundles using these APIs 32 of 41
  • 33.
    Portable Java Contracts osgi.contractcapability to the rescue client bundle requires capability with single 'marketing' or 'spec' version and also imports the package without version osgi.contract provider binds the contract version to package versions IImmppoorrtt-PPaacckkaaggee: javax.servlet, javax.servlet.http RReeqquuiirree-CCaappaabbiilliittyy: osgi.contract; filter:="(&(osgi.contract=JavaServlet)(version=2.5))" Enables creating portable bundles importing non-semantically versioned packages. 33 of 41
  • 34.
    Our bundle manifestshould really be BBuunnddllee-MMaanniiffeessttVVeerrssiioonn: 2 BBuunnddllee-SSyymmbboolliiccNNaammee: devicemon-ds BBuunnddllee-VVeerrssiioonn: 0.0.1 IImmppoorrtt-PPaacckkaaggee: javax.servlet, org.coderthoughts.devicemon.ssh;version="[1.0,2)", org.osgi.service.http;version="[1.2,2)" RReeqquuiirree-CCaappaabbiilliittyy: osgi.extender;filter:="(&(osgi.extender=osgi.component) (version>=1.2)(!(version>=2.0)))", osgi.whiteboard;filter:="(osgi.whiteboard=osgi.http) (version>=1.0)(!(version>=2.0)))", osgi.contract;filter:="(&(osgi.contract=JavaServlet) (version=2.5))" 34 of 41
  • 35.
    Providing Portable Contracts Thebundle exporting the package should do this: EExxppoorrtt-PPaacckkaaggee: javax.servlet;version=2.6, javax.servlet.http;version=2.6 PPrroovviiddee-CCaappaabbiilliittyy: osgi.contract; osgi.contract=JJaavvaaSSeerrvvlleett;version:VVeerrssiioonn=2.5; uses:="javax.servlet, javax.servlet.http", osgi.contract;osgi.contract=JJaavvaaSSeerrvvlleett;version:VVeerrssiioonn=3; uses:="javax.servlet, javax.servlet.http" as it only knows how the mapping is done. Each marketing version is mapped to a package version. For more details, see OSGi RFC 180 (https://github.com/osgi/design/raw/master /rfcs/rfc0180/rfc-0180-portable- java-contracts.pdf). 35 of 41
  • 36.
    For all packagesother than JCP-ones 36 of 41
  • 37.
    http://www.bndtools.org (http://www.bndtools.org) can help withversion maintenance! reallybndtools Use Semantic Versioning! 37 of 41
  • 38.
    Where can Iget it? Core R6 spec released this week: http://www.osgi.org/Specifications/HomePage (http://www.osgi.org/Specifications/HomePage) Enterprise R6 draft released this week: http://www.osgi.org/Specifications/Drafts (http://www.osgi.org/Specifications/Drafts) RFCs 189, 190, 208 included in zip 38 of 41
  • 39.
    Links OSGi specs: http://www.osgi.org/Specifications (http://www.osgi.org/Specifications) Apache FelixProject: http://felix.apache.org (http://felix.apache.org) OSGi RFC 180 https://github.com/osgi/design/raw/master /rfcs/rfc0180/rfc-0180-portable-java-contracts.pdf (https://github.com/osgi/design/raw/master /rfcs/rfc0180/rfc-0180-portable-java-contracts.pdf) devicemon project: https://github.com/bosschaert/devicemon (https://github.com/bosschaert/devicemon) Subsystem Gogo command https://github.com/bosschaert/coderthoughts39 of 41
  • 40.
  • 41.