Cook Up a Runtime with The New OSGi Resolver - Neil Bartlett
-
Upload
mfrancis -
Category
Technology
-
view
465 -
download
2
Transcript of Cook Up a Runtime with The New OSGi Resolver - Neil Bartlett
Copyright © 2005 - 2013 Paremus Ltd.May not be reproduced by any means without express permission. All rights reserved.
Paremus Packager March 2013
Cook Up a Runtime with the OSGi ResolverNeil Bartlett - Paremus
Friday, 29 March 13
NO YOU CAN’T
• Example: missing import: org.wtf.
• Google for org.wtf, find that it’s part of bundle com.acme.fml
• Download and install com.acme.fml, now you have more missing imports: org.thingummy, javax.whatever (version 3.0.2.SNAPSHOT).
• Go round again... and again... and again...
Friday, 29 March 13
Nothing’s Happening
• Oh you’re using Declarative Services! Did you remember to include org.apache.felix.scr?
• Oh you’re using Blueprint. Did you remember to include org.apache.aries.blueprint?
• Oh you’re using JPA. Did you remember to include org.eclipse.gemini.jpa?
Friday, 29 March 13
Extender/Whiteboard
• NO direct/static dependency
• Dependency is implicit: without the extender, nothing happens.
• NO diagnostic error messages
Friday, 29 March 13
Not Really Solutions
• Deployment Admin Packages
• Eclipse Features
• Virgo Plans/PARs
• Karaf KARs/Features
• etc...
Friday, 29 March 13
OSGi Release 5
• Released April 2012
• New Specification: Resolver and Repository
Friday, 29 March 13
Simple API!
public interface Repository { Map<Requirement, Collection<Capability>> findProviders( Collection<? extends Requirement> requirements);}
Friday, 29 March 13
Repository
• Can return Resources from anywhere
• Should have knowledge of capabilities and requirements of the resources it manages
• Database? XML file? Just an implementation detail.
Friday, 29 March 13
XML Index Format<repository name='Local' xmlns='http://www.osgi.org/xmlns/repository/v1.0.0'> <resource> <capability namespace='osgi.identity'> <attribute name='osgi.identity' value='org.apache.felix.gogo.runtime'/> <attribute name='type' value='osgi.bundle'/> <attribute name='version' type='Version' value='0.10.0'/> </capability> <capability namespace='osgi.content'> <attribute name='osgi.content' value='15e94961ae2d0046278686965fe6a34ad43d8d18719f5bc2304e725cdb57a379'/> <attribute name='url' value='org.apache.felix.gogo.runtime/org.apache.felix.gogo.runtime-0.10.0.jar'/> <attribute name='size' type='Long' value='66965'/> <attribute name='mime' value='application/vnd.osgi.bundle'/> </capability> <capability namespace='osgi.wiring.package'> <attribute name='osgi.wiring.package' value='org.apache.felix.service.command'/> <attribute name='version' type='Version' value='0.10.0'/> <attribute name='status' value='provisional'/> <attribute name='bundle-symbolic-name' value='org.apache.felix.gogo.runtime'/> <attribute name='bundle-version' type='Version' value='0.10.0'/> <directive name='mandatory' value='status'/> </capability> ...
Friday, 29 March 13
Generating an Index
• RepoIndex: https://github.com/osgi/bindex
• Standalone library, also command line, ANT, OSGi service, etc.
Friday, 29 March 13
Repository Implementations
• RI from Red Hat: github.com/jbosgi/jbosgi-repository
• bnd “Fixed Indexed Repo”
• Just needs a URI to an index
• bnd “Local Indexed Repo”
• Mutable, based on local file-system folder
• Automatically reindexes on deploy
Friday, 29 March 13
Simple API!
public interface Resolver { Map<Resource, List<Wire>> resolve(ResolveContext context) throws ResolutionException;}
Friday, 29 March 13
Resolver Result
• Returns a Delta: new Resources, new Wires
• Can be used by OSGi Framework
• Use outside OSGi to discover resources
Friday, 29 March 13
DO NOT IMPLEMENT
• Implementing a Resolver is HARD
• Resolver is very generic. You almost certainly don’t NEED to implement your own
Friday, 29 March 13
Resolver Implementation
• Just One: The RI from Apache Felix
• Used in Felix Framework
• Soon to be used in Equinox Framework
• Used by Subsystems Specification
• Used by Bnd(tools)
• Soon to be used in Paremus Nimble
Friday, 29 March 13
Resolver is Clueless!
• Resolver just finds a solution to a puzzle
• The inputs to the puzzle depend on us: the Resolve Context
Friday, 29 March 13
Resolve Context
• Implemented by Resolver clients. I.e., us!
• Guides the resolver.
Friday, 29 March 13
Not So Simple API!public abstract class ResolveContext {
public Collection<Resource> getMandatoryResources() { return emptyCollection(); }
public Collection<Resource> getOptionalResources() { return emptyCollection(); }
public abstract Map<Resource, Wiring> getWirings();
public abstract List<Capability> findProviders(Requirement requirement);
public abstract boolean isEffective(Requirement requirement);
public abstract int insertHostedCapability(List<Capability> capabilities, HostedCapability hostedCapability);
}
Friday, 29 March 13
getMandatoryResources()
• This is our starting point
• List of resources that must be present in the result
• Bndtools creates a single dummy Resource containing the input Requirements
Friday, 29 March 13
getOptionalResources()
• List of resources we hope will be present in the result
• Failure to resolve one of these doesn’t break the whole resolution
Friday, 29 March 13
getWirings()
• Map of existing resolved resources and their wires
• Inside OSGi, this is the already resolved bundles
• In Bndtools this is empty
Friday, 29 March 13
findProviders()
• Here’s the meat!
• The Resolver wants to resolve a requirement...
• ... asks us to find the candidate Capabilities to satisfy it
• We return a ranked collection of Capabilities
• Typically we talk to our Repositories
• Resolver tries to use the highest ranked candidate, but no promises.
Friday, 29 March 13
GOTCHA
• Don’t go to Repositories for JRE packages etc.
• Always check system bundle capabilities first.
• Some Resources have “self-requirements”, e.g. importing package exported by same bundle.
• Always check first if the resource’s own capabilities satisfy the requirement
Friday, 29 March 13
insertHostedCapability()
• Oh Mummy...
• Insert fragment capabilities into the list returned by findProviders(), at the correct position
• More proof that fragments are horrible.
Friday, 29 March 13
Implementations
• Felix and Equinox Frameworks
• BndrunResolveContext in bnd project takes a .bndrun file as input
Friday, 29 March 13
Effective
• Some requirements are “effective” at different times
• E.g.: Require-Capability: osgi.service;filter:=...
• Should Not block resolution by the OSGi Framework
• Should guide OBR/Nimble/Bndtools to add a provider to the result
Friday, 29 March 13
Effective
Require-Capability: osgi.service; \ filter:="(objectClass=org.example.exchange.api.Exchange)"; \ effective:=active
Friday, 29 March 13
Effective
• Requirements are only effective in OSGi Framework resolution if effective == “resolve”
• ... but “resolve” is the default, so omitting the “effective:” directive also works.
• Other Resolve Contexts (e.g. Bndtools) can decide by implementing isEffective(Requirement).
Friday, 29 March 13
effective:=active
• No value for “effective:” is defined by OSGi other than “resolve”
• “active” is a convention for requirements that apply to active bundles.
• E.g.: extenders, whiteboard, services, etc
Friday, 29 March 13
Choice
• Your app requires a Web container, e.g. osgi.extender;filter:=“(osgi.extender=osgi.wab)”
• Tomcat and Jetty are both available.
• It only makes sense to have one! How do we decide?
Friday, 29 March 13
Choice
• It’s all down to ResolveContext.findProviders()
• Ranked preference, Resolver tries to pick highest.
• Or we return just one.
Friday, 29 March 13
Current State-of-the-Art
• “Repository Path”
• Resources from earlier repos are preferred over later repos.
• Forces us to have many, granular repos.
• Probably won’t scale.
Friday, 29 March 13
Future?
• Interactive Resolve.
• Ask the user, but cache the answer (...for how long?)
• Policies
• “Prefer Jetty over Tomcat”
• Repository Filters
Friday, 29 March 13
What is an Application??
• A small number of bundles defining the high-level functionality.
• All of the dependencies of the above.
• Curate your top-level bundles.
• Generate your dependency lists.
Friday, 29 March 13
Caution
• When should we resolve?
• The result can change if repo contents change!
• Resolve => Test => Resolve => Deploy to Prod... bang!
• WYTIWYR
• Persist your resolution result.
Friday, 29 March 13