diff --git a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/LeshanClient.java b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/LeshanClient.java index 1734d9b50b..cea86a1baf 100644 --- a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/LeshanClient.java +++ b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/LeshanClient.java @@ -90,8 +90,8 @@ public LeshanClient(String endpoint, InetSocketAddress localAddress, /** @since 2.0 */ public LeshanClient(String endpoint, InetSocketAddress localAddress, - List objectEnablers, NetworkConfig coapConfig, Builder dtlsConfigBuilder, List trustStore, - EndpointFactory endpointFactory, RegistrationEngineFactory engineFactory, + List objectEnablers, NetworkConfig coapConfig, Builder dtlsConfigBuilder, + List trustStore, EndpointFactory endpointFactory, RegistrationEngineFactory engineFactory, Map additionalAttributes, Map bsAdditionalAttributes, LwM2mNodeEncoder encoder, LwM2mNodeDecoder decoder, ScheduledExecutorService sharedExecutor) { @@ -102,7 +102,8 @@ public LeshanClient(String endpoint, InetSocketAddress localAddress, objectTree = createObjectTree(objectEnablers); observers = createClientObserverDispatcher(); bootstrapHandler = createBoostrapHandler(objectTree); - endpointsManager = createEndpointsManager(localAddress, coapConfig, dtlsConfigBuilder, trustStore, endpointFactory); + endpointsManager = createEndpointsManager(localAddress, coapConfig, dtlsConfigBuilder, trustStore, + endpointFactory); requestSender = createRequestSender(endpointsManager, sharedExecutor); engine = engineFactory.createRegistratioEngine(endpoint, objectTree, endpointsManager, requestSender, bootstrapHandler, observers, additionalAttributes, bsAdditionalAttributes, sharedExecutor); @@ -189,8 +190,10 @@ protected CoapResource createBootstrapResource(RegistrationEngine engine, Bootst } protected CaliforniumEndpointsManager createEndpointsManager(InetSocketAddress localAddress, - NetworkConfig coapConfig, Builder dtlsConfigBuilder, List trustStore, EndpointFactory endpointFactory) { - return new CaliforniumEndpointsManager(localAddress, coapConfig, dtlsConfigBuilder, trustStore, endpointFactory); + NetworkConfig coapConfig, Builder dtlsConfigBuilder, List trustStore, + EndpointFactory endpointFactory) { + return new CaliforniumEndpointsManager(localAddress, coapConfig, dtlsConfigBuilder, trustStore, + endpointFactory); } protected CaliforniumLwM2mRequestSender createRequestSender(CaliforniumEndpointsManager endpointsManager, @@ -211,6 +214,8 @@ public void start() { LOG.info("Starting Leshan client ..."); endpointsManager.start(); engine.start(); + objectTree.start(); + if (LOG.isInfoEnabled()) { LOG.info("Leshan client[endpoint:{}] started.", engine.getEndpoint()); } @@ -221,6 +226,8 @@ public void stop(boolean deregister) { LOG.info("Stopping Leshan Client ..."); engine.stop(deregister); endpointsManager.stop(); + objectTree.stop(); + LOG.info("Leshan client stopped."); } @@ -230,6 +237,8 @@ public void destroy(boolean deregister) { engine.destroy(deregister); endpointsManager.destroy(); requestSender.destroy(); + objectTree.destroy(); + LOG.info("Leshan client destroyed."); } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java index 20d190d74b..4143cca360 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java @@ -21,6 +21,9 @@ import org.eclipse.leshan.client.LwM2mClient; import org.eclipse.leshan.client.resource.listener.ObjectListener; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.Destroyable; +import org.eclipse.leshan.core.Startable; +import org.eclipse.leshan.core.Stoppable; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.request.BootstrapDeleteRequest; import org.eclipse.leshan.core.request.BootstrapDiscoverRequest; @@ -55,6 +58,12 @@ *

* In case you really need the flexibility of this interface you should consider to inherit from * {@link BaseObjectEnabler}. + *

+ * An instance that implements this interface synchronizes with the lifecycle of the LeshanClient. This means when + * {@code LeshanClient#destroy()} is called, {@code LwM2mObjectEnabler#destroy()} is also called if it implements the + * {@link Destroyable} interface. And {@link Startable} ({@code #start()}) and {@link Stoppable} ({@code #stop()}) are + * also same as this. If you need to restart the instance, please implement {@link Startable} with {@link Stoppable} + * together. */ public interface LwM2mObjectEnabler { diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java index e4ab4d1b56..71b22278cc 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java @@ -25,6 +25,9 @@ import org.eclipse.leshan.client.LwM2mClient; import org.eclipse.leshan.client.resource.listener.ObjectListener; import org.eclipse.leshan.client.resource.listener.ObjectsListener; +import org.eclipse.leshan.core.Destroyable; +import org.eclipse.leshan.core.Startable; +import org.eclipse.leshan.core.Stoppable; /** * The LWM2M Object Tree. @@ -32,7 +35,7 @@ * It contains all the {@link LwM2mObjectEnabler} which are the implementation of each LWM2M object supported by the * client. */ -public class LwM2mObjectTree { +public class LwM2mObjectTree implements Startable, Stoppable, Destroyable { protected ObjectListener dispatcher = new ObjectListenerDispatcher(); protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList<>(); @@ -94,6 +97,35 @@ public void removeObjectEnabler(int objectId) { } } + @Override + public void destroy() { + for (LwM2mObjectEnabler objectEnabler : objectEnablers.values()) { + if (objectEnabler instanceof Destroyable) { + ((Destroyable) objectEnabler).destroy(); + } else if (objectEnabler instanceof Stoppable) { + ((Stoppable) objectEnabler).stop(); + } + } + } + + @Override + public void start() { + for (LwM2mObjectEnabler objectEnabler : objectEnablers.values()) { + if (objectEnabler instanceof Startable) { + ((Startable) objectEnabler).start(); + } + } + } + + @Override + public void stop() { + for (LwM2mObjectEnabler objectEnabler : objectEnablers.values()) { + if (objectEnabler instanceof Stoppable) { + ((Stoppable) objectEnabler).stop(); + } + } + } + protected class ObjectListenerDispatcher implements ObjectListener { @Override public void objectInstancesAdded(LwM2mObjectEnabler object, int... instanceIds) {