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 <[email protected]> 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 <[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]





---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to