Using Properties to Import Endpoint Descriptions
OSGi Remote Services can be imported by service consumers via several methods. One method is to have a network-based discovery provider, that uses some communications protocol to publish, discover and import remote services over some network.
Another method is to have File-Based Remote Services Discovery. The OSGI Remote Services and Remote Service Admin specifications define an xml-formatted document called the the Endpoint Description Extender Format (EDEF).
According to the RSA specification, EDEF files can be provided in the bundle MANIFEST.MF after the 'Remote-Service header, and when this bundle is started, all given EDEF files will be read by ECF RSA implementation, and all endpoint descriptions will be imported. For example, in this manifest...which is part of the ECF Timeservice Example...there is this header:
In the com.mycorp.examples.timeservice.consumer.filediscovery project is the TimeService EDEF. When this bundle is started, the ECF RSA implementation will read and parse this file, and import the given endpoint description as a remote service proxy.
Although EDEF is general, it's not as easy-to-use as it could be under some circumstances. For example, both RSA as specified, and ECF's implementation require that some properties be set, while other properties in the EDEF are optional. It's often a lot to ask that the EDEF creator know the required vs. optional properties.
EDEF Properties Files
ECF has recently introduced a mechanism to make it easier to create and import Endpoint Descriptions using properties files. Properties files can be used to override values in an underlying XML EDEF file, with the properties file values always taking precedence.
Properties files can now also be used as an alternative to XML-based endpoint definition. You can now remove the XML file entirely and specify the properties file in your bundle manifest.
Properties file content
While EDEF properties files are structured as name/value pairs, they can contain all the attributes usually found in XML-based EDEF files. Support has been added for various data types including arrays and also the generation of random values (e.g. UUIDs) if needed. The structure for a property entry is:
# # String properties do not require a type # # Leaving value blank generates default # # name:type=value (leave value blank to generate default) # # String ecf.endpoint.id=ecftcp://localhost:3288/server # Boolean service.imported:boolean=true # UUID endpoint.id:uuid=0 # Long endpoint.service.id:Long=0 # Long nanoTime ecf.endpoint.ts:Long:nanoTime=0 # Array with one element objectClass:array=com.mycorp.examples.timeservice.ITimeService # Array with multiple elements remote.intents.supported:array=passByValue,exactlyOnce,ordered
Properties file usage
EDEF properties files can be used in a variety of ways:
- Default properties files - applies to all of service endpoints defined in a bundle (or in a specific folder)
- Service-specific properties files - applies to a specific service endpoint definition
- Profile-specific properties files - can be specified either for default or for service-specific properties and activated by a command line parameter
These three types of properties files can be combined in a variety of ways depending on your specific needs. In any case, all attributes defined in properties files will override anything in an XML EDEF file, if that file exists.
Default properties files
A default properties file must be named edef_defaults.properties. If this file is located in the bundle root folder, then the defaults will apply to all remote services defined in the bundle. This can be useful if all of your remote services share the same provider. For example, all Jersey JAX-RS client definitions share the following properties:
endpoint.id:uuid=0 ecf.endpoint.id.ns=ecf.namespace.jaxrs remote.configs.supported:array=ecf.jaxrs.jersey.server remote.intents.supported:array=passByValue, exactlyOnce, ordered, jaxrs service.imported.configs:array=ecf.jaxrs.jersey.server service.intents:array=osgi.async ecf.endpoint.rsfilter=(objectClass=*) ecf.rsvc.id:Long=0
You can also place an edef_defaults.properties file in a directory (e.g. 'edef' or 'OSGI-INF') that contains a specific set of endpoint definitions. In this case the defaults will apply only to those endpoints specified in that directory.
Properties specified in a specific directory will override those specified in the bundle root.
bundle root /edef_defaults.properties (applied first) /edef edef_defaults.properties (applied to services in folder and override base defaults) timeserviceendpointdescription.xml
Service-specific properties files
A properties file can contain all or some of the properties needed to define an endpoint. If a properties file is meant to override values in an existing XML EDEF file, then it must be named the same except for the file extension.
bundle root /edef_defaults.properties /edef edef_defaults.properties timeserviceendpointdescription.xml timeserviceendpointdescription.properties (overrides all default and XML properties)
Again, you can also specify the properties file directly in your bundle manifest and eliminate the XML file entirely.
Endpoint definitions often need to vary based on some runtime configuration. For example, you may have a different endpoint URL for various environments.
Development environment - http://dev.myserver.com/rservices/rs1 Test environment - http://test.myserver.com/rservices/rs1 Production environment - http://prod.myserver.com/rservices/rs1
Profile-specific properties files allow you to do this by overriding both the default and service-specific properties described above. First, a profile name can be specified as a command line argument:
If a profile is specified, the framework will attempt to locate properties files with the profile name specified as a suffix. Profile-based properties can be specified for both defaults and endpoint-specific properties.
For example, if the profile name is set as 'dev', then the framework would look at this file structure:
bundle root /edef_defaults.properties /edef-defaults-dev.properties (overrides non-profile defaults) /edef edef_defaults.properties edef-defaults-dev.properties (overrides all root defaults and folder defaults) timeserviceendpointdescription.properties timeserviceendpointdescription-dev.properties (overrides all non-profile defaults)
EDEF Properties for Importing JaxRS Remote Services into an Eclipse RCP Application
Patrick Paulin has blogged about using EDEF properties for importing JaxRS Remote Services into an Eclipse RCP Application.