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