Carsten Ziegeler David Bosschaert
What's cool in the new and updated
OSGi Specs
1 of 53
OSGi Specs Carsten Ziegeler David Bosschaert 1 of 53 Speakers - - PDF document
What's cool in the new and updated OSGi Specs Carsten Ziegeler David Bosschaert 1 of 53 Speakers Carsten Ziegeler (cziegeler@apache.org) RnD Adobe Research Switzerland OSGi Board, CPEG and EEG Member ASF member David Bosschaert
Carsten Ziegeler David Bosschaert
What's cool in the new and updated
1 of 53
Speakers
Carsten Ziegeler (cziegeler@apache.org) ⦿ RnD Adobe Research Switzerland ⦿ OSGi Board, CPEG and EEG Member ⦿ ASF member David Bosschaert (davidb@apache.org) ⦿ RnD Adobe Research Dublin ⦿ Co-chair OSGi EEG ⦿ Open-source and cloud enthusiast
2 of 53
Agenda
⦿ Framework updates ⦿ Repository update ⦿ Asynchronous Services & Promises ⦿ Declarative Services ⦿ Http Service ⦿ Cloud ⦿ Semantic Versioning Annotations ⦿ Other spec updates
3 of 53
OSGi Core R6 Release
⦿ Service Scopes ⦿ Package and Type Annotations ⦿ Data Transfer Objects ⦿ Native Namespace ⦿ WeavingHook Enhancements ⦿ System Bundle Framework Hooks ⦿ Extension Bundle Activators ⦿ Framework Wiring
4 of 53
Framework Updates Service Scopes (RFC 195)
OSGi R5 supports two service scopes: ⦿ Singleton ⦿ Bundle (ServiceFactory) Transparent to the client
S getService(S Se er rv vi ic ce eR Re ef fe er re en nc ce e<S> r re ef f) v vo
id d ungetService(S Se er rv vi ic ce eR Re ef fe er re en nc ce e<S> r re ef f)
5 of 53
Framework Updates Service Scopes (RFC 195)
⦿ Third Scope: prototype ⦿ Driver: Support for EEG specs (EJB, CDI) ⦿ Usage in other spec updates Clients need to use new API / mechanisms
6 of 53
Framework Updates Service Scopes (RFC 195)
New BundleContext Methods API
S getServiceObjects(S Se er rv vi ic ce eR Re ef fe er re en nc ce e<S> r re ef f).getService() v vo
id d getServiceObjects(S Se er rv vi ic ce eR Re ef fe er re en nc ce e<S> r re ef f).ungetService(S)
Transparent to the client
7 of 53
Framework Updates Service Scopes (RFC 195)
⦿ New PrototypeServiceFactory interface ⦿ Managed service registration properties for inspection ⦿ Support in component frameworks (DS, Blueprint)
8 of 53
9 of 53
RFC 185 – Data Transfer Objects
⦿ Defines a DTO model for OSGi
⦿ Serializable/Deserializable objects
⦿ Use cases: REST, JMX, Web Console... ⦿ To be adopted by other specs
10 of 53
RFC 185 – Data Transfer Objects
Getting DTOs: adapter pattern
p pu ub bl li ic c c cl la as ss s B Bu un nd dl le eD DT TO O e ex xt te en nd ds s org.osgi.dto.DTO { p pu ub bl li ic c l lo
ng g id; p pu ub bl li ic c l lo
ng g lastModified; p pu ub bl li ic c i in nt t state; p pu ub bl li ic c S St tr ri in ng g symbolicName; p pu ub bl li ic c S St tr ri in ng g version; }
11 of 53
RFC 185 – Data Transfer Objects
DTOs for the OSGi framework ⦿ FrameworkDTO ⦿ BundleDTO ⦿ ServiceReferenceDTO ⦿ BundleStartLevelDTO, FrameworkStartLevelDT ⦿ CapabilityDTO, RequirementDTO, ResourceDTO ⦿ BundleWiringsDTO, etc
12 of 53
13 of 53
OSGi Repository today
14 of 53
Example Repository namespaces
15 of 53
RFC 187 - Repository 1.1
Existing repository powerful but: limited to queries in a single namespace New in RFC 187:
Combine requirements spanning multiple namespaces:
R Re ep po
si it to
ry y repo = ... // Obtain from Service Registry C Co
ll le ec ct ti io
n<R Re es so
ur rc ce e> res = repo.findProviders( repo.getExpressionCombiner().a an nd d( repo.newRequirementBuilder("osgi.wiring.package"). addDirective("filter","(osgi.wiring.package=foo.pkg1)"). buildExpression(), repo.newRequirementBuilder("osgi.identity"). addDirective("filter", "(license=http://opensource.org/licenses/Apache-2.0)"). buildExpression()));
16 of 53
17 of 53
Async Services
existing service new ones, written for async access
result can be obtained later
18 of 53
Async Services - example
A typical service:
p pu ub bl li ic c i in nt te er rf fa ac ce e C Ca al lc cS Se er rv vi ic ce e { B Bi ig gI In nt te eg ge er r factorial(i in nt t num); }
Invoke it asynchronously:
C Ca al lc cS Se er rv vi ic ce e mySvc = ... // from service registry A As sy yn nc c asyncService = ... // from service registry C Ca al lc cS Se er rv vi ic ce e myMediator = asyncService.mediate(mySvc); f fi in na al l P Pr ro
mi is se e<B Bi ig gI In nt te eg ge er r> p = asyncService.call( myMediator.factorial(1000000)); // ... factorial invoked asynchronously ... // callback to handle the result when it arrives p.onResolve(n ne ew w R Ru un nn na ab bl le e() { p pu ub bl li ic c v vo
id d run() { S Sy ys st te em m.o
ut t.println("Found the answer: " + p.getValue()); } });
19 of 53
OSGi Promises
Make latency and errors explicit
Based on callbacks
CompletableFuture and Lambdas
Also useful elsewhere
20 of 53
OSGi Promises - example
S Su uc cc ce es ss s<S St tr ri in ng g,S St tr ri in ng g> transformResult = n ne ew w S Su uc cc ce es ss s<>() { p pu ub bl li ic c P Pr ro
mi is se e<S St tr ri in ng g> call(P Pr ro
mi is se e<S St tr ri in ng g> p) { r re et tu ur rn n P Pr ro
mi is se es s.resolved(toHTML(p.getValue())); } }; P Pr ro
mi is se e<S St tr ri in ng g> p = asyncRemoteMethod(); p.t th he en n(validateResult) .t th he en n(transformResult) .t th he en n(showResult, showError);
21 of 53
22 of 53
RFC 190 - Declarative Services Enhancements
⦿ Support of prototype scope ⦿ Introspection API ⦿ DTOs ⦿ But most importantly...
23 of 53
Simplify Component Dvlpmnt
@Component(p pr ro
pe er rt ty y={ M My yC Co
mp po
ne en nt t.PROP_ENABLED + ":Boolean=" + M My yC Co
mp po
ne en nt t.DEFAULT_ENABLED M My yC Co
mp po
ne en nt t.PROP_TOPIC + "=" + M My yC Co
mp po
ne en nt t.DEFAULT_TOPIC_1, M My yC Co
mp po
ne en nt t.PROP_TOPIC + "=" + M My yC Co
mp po
ne en nt t.DEFAULT_TOPIC_2, "service.ranking:Integer=15" }) p pu ub bl li ic c c cl la as ss s M My yC Co
mp po
ne en nt t { s st ta at ti ic c f fi in na al l S St tr ri in ng g PROP_ENABLED = "enabled"; s st ta at ti ic c f fi in na al l S St tr ri in ng g PROP_TOPIC = "topic"; s st ta at ti ic c f fi in na al l S St tr ri in ng g PROP_USERNAME = "userName"; s st ta at ti ic c f fi in na al l b bo
le ea an n DEFAULT_ENABLED = t tr ru ue e; s st ta at ti ic c f fi in na al l S St tr ri in ng g DEFAULT_TOPIC_1 = "topicA"; s st ta at ti ic c f fi in na al l S St tr ri in ng g DEFAULT_TOPIC_2 = "topicB";
24 of 53
Simplify Component Dvlpmnt
@Activate p pr ro
te ec ct te ed d v vo
id d activate(f fi in na al l M Ma ap p config) { f fi in na al l b bo
le ea an n enabled = P Pr ro
pe er rt ti ie es sU Ut ti il l.toBoolean(config.g ge et t(PROP_ENABLED), DEFAULT_ENABLED); i if f ( enabled ) { t th hi is s.userName = P Pr ro
pe er rt ti ie es sU Ut ti il l.toString(config.g ge et t(PROP_USERNAME), n nu ul ll l t th hi is s.topics = P Pr ro
pe er rt ti ie es sU Ut ti il l.toStringArray(config.g ge et t(PROP_TOPIC), n ne ew w S St tr ri in ng g[] {DEFAULT_TOPIC_1, DEFAULT_TOPIC_2}); } }
25 of 53
Use annotations for configuration...
@interface M My yC Co
nf fi ig g { b bo
le ea an n enabled() d de ef fa au ul lt t t tr ru ue e; S St tr ri in ng g[] topic() d de ef fa au ul lt t {"topicA", "topicB"}; S St tr ri in ng g userName(); i in nt t service_ranking() d de ef fa au ul lt t 15; }
26 of 53
...and reference them in lifecycle methods
@Component p pu ub bl li ic c c cl la as ss s M My yC Co
mp po
ne en nt t { S St tr ri in ng g userName; S St tr ri in ng g[] topics; @Activate p pr ro
te ec ct te ed d v vo
id d activate(f fi in na al l M My yC Co
nf fi ig g config) { // note: annotation MyConfig used as interface i if f ( config.enabled() ) { t th hi is s.userName = config.userName(); t th hi is s.topics = config.topic(); } } }
27 of 53
...or even simpler...
@Component p pu ub bl li ic c c cl la as ss s M My yC Co
mp po
ne en nt t { p pr ri iv va at te e M My yC Co
nf fi ig g configuration; @Activate p pr ro
te ec ct te ed d v vo
id d activate(f fi in na al l M My yC Co
nf fi ig g config) { // note: annotation MyConfig used as interface i if f ( config.enabled() ) { t th hi is s.configuration = config; } } }
28 of 53
Annotation Mapping
⦿ Fields registered as component properties ⦿ Name mapping (_ -> .) ⦿ Type conversion for configurations
29 of 53
Additional Metatype Support (RFC 208)
@ObjectClassDefinition(label="My Component", description="Coolest component in the world.") @interface M My yC Co
nf fi ig g { @AttributeDefinition(label="Enabled", description="Topic and user name are used if enabled") b bo
le ea an n enabled() d de ef fa au ul lt t t tr ru ue e; @AttributeDefinition(...) S St tr ri in ng g[] topic() d de ef fa au ul lt t {"topicA", "topicB"}; @AttributeDefinition(...) S St tr ri in ng g userName(); i in nt t service_ranking() d de ef fa au ul lt t 15; // maps to service.ranking }
30 of 53
RFC 190 - Declarative Services Enhancements
⦿ Annotation configuration support ⦿ Support of prototype scope ⦿ Introspection API ⦿ DTOs
31 of 53
32 of 53
Http Whiteboard Service RFC 189
⦿ Whiteboard support ⦿ Servlet API 3+ Support ⦿ and Introspection API
33 of 53
Whiteboard Servlet Registration
@Component(service = javax.servlet.S Se er rv vl le et t.c cl la as ss s, scope="PROTOTYPE", p pr ro
pe er rt ty y={ "osgi.http.whiteboard.servlet.pattern=/products/*", }) p pu ub bl li ic c c cl la as ss s M My yS Se er rv vl le et t e ex xt te en nd ds s H Ht tt tp pS Se er rv vl le et t { ... }
34 of 53
Whiteboard Servlet Filter Registration
@Component(service = javax.servlet.F Fi il lt te er r.c cl la as ss s, scope="PROTOTYPE", p pr ro
pe er rt ty y={ "osgi.http.whiteboard.filter.pattern=/products/*", }) p pu ub bl li ic c c cl la as ss s M My yF Fi il lt te er r i im mp pl le em me en nt ts s F Fi il lt te er r { ... }
35 of 53
Additional Support
⦿ Most listener types are supported Register with their interface ⦿ Error Pages and Resources ⦿ Shared and segregated HttpContexts ⦿ Target Http Service
36 of 53
37 of 53
Current PaaS offerings...
38 of 53
OSGi Cloud Ecosystems PaaS
39 of 53
An OSGi cloud ecosystem...
⦿ Many frameworks
○ hosting a variety of deployments
⦿ Together providing The Application ⦿ Not a bunch of replicas
○ rather a collection of different nodes ○ with different roles working together ○ some may be replicas
⦿ Load varies over time ⦿ ... and so does your cloud system
○ topology ○ configuration ○ number of nodes ○ depending on the demand
40 of 53
To realize this you need...
⦿ Information!
○ need to know what nodes are available ○ ability to react to changes
⦿ Provisioning capability ⦿ Remote invocation
○ inside your cloud system ○ to get nodes to communicate ○ either directly... ○ ... or as a means to set up communication channels
41 of 53
RFC 183 - Cloud Ecosystems
F Fr ra am me ew wo
rk kN No
de eS St ta at tu us s service:
information about each Cloud node accessible as a Remote Service throughout the ecosystem
Information such as:
Hostname/IP address Location (country etc) OSGi and Java version running A REST management URL Runtime metadata
Available memory / disk space Load measurement
... you can add custom metadata too ...
42 of 53
FrameworkNodeStatus service properties
43 of 53
RFC 182 - REST API
A cloud-friendly remote management API works great with FrameworkNodeStatus Example:
addingService(S Se er rv vi ic ce eR Re ef fe er re en nc ce e<F Fr ra am me ew wo
rk kN No
de eS St ta at tu us s> r re ef f) { // A new Node became available S St tr ri in ng g url = r re ef f.getProperty("org.osgi.node.rest.url"); R Re es st tC Cl li ie en nt t rc = n ne ew w R Re es st tC Cl li ie en nt t(n ne ew w URI(url)); // Provision the new node rc.installBundle(...); rc.startBundle(...); }
44 of 53
Additional ideas in RFC 183
⦿ Special Remote Services config type
・ osgi.configtype.ecosystem ・ defines supported Remote Service data types ・ not visible outside of cloud system
⦿ Ability to intercept remote service calls
・ can provide different service for each client ・ can do invocation counting (quotas, billing)
⦿ Providing remote services meta-data
・ quota exceeded ・ payment needed ・ maintenance scheduled
45 of 53
Current OSGi cloud work
Provides a base line ○ to build fluid cloud systems ○ portability across clouds Where everything is dynamic ○ nodes can be repurposed ... and you deal with your cloud nodes through OSGi services
46 of 53
47 of 53
Semantic Versioning...
... is a versioning policy for exported packages. OSGi versions: <major>.<minor>.<micro>.<qualifier> Updating package versions:
update micro
update minor
update major Note: not always used for bundle versions
48 of 53
RFC 197 – OSGi Type and Package Annotations
⦿ Annotations for documenting semantic versioning information
⦿ Class retention annotations
⦿ @Version ⦿ @ProviderType ⦿ @ConsumerType
49 of 53
50 of 53
▻ Remote Service Admin 1.1
・ Remote Service registration modification
▻ Subsystems 1.1
・ Provide Deployment Manifest separately ・ Many small enhancements
▻ Portable Java SE/EE Contracts
51 of 53
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 All current RFCs at https://github.com/osgi/design (https://github.com/osgi/design)
52 of 53
53 of 53