Hi Philipp;
On Thu, Sep 25, 2014 at 8:54 AM, Bulu <[email protected]> wrote:
> Hello all
>
> (sorry for asking so many questions - they come-up as I write my code)
>
no problem at all :-)
>
> In DM, how can you adapt a certain service and re-publish under a new
> interface using some properties of the adapted service?
>
When you define an adapter (DeviceConsumer), the service properties of the
adapted service (Device) are automatically propagated to the new adapter
interface (DeviceConsumer).
>
> Example:
> interface Device{
> int getId();
> }
> each published with property
> device.id=xxx
> where xxx is the int from getId()
>
> elsewhere, we want to adapt the Device services
> mgr.add(createAdapterService(Device.class,null)
> .setImplementation(DeviceConsumerImpl.class)
> .setInterface(DeviceConsumer.class.getName(), props);
>
> here, "props" should again contain the device.id=xxx value, but its not
> yet available, so the above cannot work.
>
since the adapted service properties are propagated, I think you don't need
to pass a props to the setInterface method; just pass "null":
mgr.add(createAdapterService(Device.class,null)
.setImplementation(DeviceConsumerImpl.class)
.setInterface(DeviceConsumer.class.getName(), null);
If you pass some properties to the setInterface method, those properties
will be appended to the service properties of the original adapted service,
so in the end the re-publised service will contain the adapted service
properties + the properties you pass to the setInterface methods.
does this help ?
regards
/Pierre
> We could inject it in the service's init method:
> class DeviceConsumerImpl {
> Device d;
> public void init(Component c){
> Dictionary<String, Object> props = new Hashtable<>();
> props.put("device.id", d.getId())
> c.setInterface(DeviceConsumer.class.getName(), props);
> }
>
> but this fails with IllegalStateException (it seems you cannot publish
> (ie. setInterface) a new service while the object is being initialized).
>
> So how should it be done?
>
> I came up with a workaround, which is to publish the service at first with
> incomplete properties, and just update them in the init method when the
> values are present. But that seems like a hack... Is there a better way?
>
> Thanks Philipp
>
>
>
>
>
> On 24.09.2014 18:09, Pierre De Rop wrote:
>
>> Hi Philipp;
>>
>> see my response, inlined below:
>>
>>
>> On Wed, Sep 24, 2014 at 4:46 PM, Bulu <[email protected]> wrote:
>>
>> Hello all
>>>
>>> If the published property of a service is based on a value in the actual
>>> service object, and that value later changes, how can I update the
>>> properties using DM?
>>>
>>> Example: You have Device objects (and the corresponding impl)
>>> public interface Device{
>>> public int getRoom();
>>> public void setRoom(int i);
>>> }
>>>
>>> Maybe you originally register the device like this
>>>
>>> Device d = new DeviceImpl();
>>> s.setRoom(12);
>>> Dictionary<String, Object> props = new Hashtable<>();
>>> props.put("room", d.getRoom());
>>> mgr.add(createComponent()
>>> .setImplementation(d)
>>> .setInterface(Device.class.getName(), props));
>>>
>>> ... later somebody else (maybe a consumer of the service...) calls
>>> d.setRoom(13)
>>>
>>> How can I update the "room" property of the service?
>>>
>>> I believe I could keep the Component from start(Component c) and later
>>> use
>>> its setServiceProperties() but is that clean/correct?
>>>
>>> This is indeed possible, but alternatively, you could also declare a
>> ServiceRegistration field in your implementation class, which will be
>> injected once the device service has been registered.
>> And later, from the setRoot(int id) you can then use the service
>> registration in order to modify or add some service properties.
>>
>>
>>
>> like so:
>>> class DeviceImpl implements Device {
>>> private Component c;
>>> private int room;
>>> public void start(Component c){
>>> this.c = c;
>>> }
>>>
>>> public void setRoom(int i){
>>> room = i;
>>> c.setServiceProperties(c.getServiceProperties().put("room", i));
>>> }
>>> }
>>>
>>> Is this correct? Is there a better method or pattern to use? Any problems
>>> to expect from keeping the Component around?
>>>
>>> if you use this pattern instead of using the ServiceRegistration, as
>> described before, then yes, it would also work, except that there is a
>> little mistake in the above example: the setServiceProperties takes a
>> Dictionary as parameter, while the c.getServiceProperties().put("room", i)
>> returns an object.
>>
>> Since the Component.getServiceProperties() method returns a copy of the
>> actual service properties, you could then do like this:
>>
>> Dictionary props = component.getServiceProperties();
>> props.put("room", i);
>> component.setServiceProperties(props);
>>
>>
>> Also, what happens when the service consumer which is calling setRoom(),
>>> is actually filtering on that property, so that his object gets removed
>>> still while he is calling the method?
>>>
>>> there are two cases:
>>
>> 1) using DM 3.2.0, if your consumer calls the device.setRoom(int id)
>> method, then at the time this methods calls
>> "component.setServiceProperties()", then the consumer will be
>> synchronously
>> called in it's "changed" callback if one has been defined and if the
>> dependency filter on the device service is still satisfied.
>>
>> And if the consumer dependency filter is not satisfied anymore, then the
>> consumer will be synchronously called in its stop callback (because the
>> consumer is losing the device service, and the consumer component will
>> then
>> being stopped), and then the consumer "unbind(Device)" callback will be
>> called (if defined).
>>
>> And at this point, you will then return from the intial invocation of the
>> device.setRoot(int id) method.
>>
>> 2) using DM 4.0.0 (not yet in the trunk, only in sandbox), the same as
>> above applies except if the
>> parallel Dependency Manager is enabled.
>>
>> Indeed, In DM 4.0.0, you can now optionally register a threadpool in the
>> service registry, in order to handle all component events concurrently
>> (service depenency management, and lifecycle callbacks).
>> So, in this case, when you would call component.setServiceProperties(), or
>> serviceRegistration.setProperties() method, you would then be
>> asynchronously called in your consumer.stop / consumer.unbind(Device)
>> method.
>>
>> regards;
>> /Pierre
>>
>>
>>
>>
>> Regards Philipp
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>