From 2e3a3246bf42e4c9ea7acaa78bc05fe593ccc77c Mon Sep 17 00:00:00 2001 From: moznion Date: Tue, 1 Dec 2020 01:09:30 +0900 Subject: [PATCH 1/7] #933: Add method: `onUnexpectedErrorOccurred()` for LwM2mClientObserver Add an interface method `void onUnexpectedErrorOccurred(Throwable unexpectedError)` into LwM2mClientObserver. This aims to hook a procedure when an unexpected error has been occurred. Signed-off-by: moznion --- .../eclipse/leshan/client/observer/LwM2mClientObserver.java | 4 ++++ .../leshan/client/observer/LwM2mClientObserverAdapter.java | 4 ++++ .../client/observer/LwM2mClientObserverDispatcher.java | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java index 0ff789f66a..0fbf8d9e1d 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java @@ -69,4 +69,8 @@ void onDeregistrationFailure(ServerIdentity server, DeregisterRequest request, R String errorMessage, Exception cause); void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request); + + // ============== Unexpected Error Handling ================= + + void onUnexpectedErrorOccurred(Throwable unexpectedError); } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java index 52fc10ba73..5c2d4fe0ed 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java @@ -95,4 +95,8 @@ public void onDeregistrationFailure(ServerIdentity server, DeregisterRequest req @Override public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { } + + @Override + public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + } } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java index 39002d13a7..462399699c 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java @@ -151,4 +151,10 @@ public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest req } } + @Override + public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + for (LwM2mClientObserver observer : observers) { + observer.onUnexpectedErrorOccurred(unexpectedError); + } + } } From 7e32bf56f6d9079f5025bbc2f2c87a21e63efd66 Mon Sep 17 00:00:00 2001 From: moznion Date: Tue, 1 Dec 2020 01:13:37 +0900 Subject: [PATCH 2/7] #933: Handle unexpected errors on `DefaultRegistrationEngine` Call `LwM2mClientObserver#onUnexpectedErrorOccurred()` on `DefaultRegistrationEngine` when it raises `RuntimeException` at task loop. Signed-off-by: moznion --- .../leshan/client/engine/DefaultRegistrationEngine.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java index 4c2bd3d25c..7d9f1d248b 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java @@ -526,6 +526,7 @@ public void run() { LOG.info("Bootstrap task interrupted. "); } catch (RuntimeException e) { LOG.error("Unexpected exception during bootstrap task", e); + observer.onUnexpectedErrorOccurred(e); } } } @@ -564,6 +565,7 @@ public void run() { LOG.info("Registration task interrupted. "); } catch (RuntimeException e) { LOG.error("Unexpected exception during registration task", e); + observer.onUnexpectedErrorOccurred(e); } } } @@ -612,6 +614,7 @@ public void run() { LOG.info("Registration update task interrupted."); } catch (RuntimeException e) { LOG.error("Unexpected exception during update registration task", e); + observer.onUnexpectedErrorOccurred(e); } } } From e3aad0d6026481aadebf763121feb35bc5d7ba0d Mon Sep 17 00:00:00 2001 From: moznion Date: Tue, 1 Dec 2020 01:49:20 +0900 Subject: [PATCH 3/7] #933: Add demo code to shutdown when an unexpected error has occurred Signed-off-by: moznion --- .../leshan/client/demo/LeshanClientDemo.java | 34 +++++++++++++++++-- .../eclipse/leshan/client/demo/MyDevice.java | 12 +++++-- .../client/demo/RandomTemperatureSensor.java | 8 ++++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java index a3c2061238..dac2583bb6 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java @@ -59,6 +59,7 @@ import org.eclipse.leshan.client.californium.LeshanClientBuilder; import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory; import org.eclipse.leshan.client.object.Server; +import org.eclipse.leshan.client.observer.LwM2mClientObserverAdapter; import org.eclipse.leshan.client.resource.LwM2mObjectEnabler; import org.eclipse.leshan.client.resource.ObjectsInitializer; import org.eclipse.leshan.client.resource.listener.ObjectsListenerAdapter; @@ -623,9 +624,11 @@ public static void createAndStartClient(String endpoint, String localAddress, in initializer.setInstancesForObject(SERVER, new Server(123, lifetime)); } } - initializer.setInstancesForObject(DEVICE, new MyDevice()); + final MyDevice myDevice = new MyDevice(); + final RandomTemperatureSensor randomTemperatureSensor = new RandomTemperatureSensor(); + initializer.setInstancesForObject(DEVICE, myDevice); initializer.setInstancesForObject(LOCATION, locationInstance); - initializer.setInstancesForObject(OBJECT_ID_TEMPERATURE_SENSOR, new RandomTemperatureSensor()); + initializer.setInstancesForObject(OBJECT_ID_TEMPERATURE_SENSOR, randomTemperatureSensor); List enablers = initializer.createAll(); // Create CoAP Config @@ -745,6 +748,9 @@ public void handshakeFailed(Handshaker handshaker, Throwable error) { builder.setBootstrapAdditionalAttributes(bsAdditionalAttributes); final LeshanClient client = builder.build(); + client.addObserver( + new ClientShutdownOnUnexpectedErrorObserver(client, myDevice, randomTemperatureSensor)); + client.getObjectTree().addListener(new ObjectsListenerAdapter() { @Override public void objectRemoved(LwM2mObjectEnabler object) { @@ -872,4 +878,28 @@ public void run() { } } } + + private static class ClientShutdownOnUnexpectedErrorObserver extends LwM2mClientObserverAdapter { + final LeshanClient client; + final MyDevice myDevice; + final RandomTemperatureSensor randomTemperatureSensor; + + public ClientShutdownOnUnexpectedErrorObserver( + final LeshanClient client, + final MyDevice myDevice, + final RandomTemperatureSensor randomTemperatureSensor + ) { + this.client = client; + this.myDevice = myDevice; + this.randomTemperatureSensor = randomTemperatureSensor; + } + + @Override + public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + LOG.error("unexpected error occurred", unexpectedError); + client.destroy(true); + myDevice.destroy(); + randomTemperatureSensor.destroy(); + } + } } diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/MyDevice.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/MyDevice.java index 207649d7a8..a51c5219fc 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/MyDevice.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/MyDevice.java @@ -14,6 +14,7 @@ import org.eclipse.leshan.client.resource.BaseInstanceEnabler; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ResourceModel.Type; import org.eclipse.leshan.core.node.LwM2mResource; @@ -23,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class MyDevice extends BaseInstanceEnabler { +public class MyDevice extends BaseInstanceEnabler implements Destroyable { private static final Logger LOG = LoggerFactory.getLogger(MyDevice.class); @@ -31,9 +32,11 @@ public class MyDevice extends BaseInstanceEnabler { private static final List supportedResources = Arrays.asList(0, 1, 2, 3, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21); + private final Timer timer; + public MyDevice() { // notify new date each 5 second - Timer timer = new Timer("Device-Current Time"); + this.timer = new Timer("Device-Current Time"); timer.schedule(new TimerTask() { @Override public void run() { @@ -210,4 +213,9 @@ private long getMemoryTotal() { public List getAvailableResourceIds(ObjectModel model) { return supportedResources; } + + @Override + public void destroy() { + timer.cancel(); + } } diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/RandomTemperatureSensor.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/RandomTemperatureSensor.java index 7719a55f53..8a1fa3f565 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/RandomTemperatureSensor.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/RandomTemperatureSensor.java @@ -11,6 +11,7 @@ import org.eclipse.leshan.client.resource.BaseInstanceEnabler; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.response.ExecuteResponse; import org.eclipse.leshan.core.response.ReadResponse; @@ -18,7 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RandomTemperatureSensor extends BaseInstanceEnabler { +public class RandomTemperatureSensor extends BaseInstanceEnabler implements Destroyable { private static final Logger LOG = LoggerFactory.getLogger(RandomTemperatureSensor.class); @@ -113,4 +114,9 @@ private void resetMinMaxMeasuredValues() { public List getAvailableResourceIds(ObjectModel model) { return supportedResources; } + + @Override + public void destroy() { + scheduler.shutdown(); + } } From 16c6cb758d004ad732dda864438b8c08815c9791 Mon Sep 17 00:00:00 2001 From: moznion Date: Thu, 3 Dec 2020 22:34:16 +0900 Subject: [PATCH 4/7] #933: Rename: s/onUnexpectedErrorOccurred/onUnexpectedError/g Signed-off-by: moznion --- .../leshan/client/engine/DefaultRegistrationEngine.java | 6 +++--- .../eclipse/leshan/client/observer/LwM2mClientObserver.java | 2 +- .../leshan/client/observer/LwM2mClientObserverAdapter.java | 2 +- .../client/observer/LwM2mClientObserverDispatcher.java | 4 ++-- .../org/eclipse/leshan/client/demo/LeshanClientDemo.java | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java index 7d9f1d248b..b039ef5fde 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java @@ -526,7 +526,7 @@ public void run() { LOG.info("Bootstrap task interrupted. "); } catch (RuntimeException e) { LOG.error("Unexpected exception during bootstrap task", e); - observer.onUnexpectedErrorOccurred(e); + observer.onUnexpectedError(e); } } } @@ -565,7 +565,7 @@ public void run() { LOG.info("Registration task interrupted. "); } catch (RuntimeException e) { LOG.error("Unexpected exception during registration task", e); - observer.onUnexpectedErrorOccurred(e); + observer.onUnexpectedError(e); } } } @@ -614,7 +614,7 @@ public void run() { LOG.info("Registration update task interrupted."); } catch (RuntimeException e) { LOG.error("Unexpected exception during update registration task", e); - observer.onUnexpectedErrorOccurred(e); + observer.onUnexpectedError(e); } } } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java index 0fbf8d9e1d..91b8ce386f 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserver.java @@ -72,5 +72,5 @@ void onDeregistrationFailure(ServerIdentity server, DeregisterRequest request, R // ============== Unexpected Error Handling ================= - void onUnexpectedErrorOccurred(Throwable unexpectedError); + void onUnexpectedError(Throwable unexpectedError); } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java index 5c2d4fe0ed..37eb52aa2e 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverAdapter.java @@ -97,6 +97,6 @@ public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest req } @Override - public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + public void onUnexpectedError(Throwable unexpectedError) { } } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java index 462399699c..e2e26659a9 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/observer/LwM2mClientObserverDispatcher.java @@ -152,9 +152,9 @@ public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest req } @Override - public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + public void onUnexpectedError(Throwable unexpectedError) { for (LwM2mClientObserver observer : observers) { - observer.onUnexpectedErrorOccurred(unexpectedError); + observer.onUnexpectedError(unexpectedError); } } } diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java index dac2583bb6..4bb5b38ef7 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java @@ -895,7 +895,7 @@ public ClientShutdownOnUnexpectedErrorObserver( } @Override - public void onUnexpectedErrorOccurred(Throwable unexpectedError) { + public void onUnexpectedError(Throwable unexpectedError) { LOG.error("unexpected error occurred", unexpectedError); client.destroy(true); myDevice.destroy(); From 3f730203ab3c01908d2a41566c5e4c18af40d274 Mon Sep 17 00:00:00 2001 From: moznion Date: Fri, 4 Dec 2020 00:11:20 +0900 Subject: [PATCH 5/7] #933: Implement Destroyable, Startable and Stoppable on ObjectEnabler To call `LwM2mInstanceEnabler#stop()`, `LwM2mInstanceEnabler#start()` and `LwM2mInstanceEnabler#destroy()` on the associated method, for each enabler if implemented the interface. Signed-off-by: moznion --- .../client/resource/LwM2mInstanceEnabler.java | 9 +++++ .../leshan/client/resource/ObjectEnabler.java | 34 ++++++++++++++++++- .../leshan/client/demo/LeshanClientDemo.java | 23 +++---------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java index 63f665a28b..d9d3dbd9d4 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java @@ -22,6 +22,9 @@ import org.eclipse.leshan.client.LwM2mClient; 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.node.LwM2mObjectInstance; import org.eclipse.leshan.core.node.LwM2mResource; @@ -45,6 +48,12 @@ *

* Implementations of this interface should adhere to the definition of the implemented LWM2M Object type regarding * acceptable resource IDs for the read, write and execute methods. + * An instance that implements this interface synchronizes with the lifecycle of the LeshanClient. This means when + *

+ * {@code LeshanClient#destroy()} is called, {@code LwM2mInstanceEnabler#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 LwM2mInstanceEnabler { diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java index 615a75ed36..71a5b7866f 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java @@ -28,7 +28,10 @@ import org.eclipse.leshan.client.LwM2mClient; import org.eclipse.leshan.client.servers.ServerIdentity; import org.eclipse.leshan.client.servers.ServersInfoExtractor; +import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.LwM2mId; +import org.eclipse.leshan.core.Startable; +import org.eclipse.leshan.core.Stoppable; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.node.LwM2mObject; import org.eclipse.leshan.core.node.LwM2mObjectInstance; @@ -62,7 +65,7 @@ * Implementing a {@link LwM2mInstanceEnabler} then creating an {@link ObjectEnabler} with {@link ObjectsInitializer} is * the easier way to implement LWM2M object in Leshan client. */ -public class ObjectEnabler extends BaseObjectEnabler { +public class ObjectEnabler extends BaseObjectEnabler implements Destroyable, Startable, Stoppable{ protected Map instances; protected LwM2mInstanceEnablerFactory instanceFactory; @@ -411,4 +414,33 @@ public void setLwM2mClient(LwM2mClient client) { instanceEnabler.setLwM2mClient(client); } } + + @Override + public void destroy() { + for (LwM2mInstanceEnabler instanceEnabler : instances.values()) { + if (instanceEnabler instanceof Destroyable) { + ((Destroyable) instanceEnabler).destroy(); + } else if (instanceEnabler instanceof Stoppable) { + ((Stoppable) instanceEnabler).stop(); + } + } + } + + @Override + public void start() { + for (LwM2mInstanceEnabler instanceEnabler : instances.values()) { + if (instanceEnabler instanceof Startable) { + ((Startable) instanceEnabler).start(); + } + } + } + + @Override + public void stop() { + for (LwM2mInstanceEnabler instanceEnabler : instances.values()) { + if (instanceEnabler instanceof Stoppable) { + ((Stoppable) instanceEnabler).stop(); + } + } + } } diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java index 4bb5b38ef7..99430544e1 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java @@ -624,11 +624,9 @@ public static void createAndStartClient(String endpoint, String localAddress, in initializer.setInstancesForObject(SERVER, new Server(123, lifetime)); } } - final MyDevice myDevice = new MyDevice(); - final RandomTemperatureSensor randomTemperatureSensor = new RandomTemperatureSensor(); - initializer.setInstancesForObject(DEVICE, myDevice); + initializer.setInstancesForObject(DEVICE, new MyDevice()); initializer.setInstancesForObject(LOCATION, locationInstance); - initializer.setInstancesForObject(OBJECT_ID_TEMPERATURE_SENSOR, randomTemperatureSensor); + initializer.setInstancesForObject(OBJECT_ID_TEMPERATURE_SENSOR, new RandomTemperatureSensor()); List enablers = initializer.createAll(); // Create CoAP Config @@ -748,8 +746,7 @@ public void handshakeFailed(Handshaker handshaker, Throwable error) { builder.setBootstrapAdditionalAttributes(bsAdditionalAttributes); final LeshanClient client = builder.build(); - client.addObserver( - new ClientShutdownOnUnexpectedErrorObserver(client, myDevice, randomTemperatureSensor)); + client.addObserver(new ClientShutdownOnUnexpectedErrorObserver(client)); client.getObjectTree().addListener(new ObjectsListenerAdapter() { @Override @@ -881,25 +878,15 @@ public void run() { private static class ClientShutdownOnUnexpectedErrorObserver extends LwM2mClientObserverAdapter { final LeshanClient client; - final MyDevice myDevice; - final RandomTemperatureSensor randomTemperatureSensor; - - public ClientShutdownOnUnexpectedErrorObserver( - final LeshanClient client, - final MyDevice myDevice, - final RandomTemperatureSensor randomTemperatureSensor - ) { + + public ClientShutdownOnUnexpectedErrorObserver(final LeshanClient client) { this.client = client; - this.myDevice = myDevice; - this.randomTemperatureSensor = randomTemperatureSensor; } @Override public void onUnexpectedError(Throwable unexpectedError) { LOG.error("unexpected error occurred", unexpectedError); client.destroy(true); - myDevice.destroy(); - randomTemperatureSensor.destroy(); } } } From 7e6d029ffc7fa24128f292b50fb2ce2f3a56412f Mon Sep 17 00:00:00 2001 From: moznion Date: Fri, 4 Dec 2020 00:34:51 +0900 Subject: [PATCH 6/7] #933: register ShutdownOnUnexpectedErrorObserver for LeshanClient Instead of on `LeshanClientDemo` Signed-off-by: moznion --- .../client/californium/LeshanClient.java | 19 +++++++++++++++++++ .../leshan/client/demo/LeshanClientDemo.java | 16 ---------------- 2 files changed, 19 insertions(+), 16 deletions(-) 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 cea86a1baf..508517cad6 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 @@ -38,6 +38,7 @@ import org.eclipse.leshan.client.engine.RegistrationEngine; import org.eclipse.leshan.client.engine.RegistrationEngineFactory; import org.eclipse.leshan.client.observer.LwM2mClientObserver; +import org.eclipse.leshan.client.observer.LwM2mClientObserverAdapter; import org.eclipse.leshan.client.observer.LwM2mClientObserverDispatcher; import org.eclipse.leshan.client.resource.LwM2mObjectEnabler; import org.eclipse.leshan.client.resource.LwM2mObjectTree; @@ -115,6 +116,9 @@ public LeshanClient(String endpoint, InetSocketAddress localAddress, createRegistrationUpdateHandler(engine, endpointsManager, bootstrapHandler, objectTree); coapApi = new CoapAPI(); + + // register the shutdown observer for when the unexpected error occurred. + addObserver(new ShutdownOnUnexpectedErrorObserver(this)); } protected LwM2mObjectTree createObjectTree(List objectEnablers) { @@ -320,4 +324,19 @@ public Map getRegisteredServers() { public InetSocketAddress getAddress(ServerIdentity server) { return endpointsManager.getEndpoint(server).getAddress(); } + + private static class ShutdownOnUnexpectedErrorObserver extends + LwM2mClientObserverAdapter { + final LeshanClient client; + + public ShutdownOnUnexpectedErrorObserver(final LeshanClient client) { + this.client = client; + } + + @Override + public void onUnexpectedError(Throwable unexpectedError) { + LOG.error("unexpected error occurred. destroy the leshan-client", unexpectedError); + client.destroy(true); + } + } } diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java index 99430544e1..b6e3b9116c 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java @@ -746,8 +746,6 @@ public void handshakeFailed(Handshaker handshaker, Throwable error) { builder.setBootstrapAdditionalAttributes(bsAdditionalAttributes); final LeshanClient client = builder.build(); - client.addObserver(new ClientShutdownOnUnexpectedErrorObserver(client)); - client.getObjectTree().addListener(new ObjectsListenerAdapter() { @Override public void objectRemoved(LwM2mObjectEnabler object) { @@ -875,18 +873,4 @@ public void run() { } } } - - private static class ClientShutdownOnUnexpectedErrorObserver extends LwM2mClientObserverAdapter { - final LeshanClient client; - - public ClientShutdownOnUnexpectedErrorObserver(final LeshanClient client) { - this.client = client; - } - - @Override - public void onUnexpectedError(Throwable unexpectedError) { - LOG.error("unexpected error occurred", unexpectedError); - client.destroy(true); - } - } } From b4a89c9b69cdb9d08f60c649ac75fdbabc5cf83a Mon Sep 17 00:00:00 2001 From: moznion Date: Fri, 4 Dec 2020 00:49:27 +0900 Subject: [PATCH 7/7] #933: format code Signed-off-by: moznion --- .../org/eclipse/leshan/client/californium/LeshanClient.java | 3 +-- .../java/org/eclipse/leshan/client/resource/ObjectEnabler.java | 2 +- .../java/org/eclipse/leshan/client/demo/LeshanClientDemo.java | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) 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 508517cad6..aa6cc5c7f4 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 @@ -325,8 +325,7 @@ public InetSocketAddress getAddress(ServerIdentity server) { return endpointsManager.getEndpoint(server).getAddress(); } - private static class ShutdownOnUnexpectedErrorObserver extends - LwM2mClientObserverAdapter { + private static class ShutdownOnUnexpectedErrorObserver extends LwM2mClientObserverAdapter { final LeshanClient client; public ShutdownOnUnexpectedErrorObserver(final LeshanClient client) { diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java index 71a5b7866f..437d97b52c 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java @@ -65,7 +65,7 @@ * Implementing a {@link LwM2mInstanceEnabler} then creating an {@link ObjectEnabler} with {@link ObjectsInitializer} is * the easier way to implement LWM2M object in Leshan client. */ -public class ObjectEnabler extends BaseObjectEnabler implements Destroyable, Startable, Stoppable{ +public class ObjectEnabler extends BaseObjectEnabler implements Destroyable, Startable, Stoppable { protected Map instances; protected LwM2mInstanceEnablerFactory instanceFactory; diff --git a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java index b6e3b9116c..a3c2061238 100644 --- a/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java +++ b/leshan-client-demo/src/main/java/org/eclipse/leshan/client/demo/LeshanClientDemo.java @@ -59,7 +59,6 @@ import org.eclipse.leshan.client.californium.LeshanClientBuilder; import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory; import org.eclipse.leshan.client.object.Server; -import org.eclipse.leshan.client.observer.LwM2mClientObserverAdapter; import org.eclipse.leshan.client.resource.LwM2mObjectEnabler; import org.eclipse.leshan.client.resource.ObjectsInitializer; import org.eclipse.leshan.client.resource.listener.ObjectsListenerAdapter;