osgi declarative services - eclipsecon europe 2019 · getting started with osgi declarative...
Post on 22-May-2020
3 Views
Preview:
TRANSCRIPT
OSGIDECLARATIVESERVICES
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.2
Getting Started with OSGi Declarative ServicesSpeaker
Dirk Fauth
Software-Architect Rich Client Systeme
Eclipse Committer
Robert Bosch GmbH
Franz-Oechsle-Straße 4
73207 Plochingen
dirk.fauth@de.bosch.com
www.bosch.com
blog.vogella.com/author/fipro/
Twitter: fipro78
OVERVIEW
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.4
Bundles register (publish) services
Bundles get (bind) services
Bundles listen (find) services
Publish-Find-Bind
A BSregister
(publish)
get
(bind)
listen
(find)
<<bundle>> <<bundle>><<service>>
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.5
(Service) Component
‒ Java class contained in a bundle
‒ Declared via Component Description
Component Description
‒ XML document to declare a Service Component
Component Configuration
‒ Component Description that is parameterized with component properties
‒ Tracks the component dependencies and manages the component instance
Component Instance
‒ Instance of the component implementation class
‒ Created when a Component Configuration is activated
‒ Discarded when the Component Configuration is deactivated
Components
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.6
References
References
‒ The definition of dependencies to other services.
Target Services
‒ The services that match the reference interface and target property filter.
Bound Services
‒ The services that are bound to a Component Configuration.
Access Strategies
‒ Event Strategy
‒ Lookup Strategy
‒ Field Strategy (1.3)
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.7
Component Types
Delayed Component
‒ Activated when the service is requested
‒ Needs to specify a service
Immediate Component
‒ Activated as soon as all dependencies are satisfied
‒ Does not need to specify a service
Factory Component
‒ Creates and activates Component Configurations
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.8
Component Lifecycle – Immediate
UNSATISFIED
activate ACTIVE
deactivateBundle
started
Bundle
stoppeddisable
loadenabled
becomes
satisfiedbecomes
unsatisfied
if dynamic:
rebinding
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.9
Component Lifecycle – Delayed
UNSATISFIED
activate ACTIVE
deactivateBundle
started
Bundle
stoppeddisable
loadenabled
becomes
satisfied
becomes
unsatisfied
if dynamic:
rebinding
REGISTERED
get service
becomes
unsatisfied
unget
service
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.10
Activation consists of the following steps:
1. Load the component implementation class
2. Create the component instance and component context
3. Bind the target services
4. Call the activate method if present
For Delayed Components the load time is moved to the first request
(including reference bindings)
(see Declarative Services Specification Version 1.3 – 112.5.6 Activation)
Component Lifecycle – Activation
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.11
Component Lifecycle – Factory
UNSATISFIED
activate
ACTIVE
deactivate
Bundle
started
Bundle
stoppeddisable
loadenabled
becomes
satisfied
becomes
unsatisfied
if dynamic:
rebinding
FACTORY
newInstance
becomes
unsatisfieddispose
register
unregister
TOOLING
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.13
Tooling
Eclipse Neon
‒ PDE - DS Annotations Support
‒ Contribution by Peter Nehrer (@pnehrer)
Eclipse <= Mars
‒ Declarative Services Annotations Support (Marketplace)
https://marketplace.eclipse.org/content/declarative-services-annotations-support
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.14
PDE – DS Annotations Support
IMPLEMENT & PUBLISH
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.16
Create a bundle for the service API (e.g. org.fipro.inverter.api)
Create the service interface
Service API
public interface StringInverter {
String invert(String input);
}
Make the service implementation exchangeable
Clean dependency hierarchy
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.17
Service API
ErrorHandler
ErrorHandlerImpl
<<consumer bundle>>
<<ErrorHandler Bundle>>
<<SWT>>
<<API>> <<Provider>>
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.18
MANIFEST
• Specify the OSGi meta-data in MANIFEST.MF directly
• Overview
• Bundle-SymbolicName
• Bundle-Version
• Runtime
• Export-Package
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.19
Create a bundle for the service implementation
(e.g. org.fipro.inverter.provider)
Create the service implementation
Service Provider
@Component
public class StringInverterImpl implements StringInverter {
@Override
public String invert(String input) {
return new StringBuilder(input).reverse().toString();
}
}
@Component
public class StringInverterImpl implements StringInverter {
@Override
public String invert(String input) {
return new StringBuilder(input).reverse().toString();
}
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.20
MANIFEST
• Specify the OSGi meta-data in MANIFEST.MF directly
• Dependencies
• Import org.fipro.inverter
• Import org.osgi.service.component.annotations (optional)
• Specify upper bounds for semantic versioning
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.21
Annotation to mark a Java class as a Service Component
DS Annotation Support triggers on save
‒ Generation/Modification of Component Description XML file
‒ Generation/Modification of Service-Component header in MANIFEST.MF
‒ Bundle-ActivationPolicy: lazy header in MANIFEST.MF (PDE)
‒ Adds Component Description XML file to build.properties (PDE)
‒ No capability headers!
@Component
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.22
Capability = non-code dependency
osgi.extender=osgi.component
‒ added to spec with DS 1.3
‒ Equinox DS adapted for DS 1.2 with Eclipse Neon
osgi.service
‒ specify the provided service implementations
Capabilities
Require-Capability: osgi.extender;
filter:="(&(osgi.extender=osgi.component)(version>=1.3)(!(version>=2.0)))"
Provide-Capability: osgi.service;
objectClass:List<String>="org.fipro.inverter.StringInverter"
The p2 resolver does not support OSGi capabilities!
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.23
@Component
Type Element Default Type Element Default
configurationPid full qualified class name of
the component
property empty
configurationPolicy optional service full qualified class names of all
directly implemented interfaces
enabled true servicefactory
(depr. in 1.3)
false
factory empty String xmlns lowest DS XML namespace that
supports used features
immediate false if factory or service
true otherwise
name full qualified class name of
the component
reference
(since 1.3)
empty
properties empty scope
(since 1.3)
SINGLETON
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.24
Component life cycle methods
Method parameters
‒ ComponentContext
‒ BundleContext
‒ Map<String, ?>
Map containing component properties
‒ int / Integer for (@Deactivate)
‒ <Component Property Type> (DS 1.3)
Type safe access to component properties
@Activate / @Modified / @Deactivate
@Activate
private void activate(
ComponentContext c,
BundleContext b,
Map<String, ?> properties) {
//do some initialization stuff
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.25
Create a bundle for the service consumer
(e.g. org.fipro.inverter.command)
Create the service consumer implementation
Service Consumer – OSGi level
@Component(property= {"osgi.command.scope:String=fipro",
"osgi.command.function:String=invert"},
service=StringInverterCommand.class
)
public class StringInverterCommand {
private StringInverter inverter;
@Reference
void bindStringInverter(StringInverter inverter) { this.inverter = inverter; }
public void invert(String input) { System.out.println(inverter.invert(input)); }
}
@Component(property= {"osgi.command.scope:String=fipro",
"osgi.command.function:String=invert"},
service=StringInverterCommand.class
)
public class StringInverterCommand {
private StringInverter inverter;
@Reference
void bindStringInverter(StringInverter inverter) { this.inverter = inverter; }
public void invert(String input) { System.out.println(inverter.invert(input)); }
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.26
Specify dependency on other services
Resolving references is required to satisfy a component
(if the reference is not optional)
Different strategies for accessing services
‒ Event Strategy
‒ Field Strategy (DS 1.3)
‒ Lookup Strategy
@Reference
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.27
@Reference
Event Strategy – using event methods for bind/updated/unbind
@Component(...)
public class StringInverterCommand {
private StringInverter inverter;
@Reference
void bindStringInverter(StringInverter inverter) { this.inverter = inverter; }
void updatedStringInverter(
StringInverter inverter, Map<String, ?> properties) { //do something }
void unbindStringInverter(StringInverter inverter) { this.inverter = null; }
public void invert(String input) { System.out.println(inverter.invert(input)); }
}
@Component(...)
public class StringInverterCommand {
private StringInverter inverter;
@Reference
void bindStringInverter(StringInverter inverter) { this.inverter = inverter; }
void updatedStringInverter(
StringInverter inverter, Map<String, ?> properties) { //do something }
void unbindStringInverter(StringInverter inverter) { this.inverter = null; }
public void invert(String input) { System.out.println(inverter.invert(input)); }
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.28
ServiceReference
<service type>
<service type> + Map<String, ?>
With DS 1.3
ComponentServiceObjects
Different variations of the parameter list
@Reference - Event Method Parameter
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.29
@Reference
Field Strategy (DS 1.3) – using instance fields
@Component(...)
public class StringInverterCommand {
@Reference
private StringInverter inverter;
public void invert(String input) {
System.out.println(inverter.invert(input));
}
}
@Component(...)
public class StringInverterCommand {
@Reference
private StringInverter inverter;
public void invert(String input) {
System.out.println(inverter.invert(input));
}
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.30
@Reference
Lookup Strategy (DS 1.2) – lookup everytime needed, do not store@Component(...)
public class StringInverterCommand {
private ComponentContext context;
private ServiceReference<StringInverter> reference;
@Activate
void activate(ComponentContext context) { this.context = context; }
@Reference
void setStringInverter(ServiceReference<StringInverter> reference) { this.reference = reference; }
public void invert(String input) {
StringInverter inverter =
(StringInverter) context.locateService("StringInverter", reference);
...
}
}
@Component(...)
public class StringInverterCommand {
private ComponentContext context;
private ServiceReference<StringInverter> reference;
@Activate
void activate(ComponentContext context) { this.context = context; }
@Reference
void setStringInverter(ServiceReference<StringInverter> reference) { this.reference = reference; }
public void invert(String input) {
StringInverter inverter =
(StringInverter) context.locateService("StringInverter", reference);
...
}
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.31
@Reference
Lookup Strategy (DS 1.3) – lookup everytime needed, do not store
@Component(...
reference=@Reference(name="inverter", service=StringInverter.class)
)
public class StringInverterCommand {
private ComponentContext context;
@Activate
void activate(ComponentContext context) { this.context = context; }
public void invert(String input) {
StringInverter inverter = (StringInverter) context.locateService("inverter");
...
}
}
@Component(...
reference=@Reference(name="inverter", service=StringInverter.class)
)
public class StringInverterCommand {
private ComponentContext context;
@Activate
void activate(ComponentContext context) { this.context = context; }
public void invert(String input) {
StringInverter inverter = (StringInverter) context.locateService("inverter");
...
}
}
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.32
@Reference
Type Element Default Type Element Default
cardinality • 1:1 for event methods
• 1:1 for non-collection
fields, 0..n for collections
unbind unbind<name>
unset<name>
remove<name>
name • bind event method name
without bind prefix
• name of the field
updated updated<name>
if such a method exists
policy STATIC
policyOption RELUCTANT bind
(since 1.3)
the name of the annotated
method or empty
service full qualified class name of
the referenced service
field
(since 1.3)
the name of the annotated field
or empty
target empty String fieldOption
(since 1.3)
REPLACE
scope
(since 1.3)
BUNDLE
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.33
RCP UI is not part of the OSGi layer no @Reference support!
Eclipse 4 @Inject
‒ Only one instance can get injected (highest ranked one)
‒ No re-injection if a higher ranked service becomes available
‒ No possibility to filter
e(fx)clipse @Service
Service Consumer – Eclipse RCP
@Inject
StringInverter inverter;
@Inject
@Service
StringInverter inverter;
@Inject
@Service
List<StringInverter> inverters;
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.34
Use OSGi API directly
(BundleContext, ServiceReference, ServiceTracker)
Service Consumer – Eclipse RCP
public class ServiceUtil {
public static <T> T getService(Class<T> clazz) {
Bundle bundle = FrameworkUtil.getBundle(ServiceUtil.class);
if (bundle != null) {
ServiceTracker<T,T> st =
new ServiceTracker<>(bundle.getBundleContext(), clazz, null);
st.open();
try {
return st.waitForService(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
Do not use an Activator!
OSGi Declarative Services
Automotive Service Solutions | AA-AS/EIS2-EU | 25.10.2016
© Robert Bosch GmbH 2016. Alle Rechte vorbehalten, auch bzgl. jeder Verfügung, Verwertung, Reproduktion, Bearbeitung, Weitergabe sowie für den Fall von Schutzrechtsanmeldungen.35
Further information
OSGi Compendium Specification
https://www.osgi.org/developer/specifications/
enRoute Documentation
http://enroute.osgi.org/book/210-doc.html
Blog posts
Getting Started with OSGi Declarative Services
http://blog.vogella.com/2016/06/21/getting-started-with-osgi-declarative-services/
OSGi Component Testing
http://blog.vogella.com/2016/07/04/osgi-component-testing/
Configuring OSGi Declarative Services
http://blog.vogella.com/2016/09/26/configuring-osgi-declarative-services/
top related