26
Field injection, type safe configuration, and more new goodies in Declarative Services BJ Hargrave, IBM

Field injection, type safe configuration, and more new goodies in Declarative Services

Embed Size (px)

Citation preview

Page 1: Field injection, type safe configuration, and more new goodies in Declarative Services

Field injection, type safe configuration, and more new goodies in Declarative

ServicesBJ Hargrave, IBM

Page 2: Field injection, type safe configuration, and more new goodies in Declarative Services

a ComponentImpl

a Service Impl

ServiceComponentRuntime Impl

a Servicea ComponentInstance

ComponentDescription

a ComponentConfguration

registered service

tracksdependencies

declares component

created by

controls 0..n

0..n

0..n

references

1..n1

ConfigurationAdmin

0..n

1

0..n

1

1

<<service>>Service ComponentRuntime

Declarative Services• A declarative model for publishing and

consuming OSGi services

• Introduced in Release 4 in 2005, it greatly simplified programming OSGi services

• Service Component Runtime, SCR, is the runtime which implements the spec and manages the service components

Page 3: Field injection, type safe configuration, and more new goodies in Declarative Services

Service Component

• A Java class which can optionally be registered as a service and can optionally use services

• Described by XML in the bundle which is processed at runtime by SCR

<?xml version="1.0" encoding="UTF-8"?><scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"

name="example.provider.ExampleImpl" activate="activate"> <implementation class="example.provider.ExampleImpl"/> <service> <provide interface="example.api.Example"/> </service> <reference name="Log" interface="org.osgi.service.log.LogService" bind="setLog"/></scr:component>

Page 4: Field injection, type safe configuration, and more new goodies in Declarative Services

Service Component using annotations

• But who wants to write XML?

• So DS 1.2 added support for programming with annotations

• Tools, like , process the annotations into the XML used by SCR at runtime

@Componentpublic class ExampleImpl implements Example {

private Map<String, Object> properties;private LogService log;@Activatevoid activate(Map<String, Object> map) {

properties = map;}@Overridepublic boolean say(String message) {

log.log((int) properties.get("loglevel"), message);return false;

}@Referencevoid setLog(LogService log) {

this.log = log;}

}

Page 5: Field injection, type safe configuration, and more new goodies in Declarative Services

Pretty cool!

Page 6: Field injection, type safe configuration, and more new goodies in Declarative Services

So what is new in Declarative Services 1.3?

• Field Injection

• Type Safe Configuration with MetaType integration

• Configuration Admin integration improvements

• Multiple PIDs

• Introspection

• And more small improvements we don’t have time to discuss today

• See 112.17 “Changes” in the DS 1.3 spec

Page 7: Field injection, type safe configuration, and more new goodies in Declarative Services

Field Injection

Page 8: Field injection, type safe configuration, and more new goodies in Declarative Services

Injection

• Method injection

• Constructor injection

• Field injection

@Referencevoid setLog(LogService log) {

this.log = log;}

Page 9: Field injection, type safe configuration, and more new goodies in Declarative Services

Field Injection

• Scalar cardinality

• Static policy

• Dynamic policy

@Referenceprivate Example target;

@Referenceprivate volatile Example target;

https://github.com/bjhargrave/osgice2015/blob/master/1ScalarFieldRef/src/example/command/ExampleCommand.java#L17

Page 10: Field injection, type safe configuration, and more new goodies in Declarative Services

Field Injection

• Multiple cardinality

• Service type from generic signature

• SCR-managed collection implementation

• Static policy

• Dynamic policy

@Referenceprivate List<Example> targets;

https://github.com/bjhargrave/osgice2015/blob/master/2MultipleFieldRef/src/example/command/ExampleCommand.java#L20

@Referenceprivate volatile List<Example> targets;

Page 11: Field injection, type safe configuration, and more new goodies in Declarative Services

Field Injection

• User managed collection

• Can also inject fields of types related to services and collections of those types

@Reference(policy = ReferencePolicy.DYNAMIC)private final List<Example> targets = new CopyOnWriteArrayList<>();

@ReferenceServiceReference<Example> sr;@ReferenceComponentServiceObjects<Example> so;@Reference(service=Example.class)Map<String,Object> props;@ReferenceMap.Entry<Map<String,Object>,Example> tuple;

Page 12: Field injection, type safe configuration, and more new goodies in Declarative Services

Type Safe Configuration

Page 13: Field injection, type safe configuration, and more new goodies in Declarative Services

Component Properties

• Component properties come from

• Component description

• Configuration Admin configuration

• ComponentFactory.newInstance

<property name=“myport" type="Integer" value="8080"/>

Dictionary<String, Object> props = new Hashtable<>();props.put("myport", Integer.valueOf(8081));cm.getConfiguration("Example").update(props);

Dictionary<String, Object> props = new Hashtable<>();props.put("myport", Integer.valueOf(8082));cf.newInstance(props);

Page 14: Field injection, type safe configuration, and more new goodies in Declarative Services

Getting the property values

• Activate method

• But what if the configuration value for myport was of type String? Or type Long?

• Type safety failure in your code

• You also need to handle the case where the property is not set

private int myport;@Activatevoid activate(Map<String, Object> props) {myport = props.containsKey("myport") ? ((Integer) props.get("myport")).intValue() : 8080;

}

Page 15: Field injection, type safe configuration, and more new goodies in Declarative Services

Component Property Types

• Define and use your component properties in a type safe manner using annotations!

@interface Props {int myport() default 8080;

}@Componentpublic class ExampleImpl implements Example {private int myport;@Activatevoid activate(Props props) {myport = props.myport();

}}

https://github.com/bjhargrave/osgice2015/blob/master/3TypeSafeConfig/src/example/provider/ExampleImpl.java#L14

Page 16: Field injection, type safe configuration, and more new goodies in Declarative Services

Type Safe Configuration and MetaType

Page 17: Field injection, type safe configuration, and more new goodies in Declarative Services

Component Property Types integrate with MetaType Service

• Use the new MetaType annotations to define metatype resources and associate them with your component

https://github.com/bjhargrave/osgice2015/blob/master/4TypeSafeConfigWithMetatype/src/example/provider/ExampleImpl.java#L14

@ObjectClassDefinition@interface Props {int myport() default 8080;

}@Designate(ocd=Props.class)@Componentpublic class ExampleImpl implements Example {private int myport;@Activatevoid activate(Props props) {myport = props.myport();

Page 18: Field injection, type safe configuration, and more new goodies in Declarative Services

Multiple Configurations

Page 19: Field injection, type safe configuration, and more new goodies in Declarative Services

Component properties from Configurations

• DS integrates with Configuration Admin and will get component properties from a configuration with the configuration pid of the component

@ObjectClassDefinition(pid = "Example")@interface Name {String name() default "Default Name";

}@Component(configurationPid = "Example")public class ExampleImpl implements Example {private String name;@Activatevoid activate(Name name) {this.name = name.name();

}}

Page 20: Field injection, type safe configuration, and more new goodies in Declarative Services

Sometimes we need to use multiple configurations

• A component may want to use a “system” configuration as well as a specific configuration

@ObjectClassDefinition(pid = “System")@interface Name {

String name() default "Default Name";}@ObjectClassDefinition(pid = "Example")@interface Words {

String hello() default "Hello";String goodbye() default "Goodbye";

}@Component(configurationPid = {“System", "Example"})public class ExampleImpl implements Example {

private String name;private Words words;@Activatevoid activate(Name name, Words words) {

this.name = name.name();this.words = words;

}https://github.com/bjhargrave/osgice2015/blob/master/6MultiplePIDs/src/example/provider/ExampleImpl.java#L13

Page 21: Field injection, type safe configuration, and more new goodies in Declarative Services

Introspection

Page 22: Field injection, type safe configuration, and more new goodies in Declarative Services

Introspecting the Service Components

• SCR now registers a ServiceComponentRuntime service which provides APIs to introspect the service components managed by SCR

public interface ServiceComponentRuntime {Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(Bundle... bundles);ComponentDescriptionDTO getComponentDescriptionDTO(Bundle bundle, String name);Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(ComponentDescriptionDTO

description);boolean isComponentEnabled(ComponentDescriptionDTO description);Promise<Void> enableComponent(ComponentDescriptionDTO description);Promise<Void> disableComponent(ComponentDescriptionDTO description);

}

https://github.com/bjhargrave/osgice2015/blob/master/5Introspection/src/example/command/ExampleCommand.java#L25

Page 23: Field injection, type safe configuration, and more new goodies in Declarative Services

SCR Data Transfer Objects

• DTOs are defined for

• Component descriptions - ComponentDescriptionDTO

• Component configurations - ComponentConfigurationDTO

• References - ReferenceDTO, SatisfiedReferenceDTO, UnsatisfiedReferenceDTO

Page 24: Field injection, type safe configuration, and more new goodies in Declarative Services

Why isn’t my component active?

• You can use the DTOs to figure out why

• It might be missing a required configuration or have an unsatisfied reference to a service

public class ComponentConfigurationDTO extends DTO {public static final int UNSATISFIED_CONFIGURATION= 1;public static final int UNSATISFIED_REFERENCE = 2;public static final int SATISFIED = 4;public static final int ACTIVE = 8;public ComponentDescriptionDTO description;public int state;public long id;public Map<String, Object> properties;public SatisfiedReferenceDTO[] satisfiedReferences;public UnsatisfiedReferenceDTO[] unsatisfiedReferences;

}

Page 25: Field injection, type safe configuration, and more new goodies in Declarative Services

Fin https://github.com/bjhargrave/osgice2015

Page 26: Field injection, type safe configuration, and more new goodies in Declarative Services