felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Bools <mark.bo...@principia-it.co.uk>
Subject Re: iPOJO: When do imported services become available?
Date Wed, 04 Jul 2012 17:16:17 GMT
Clement:

Okay, I've uploaded the example to GitHub (sorry if you don't use Maven, but all of this assumes
you do).

The GitHub site is https://github.com/ITSLM

Cloning https://github.com/ITSLM/OMNEITY-dev-environment.git should create a suitable build
environment.

The main code is in https://github.com/ITSLM/Omneity.git (under Omneity in the OMNEITY-dev-environment
project).

You will first need to build (all with mvn clean install):

- osgi-logging library as this is used by the other components.
- neo4j-lib-bundle as this is used by the data manager component at the moment.

Then, in any order:

- Omneity
- OBRadapter
- MVNAdapter
- felixLauncher (only needed if you want to set up felix launcher in Eclipse, although the
pom does provide details of the felix environment I'm using).

If you import these projects into Eclipse, the felixLauncher can be used to run the felix
environment as I have it configured (the only addition, other than adding the main class org.apache.felix.main.Main
to the the run configuration, is to add the following to the VM arguments if you want to see
the logging output -Dlogback.configurationFile=conf/logback.xml ).

In the Omneity and felixLauncher repositories the master branch contains the working sample
where I am using DataSourceManagerImpl without a composite structure around it and the composite-test
branch contains the version where I'm having difficulty.

Other details about my development environment can be found at http://omneity.itslm.com/wiki/Development_Environment

I hope that provides enough information.

Regards,
Mark


On 4 Jul 2012, at 09:43, Mark Bools wrote:

> Clement, thanks for responding. I'll go one better, I'll upload the system I am currently
working on (don't worry, it's not much more than a test case at the moment as the project
is VERY early in development). I'll get this done today and provide details when it's done.
> 
> 
> On 4 Jul 2012, at 07:36, Clement Escoffier wrote:
> 
>> Hi,
>> 
>> I don't really see why all imported services are not injected correctly. They are
imported correctly, but it seems like the instance does not see all of them. 
>> Would you have a mean to provide me a 'test case' to let me check what's going wrong
here. 
>> 
>> Regards,
>> 
>> Clement
>> 
>> 
>> On 03.07.2012, at 18:27, Mark Bools wrote:
>> 
>>> Still puzzled by this one. Any help appreciated.
>>> 
>>> I've continued to poke this one with a sharp stick, but I'm not making any progress.
>>> 
>>> I recently removed the (optional="true") requirement from the @Requires for the
adapter array (everything else is as originally described, although I added one more Adapter
implementation; MVNAdapter) and now I get one Adapter mapped into the adapter array and, as
can be seen below, I get one Adapter satisfying the requires in the DataSourceManager instance.
What I do not understand is why? The require is clearly aggregate="true" and I expected that
all imported Adapter instances would be mapped in under those circumstances, am I wrong in
thinking that?
>>> 
>>> All of the relevant services are being imported (or that's how I read this output),
but only the first one seems to be dynamically mapped into the requires of the DataSourceManagerImpl-0
instance, and consequently  to the adapter array.
>>> 
>>> instance DataSourceManager
>>> instance name="DataSourceManager" state="valid" bundle="39" component.type="DataSourceManager"
>>> 	handler name="org.apache.felix.ipojo:instance" state="valid"
>>> 		instance factory="com.itslm.omneity.data.service.DataSourceManagerImpl" name="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
state="valid"
>>> 	handler name="org.apache.felix.ipojo:provides" state="valid"
>>> 		exports specification="com.itslm.omneity.data.api.DataSourceManager" filter="(objectClass=com.itslm.omneity.data.api.DataSourceManager)"
state="resolved"
>>> 	handler name="org.apache.felix.ipojo:subservice" state="valid"
>>> 		requires specification="com.itslm.omneity.adapter.api.Adapter" filter="(&(objectClass=com.itslm.omneity.adapter.api.Adapter)(!(instance.name=DataSourceManager)))"
state="resolved"
>>> 			provider name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
>>> 			provider name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
>>> 			provider name="com.itslm.omneity.adapter.mvn.MVNAdapter-0"
>>> 		requires specification="org.osgi.service.log.LogService" filter="(&(objectClass=org.osgi.service.log.LogService)(!(instance.name=DataSourceManager)))"
state="resolved"
>>> 			provider name="null"
>>> 	handler name="org.apache.felix.ipojo:architecture" state="valid"
>>> 	services
>>> 		service architecture.instance="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
factory.name="architecture" instance.name="architecture-7" objectclass="[org.apache.felix.ipojo.architecture.Architecture]"
service.id="5"
>>> 		service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" service.id="6"
>>> 		service factory.name="com.itslm.omneity.data.service.DataSourceManagerImpl"
instance.name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" objectclass="[com.itslm.omneity.data.api.DataSourceManager,
com.tinkerpop.blueprints.TransactionalGraph, com.tinkerpop.blueprints.KeyIndexableGraph, com.tinkerpop.blueprints.IndexableGraph,
com.tinkerpop.blueprints.Graph]" service.id="7"
>>> 		service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" service.id="8"
>>> 		service factory.name="com.itslm.omneity.adapter.mvn.MVNAdapter" instance.name="com.itslm.omneity.adapter.mvn.MVNAdapter-0"
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="mvn" service.id="9"
>>> 		service objectclass="[org.osgi.service.log.LogService]" service.id="10"
>>> 	containedinstances
>>> 		instance name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" state="valid"
bundle="37" component.type="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>> 			handler name="org.apache.felix.ipojo:requires" state="valid"
>>> 				requires specification="com.itslm.omneity.adapter.api.Adapter" id="com.itslm.omneity.adapter.api.Adapter"
optional="false" aggregate="true" proxy="false" binding-policy="dynamic" state="resolved"
>>> 					uses service.id="6" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
>>> 			handler name="org.apache.felix.ipojo:callback" state="valid"
>>> 			handler name="org.apache.felix.ipojo:provides" state="valid"
>>> 				provides specifications="[com.itslm.omneity.data.api.DataSourceManager,com.tinkerpop.blueprints.TransactionalGraph,com.tinkerpop.blueprints.KeyIndexableGraph,com.tinkerpop.blueprints.IndexableGraph,com.tinkerpop.blueprints.Graph]"
state="registered" service.id="7"
>>> 					property name="factory.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>> 					property name="instance.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
>>> 					controller value="true"
>>> 			handler name="org.apache.felix.ipojo:architecture" state="valid"
>>> 			object name="com.itslm.omneity.data.service.DataSourceManagerImpl@5492de02"
>>> g! 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> If I remove the composite wrapper and instantiate directly, I get what I expected;
all three Adapter services mapped in to the instance and the adapter array full populated
with the three services.
>>> 
>>> g! instance com.itslm.omneity.data.service.DataSourceManagerImpl-0
>>> instance name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" state="valid"
bundle="37" component.type="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>> 	handler name="org.apache.felix.ipojo:requires" state="valid"
>>> 		requires specification="com.itslm.omneity.adapter.api.Adapter" id="com.itslm.omneity.adapter.api.Adapter"
optional="false" aggregate="true" proxy="false" binding-policy="dynamic" state="resolved"
>>> 			uses service.id="37" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
>>> 			uses service.id="40" instance.name="com.itslm.omneity.adapter.mvn.MVNAdapter-0"
>>> 			uses service.id="35" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
>>> 	handler name="org.apache.felix.ipojo:callback" state="valid"
>>> 	handler name="org.apache.felix.ipojo:provides" state="valid"
>>> 		provides specifications="[com.itslm.omneity.data.api.DataSourceManager,com.tinkerpop.blueprints.TransactionalGraph,com.tinkerpop.blueprints.KeyIndexableGraph,com.tinkerpop.blueprints.IndexableGraph,com.tinkerpop.blueprints.Graph]"
state="registered" service.id="43"
>>> 			property name="factory.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>> 			property name="instance.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
>>> 			controller value="true"
>>> 	handler name="org.apache.felix.ipojo:architecture" state="valid"
>>> 	object name="com.itslm.omneity.data.service.DataSourceManagerImpl@61ffbcb"
>>> g! 
>>> 
>>> 
>>> 
>>> 
>>> This is really baking my noodle.
>>> 
>>> Regards,
>>> Mark
>>> 
>>> 
>>> On 2 Jul 2012, at 16:07, Mark Bools wrote:
>>> 
>>>> I've been chasing this one around for a while, so I thought it time to ask.
:)
>>>> 
>>>> I have an Adapter service with one implementation OBRAdapter. I can create
instances of the OBRAdaptor without difficulty using the following metadata.xml
>>>> 
>>>> <ipojo>
>>>> 	<instance component="com.itslm.omneity.adapter.obr.OBRAdapter">
>>>> 		<property name="scheme" value="obr1"/>
>>>> 	</instance>
>>>> 	<instance component="com.itslm.omneity.adapter.obr.OBRAdapter">
>>>> 		<property name="scheme" value="obr2"/>
>>>> 	</instance>
>>>> </ipojo>
>>>> 
>>>> Now, although these are 'system supplied' Adapters I want to isolate  Adapters
inside a data management component so that user supplied 'plugins' (that will be picked up
programmatically later) have limited access to the rest of the system. So I created a composite
using the following metadata.xml on a substantially empty jar (with only bundle identity,
basically):
>>>> 
>>>> <ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>> 	xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd

>>>> 	    org.apache.felix.composite http://felix.apache.org/ipojo/schemas/SNAPSHOT/composite.xsd"
>>>> 	xmlns="org.apache.felix.ipojo" xmlns:comp="org.apache.felix.ipojo.composite">
>>>> 
>>>> 	<comp:composite name="DataSourceManager">
>>>> 		<comp:instance component="com.itslm.omneity.data.service.DataSourceManagerImpl"
/>
>>>> 		<comp:provides action="export"
>>>> 			specification="com.itslm.omneity.data.api.DataSourceManager" />
>>>> 
>>>> 		<!-- Will programmatically identify and load Adaptor plugins, this next

>>>> 			entry imports Adapters in the global scope (so, only those that are in
the 
>>>> 			main bundle directory) 
>>>> 			-->
>>>> 		<comp:subservice action="import" aggregate="true"
>>>> 			specification="com.itslm.omneity.adapter.api.Adapter" />
>>>> 
>>>> 		<comp:subservice action="import"
>>>> 			specification="org.osgi.service.log.LogService" />
>>>> 
>>>> 	</comp:composite>
>>>> 
>>>> 	<comp:instance component="DataSourceManager" name="DataSourceManager"
/>
>>>> 
>>>> </ipojo>
>>>> 
>>>> When I examine the running system I see the two Adapters apparently instantiated
and available inside the DataSourceManager component (as I hoped).
>>>> 
>>>> g! instance DataSourceManager
>>>> instance name="DataSourceManager" state="valid" bundle="38" component.type="DataSourceManager"
>>>> 	handler name="org.apache.felix.ipojo:instance" state="valid"
>>>> 		instance factory="com.itslm.omneity.data.service.DataSourceManagerImpl"
name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" state="valid"
>>>> 	handler name="org.apache.felix.ipojo:provides" state="valid"
>>>> 		exports specification="com.itslm.omneity.data.api.DataSourceManager" filter="(objectClass=com.itslm.omneity.data.api.DataSourceManager)"
state="resolved"
>>>> 	handler name="org.apache.felix.ipojo:subservice" state="valid"
>>>> 		requires specification="com.itslm.omneity.adapter.api.Adapter" filter="(&(objectClass=com.itslm.omneity.adapter.api.Adapter)(!(instance.name=DataSourceManager)))"
state="resolved"
>>>> 			provider name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
>>>> 			provider name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
>>>> 		requires specification="org.osgi.service.log.LogService" filter="(&(objectClass=org.osgi.service.log.LogService)(!(instance.name=DataSourceManager)))"
state="resolved"
>>>> 			provider name="null"
>>>> 	handler name="org.apache.felix.ipojo:architecture" state="valid"
>>>> 	services
>>>> 		service architecture.instance="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
factory.name="architecture" instance.name="architecture-6" objectclass="[org.apache.felix.ipojo.architecture.Architecture]"
service.id="4"
>>>> 		service factory.name="com.itslm.omneity.data.service.DataSourceManagerImpl"
instance.name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" objectclass="[com.itslm.omneity.data.api.DataSourceManager,
com.tinkerpop.blueprints.TransactionalGraph, com.tinkerpop.blueprints.KeyIndexableGraph, com.tinkerpop.blueprints.IndexableGraph,
com.tinkerpop.blueprints.Graph]" service.id="5"
>>>> 		service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" service.id="6"
>>>> 		service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" service.id="7"
>>>> 		service objectclass="[org.osgi.service.log.LogService]" service.id="8"
>>>> 	containedinstances
>>>> 		instance name="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
state="valid" bundle="36" component.type="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>>> 			handler name="org.apache.felix.ipojo:requires" state="valid"
>>>> 				requires specification="com.itslm.omneity.adapter.api.Adapter" id="com.itslm.omneity.adapter.api.Adapter"
optional="true" nullable="true" aggregate="true" proxy="false" binding-policy="dynamic" state="resolved"
>>>> 			handler name="org.apache.felix.ipojo:callback" state="valid"
>>>> 			handler name="org.apache.felix.ipojo:provides" state="valid"
>>>> 				provides specifications="[com.itslm.omneity.data.api.DataSourceManager,com.tinkerpop.blueprints.TransactionalGraph,com.tinkerpop.blueprints.KeyIndexableGraph,com.tinkerpop.blueprints.IndexableGraph,com.tinkerpop.blueprints.Graph]"
state="registered" service.id="5"
>>>> 					property name="factory.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl"
>>>> 					property name="instance.name" value="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
>>>> 					controller value="true"
>>>> 			handler name="org.apache.felix.ipojo:architecture" state="valid"
>>>> 			object name="com.itslm.omneity.data.service.DataSourceManagerImpl@7e266b44"
>>>> g! 
>>>> 
>>>> However, inside the DataSourceManagerImpl I have a @Requires, e.g.
>>>> 
>>>> 	/** All of the Adapter services currently available. */
>>>> 	@Requires(optional = true)
>>>> 	private Adapter[] adapters;
>>>> 
>>>> This does what I expect outside the composite (namely, dynamically tracks
the currently available adapters), but inside the composite this field is not populated (at
least not in the start() method where I do a simple LOGGER.debug("Adapters found: " + adapters.length)
as a test. This reports '2' when running outside the composite, but '0' when running inside
the composite.
>>>> 
>>>> I know I'm missing (or misunderstanding) something. Can anyone help by explaining
where I'm going wrong? Thanks in advance.
>>>> 
>>>> Regards,
>>>> Mark
>>>> 
>>>> 
>>> 
>> 
> 


Mime
View raw message