How to add an observer to a nano service
Registering observers to nano services is quite common.
Prerequisite for the tutorial
You should have read these tutorials beforehand:
Package initialization
How to start a simple target
The short way
To make registration as easy as possible, another service has been created: the RecordHelper. Enter the dependency in the ServiceStarter.
public void getDependencies(@NotNull final IServiceDependencyList aDependencyList) { aDependencyList.add(IRecordHelper.class); }
In the target:
private boolean asyncStartTarget(@NotNull final CEnvelope aEnvelope, @NotNull final CRecord aRecord) throws CException { mDependencies.getRecordHelper() .addObserver(CRecordNotifyRemoteNodeAdded.class, this, true); aEnvelope.setResultSuccess(); return true; }
The long way
Add the nano service registry as a dependency to the service starter. As a filter, we need to enter the namespace where the desired nano service is registered.
public void getDependencies(@NotNull final IServiceDependencyList aDependencyList) { aDependencyList.add(INanoServiceRegistry.class, "nid=SYSTEM"); }
In the ServiceStarter, the desired service is also fetched with filter.
@Override public void start(@NotNull final IServiceRegistry aServiceRegistry) throws Exception { if (mService == null) { mNanoServiceRegistry = aServiceRegistry.getServiceOrThrow(INanoServiceRegistry.class, "nid=SYSTEM"); ... } }
In the target, the observer is registered directly in the nano service registry.
private boolean asyncStartTarget(@NotNull final CEnvelope aEnvelope, @NotNull final CRecord aRecord) throws CException { final INanoServiceRegistry nanoServiceRegistry = mDependencies.getNanoServiceRegistry(); nanoServiceRegistry.addObserver(CRecordNotifyRemoteNodeAdded.class, getAddress(), false); aEnvelope.setResultSuccess(); return true; }
The disadvantage here is if you want to register multiple observers in different namespaces. You would then also have to enter multiple dependencies in the ServiceStarter and the Dependencies interface. However, this rarely happens.
Other ways
You could also enter dependencies to the respective namespaces. From the namespaces you get to the nano service registries, and there you can register the observers.
Or get the namespace registry, from the registry get the namespace, and from the namespace get the nano service registry.
Last but not least, you can use the namespace factory to have the namespace created only if it does not exist. Otherwise, the factory returns the existing namespace. And via the namespace we come back to the nano service registry.
Consume the messages
Add the message handler in the constructor:
addMessageHandler(CRecordNotifyRemoteNodeAdded.ID, this::asyncNotifyRemoteNodeAdded);
After that you can receive this message every time the notification is triggered.
private boolean asyncNotifyRemoteNodeAdded(@NotNull final CEnvelope aEnvelope, @NotNull final CRecord aRecord) throws CException { // do something aEnvelope.setResultSuccess(); return true; }