You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Bulu <bu...@romandie.com> on 2014/09/24 16:46:53 UTC

Dependency Manager: how to update service properties

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?

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?

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?

Regards Philipp



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Dependency Manager: publish adapter with properties of the adapted service

Posted by Bulu <bu...@romandie.com>.
Yes OK. This is what I'm currently doing.

First publish the adapter as EventHandler and later (in init() ) set the 
properties correctly.
I just thought it wasn't clean.
Thanks again Philipp

On 25.09.2014 11:34, Pierre De Rop wrote:
> Ah ok; I understand.
>
>  From your adapter (DeviceConsumerImpl), in the init() method, just call
> component.setServiceProperties()  instead of component.setInterface method.
>
> Something like this:
>
> class DeviceConsumerImpl implements DeviceConsumer
>      void init(Component c) {
>          DependencyManager dm = c.getDependencyManager();
>
>          // add a dynamic dependency on the DeviceParameter ...
>          c.add(dm.createServiceDependency()
>              .setService(DeviceParameter.class, "(device.id=" +
> device.getDeviceId() + ")")
>              .setRequired(true));
>
>          // Now, set our adapter service properties, which will be appended
> to the republished
>          // adapted service properties !
>
>          Hashtable props = new Hashtable();
>          props.put(EventConstants.EVENT_TOPIC, "my/device/events");
>          props.put(EventConstants.EVENT_FILTER,"(device.id=" +
> device.getDeviceId() + ")");
>          c.setServiceProperties(props);
>      }
>
> This works with DM 4.0.0, but should also work with DM 3.2.0 (but I did not
> have time to test).
>
> regards
> /Pierre
>
> On Thu, Sep 25, 2014 at 11:07 AM, Bulu <bu...@romandie.com> wrote:
>
>> Hello Pierre
>>
>> My example was too simple, I would like to republish the adapter with
>> values from the adapted service, but under new keys.
>>
>> Specifically, the new interface is EventHandler and I want to build the
>> EVENT_FILTER from the adapted service (ie. Device) properties..
>>
>>
>> Dictionary props =new  Hashtable();
>> props.put(EventConstants.EVENT_TOPIC, "my/device/events");
>>
>> props.put(EventConstants.EVENT_FILTER,"(device.id=xxx)"); // xxx comes
>> from the Device instance
>>
>> mgr.add(createAdapterService(Device.class,null)
>>    .setImplementation(DeviceConsumerImpl.class)
>>    .setInterface(EventHandler.class.getName(), props);
>>
>> Philipp
>>
>>
>> On 25.09.2014 10:53, Pierre De Rop wrote:
>>
>>> Hi Philipp;
>>>
>>> On Thu, Sep 25, 2014 at 8:54 AM, Bulu <bu...@romandie.com> 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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>>>>   ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Dependency Manager: publish adapter with properties of the adapted service

Posted by Pierre De Rop <pi...@gmail.com>.
Ah ok; I understand.

>From your adapter (DeviceConsumerImpl), in the init() method, just call
component.setServiceProperties()  instead of component.setInterface method.

Something like this:

class DeviceConsumerImpl implements DeviceConsumer
    void init(Component c) {
        DependencyManager dm = c.getDependencyManager();

        // add a dynamic dependency on the DeviceParameter ...
        c.add(dm.createServiceDependency()
            .setService(DeviceParameter.class, "(device.id=" +
device.getDeviceId() + ")")
            .setRequired(true));

        // Now, set our adapter service properties, which will be appended
to the republished
        // adapted service properties !

        Hashtable props = new Hashtable();
        props.put(EventConstants.EVENT_TOPIC, "my/device/events");
        props.put(EventConstants.EVENT_FILTER,"(device.id=" +
device.getDeviceId() + ")");
        c.setServiceProperties(props);
    }

This works with DM 4.0.0, but should also work with DM 3.2.0 (but I did not
have time to test).

regards
/Pierre

On Thu, Sep 25, 2014 at 11:07 AM, Bulu <bu...@romandie.com> wrote:

> Hello Pierre
>
> My example was too simple, I would like to republish the adapter with
> values from the adapted service, but under new keys.
>
> Specifically, the new interface is EventHandler and I want to build the
> EVENT_FILTER from the adapted service (ie. Device) properties..
>
>
> Dictionary props =new  Hashtable();
> props.put(EventConstants.EVENT_TOPIC, "my/device/events");
>
> props.put(EventConstants.EVENT_FILTER,"(device.id=xxx)"); // xxx comes
> from the Device instance
>
> mgr.add(createAdapterService(Device.class,null)
>   .setImplementation(DeviceConsumerImpl.class)
>   .setInterface(EventHandler.class.getName(), props);
>
> Philipp
>
>
> On 25.09.2014 10:53, Pierre De Rop wrote:
>
>> Hi Philipp;
>>
>> On Thu, Sep 25, 2014 at 8:54 AM, Bulu <bu...@romandie.com> 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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>
>>>>>
>>>>>
>>>>>  ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>

Re: Dependency Manager: publish adapter with properties of the adapted service

Posted by Bulu <bu...@romandie.com>.
Hello Pierre

My example was too simple, I would like to republish the adapter with 
values from the adapted service, but under new keys.

Specifically, the new interface is EventHandler and I want to build the 
EVENT_FILTER from the adapted service (ie. Device) properties..


Dictionary props =new  Hashtable();
props.put(EventConstants.EVENT_TOPIC, "my/device/events");

props.put(EventConstants.EVENT_FILTER,"(device.id=xxx)"); // xxx comes from the Device instance

mgr.add(createAdapterService(Device.class,null)
   .setImplementation(DeviceConsumerImpl.class)
   .setInterface(EventHandler.class.getName(), props);

Philipp

On 25.09.2014 10:53, Pierre De Rop wrote:
> Hi Philipp;
>
> On Thu, Sep 25, 2014 at 8:54 AM, Bulu <bu...@romandie.com> 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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


Re: Dependency Manager: publish adapter with properties of the adapted service

Posted by Pierre De Rop <pi...@gmail.com>.
Hi Philipp;

On Thu, Sep 25, 2014 at 8:54 AM, Bulu <bu...@romandie.com> 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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Dependency Manager: publish adapter with properties of the adapted service

Posted by Bulu <bu...@romandie.com>.
Hello all

(sorry for asking so many questions - they come-up as I write my code)

In DM, how can you adapt a certain service and re-publish under a new 
interface using some properties of the adapted service?

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.

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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Dependency Manager: how to update service properties

Posted by Bulu <bu...@romandie.com>.
Hello Pierre

Thanks - I will go with the injected ServiceRegistration so also the 
correct tear-down (release of the reference) is managed by DM (and I 
also get less dependency on the DM package).

Regards 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 <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Dependency Manager: how to update service properties

Posted by Pierre De Rop <pi...@gmail.com>.
Hi Philipp;

see my response, inlined below:


On Wed, Sep 24, 2014 at 4:46 PM, Bulu <bu...@romandie.com> 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: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>