Thanks for the clarification now I got it.
Yes whiteboard model should work nicely. Especially as this component
might not be the only subscriber.
Christian
On 14.10.2016 08:58, Peter Kriens wrote:
@Christian: The MQTT client is optional and dynamic. So the activate method
cannot be used. You need to subscribe/unsubscribe based on the availability of
the mqtt server.
@Daghan:
Divide and conquer! You’re trying to do multiple responsibilities in one
component and that is the antithesis of modularity, also called lack of
cohesion. This is a perfect example of how things could get simpler by choosing
the right decomposition.
The best solution imho is to introduce a second,component. Let the Device
component just be a Device, it should not have to worry about Mqtt. After all,
you could be connected to other event queues. (It also makes it easier to
test.) You made mqtt optional to reflect this. This is exactly the reason the
Whiteboard Pattern was invented!
This would look like:
@Component( property = “subscriptionChannel=” )
public class LT100HDeviceImpl implements Device, TtnMqttMessageListener
{
// remove the mqtt subscription code but
// implement the TtnMqttMessageListener
}
And the whiteboard component. Notice the _ in the _mqtt field. This ensures it
is set before the event method that has a name that will appear in a sorted
list later. (References are sorted by name.) (I vaguely recall field references
are done before bind methods but this makes it certain.)
@Component(immediate=true)
public class MQTTWhiteboard {
@Reference
TtnMqttProtocol _mqtt;
@Reference( cardinality = ReferenceCardinality.OPTIONAL, policy
= ReferencePolicy.DYNAMIC )
void addMqttListener( TtnMqttMessageListener l,
Map<String,Object> props ) {
String channel = props.get( “subscriptionChannel” );
if ( channel != null && !channel.isEmpty() ) {
_mqtt. subscribe( channel, l );
}
void removeMqttListener( TtnMqttMessageListener l,
Map<String,Object> props ) {
String channel = props.get( “subscriptionChannel” );
if ( channel != null && !channel.isEmpty() ) {
_mqtt.unsubscribe( channel );
}
}
You now created a whiteboard service that can also be used by other Device
implementations while significantly reducing the complexity of your
implementation.
This is why after all those years I still love OSGi … you can only do this when
you have dynamic components. As your struggle showed, trying to manage this is
quickly becoming quite complex. Whenever you enter in such a struggle, think,
lack of cohesion is often your problem.
Kind regards,
Peter Kriens
On 14 okt. 2016, at 08:09, Christian Schneider <ch...@die-schneider.net> wrote:
In your case simply inject the ttnMqttClient in the @Reference and do the
subscribe in @Activate when you get the config and the unsubscribe in
@Deactivate.
Christian
2016-10-13 23:00 GMT+02:00 Daghan ACAY <daghana...@hotmail.com>:
Hi all,
I am trying to create a component that is instantiated by ConfigAdmin and uses
multiple references to operate. Basically the component should instantiate
through a factory configuration and use that configuration to set up its own
@Reference s. You can see the code here:
https://github.com/daghanacay/com.easyiot.device/blob/master/com.easyiot.LT100H.device.provider/src/com/easyiot/LT100H/device/provider/LT100HDeviceImpl.java
All the mentioned @Reference ed components are instantiated by configuration as
well, so at a given time the @Reference might not be available but my own
component should still work. yet should the Reference available then it should
be injected, basic 0-1 strategy.
Problem I am facing with the current form of the code is that, the @Reference
injection is happening before the @Activate method is called. This leads to NPE
in the @Reference method due to null configuration. Is it possible to make this
code work such that config is provided to the component before the dependency
injection?
I have tried annotating the class fields and set them "volatile". I even make
them a list and use the class fields in the activate method this time the class fields
were null due to 0-1 strategy. so I end up with annotating the methods.
I might have designed this all wrong, so any help simple or fundamental is
appreciated.
Regards
-Daghan
Sent by MailWise – See your emails as clean, short chats.
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
--
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
http://www.talend.com
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
http://www.talend.com
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev