Cook Up a Runtime with The New OSGi Resolver - Neil Bartlett

Post on 15-Apr-2017

465 views 2 download

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

neil.bartlett@paremus.com

Friday, 29 March 13

Problem Statement (1)

Friday, 29 March 13

OSGi“The Framework that Likes

to Say...”

Friday, 29 March 13

NO YOU CAN’T

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

THIS IS NOT A JOB FOR HUMAN BEANS

Friday, 29 March 13

Problem Statement (2)

Friday, 29 March 13

NOTHING’S HAPPENING!

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

Friday, 29 March 13

OSGi Release 5

• Released April 2012

• New Specification: Resolver and Repository

Friday, 29 March 13

Repositories

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

Resolver

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

So the Resolver talks to the Repository, right?

Friday, 29 March 13

WRONG

• Resolver has no knowledge of any Repository.

Friday, 29 March 13

At least it knows about current Bundles and Wires, right?

Friday, 29 March 13

WRONG

• Resolver has no knowledge of existing state.

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

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

isEffective()

• Decide whether to ignore 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

DEMO

Friday, 29 March 13

Requirement “Effectiveness”

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

Open Questions

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

Conclusion

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

Thank YouThank You

Friday, 29 March 13