diff --git a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/CaliforniumClientEndpointsProvider.java b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/CaliforniumClientEndpointsProvider.java
index 2dac882fd4..1be948c179 100644
--- a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/CaliforniumClientEndpointsProvider.java
+++ b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/CaliforniumClientEndpointsProvider.java
@@ -261,7 +261,7 @@ public CoapServer getCoapServer() {
@Override
public LwM2mClientEndpoint getEndpoint(LwM2mServer server) {
- if (currentServer.equals(server)) {
+ if (currentServer != null && currentServer.equals(server)) {
return endpoint;
}
return null;
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java
index 7c01f5df6f..c3d49f78ef 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java
@@ -19,6 +19,7 @@
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,7 @@
import org.eclipse.leshan.client.bootstrap.BootstrapConsistencyChecker;
import org.eclipse.leshan.client.bootstrap.DefaultBootstrapConsistencyChecker;
+import org.eclipse.leshan.client.endpoint.DefaultCompositeClientEndpointsProvider;
import org.eclipse.leshan.client.endpoint.LwM2mClientEndpointsProvider;
import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory;
import org.eclipse.leshan.client.engine.RegistrationEngine;
@@ -266,10 +268,28 @@ public LeshanClientBuilder setSharedExecutor(ScheduledExecutorService executor)
}
/**
- * @return the builder for fluent client creation.
+ * By default LeshanClient doesn't support any protocol. Users need to provide 1 or several
+ * {@link LwM2mClientEndpointsProvider} implementation.
+ *
+ * Leshan project provides {@code coap} and {@code coaps} support based on Californium/Scandium in
+ * leshan-client-cf.
+ */
+ public LeshanClientBuilder setEndpointsProviders(LwM2mClientEndpointsProvider... endpointsProvider) {
+ return setEndpointsProviders(Arrays.asList(endpointsProvider));
+ }
+
+ /**
+ * @see #setEndpointsProviders(LwM2mClientEndpointsProvider...)
*/
- public LeshanClientBuilder setEndpointsProvider(LwM2mClientEndpointsProvider endpointsProvider) {
- this.endpointsProvider = endpointsProvider;
+ public LeshanClientBuilder setEndpointsProviders(Collection providers) {
+ if (providers == null || providers.isEmpty()) {
+ throw new IllegalStateException("At least one endpoint provider should be set");
+ }
+ if (providers.size() == 1) {
+ endpointsProvider = providers.iterator().next();
+ } else {
+ endpointsProvider = new DefaultCompositeClientEndpointsProvider(providers);
+ }
return this;
}
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/CompositeClientEndpointsProvider.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/CompositeClientEndpointsProvider.java
new file mode 100644
index 0000000000..dd9d1e742c
--- /dev/null
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/CompositeClientEndpointsProvider.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Sierra Wireless and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.html.
+ *
+ * Contributors:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.leshan.client.endpoint;
+
+import java.util.Collection;
+
+/**
+ * A {@link LwM2mClientEndpointsProvider} composed of several internal {@link LwM2mClientEndpointsProvider}.
+ *
+ * Implementation should allow to use several {@link LwM2mClientEndpointsProvider}.
+ *
+ * @see DefaultCompositeClientEndpointsProvider
+ */
+public interface CompositeClientEndpointsProvider extends LwM2mClientEndpointsProvider {
+ Collection getProviders();
+}
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/DefaultCompositeClientEndpointsProvider.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/DefaultCompositeClientEndpointsProvider.java
new file mode 100644
index 0000000000..64e8192e12
--- /dev/null
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/endpoint/DefaultCompositeClientEndpointsProvider.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Sierra Wireless and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.html.
+ *
+ * Contributors:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.leshan.client.endpoint;
+
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.leshan.client.request.DownlinkRequestReceiver;
+import org.eclipse.leshan.client.resource.LwM2mObjectTree;
+import org.eclipse.leshan.client.servers.LwM2mServer;
+import org.eclipse.leshan.client.servers.ServerInfo;
+
+/**
+ * Default implementation of {@link CompositeClientEndpointsProvider}.
+ *
+ * It allows to use several {@link LwM2mClientEndpointsProvider} on same Leshan server.
+ */
+public class DefaultCompositeClientEndpointsProvider implements CompositeClientEndpointsProvider {
+
+ private final List providers;
+
+ public DefaultCompositeClientEndpointsProvider(LwM2mClientEndpointsProvider... providers) {
+ this(Arrays.asList(providers));
+ }
+
+ public DefaultCompositeClientEndpointsProvider(Collection providers) {
+ this.providers = Collections.unmodifiableList(new ArrayList<>(providers));
+ }
+
+ @Override
+ public void init(LwM2mObjectTree objectTree, DownlinkRequestReceiver requestReceiver,
+ ClientEndpointToolbox toolbox) {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ provider.init(objectTree, requestReceiver, toolbox);
+ }
+ }
+
+ @Override
+ public LwM2mServer createEndpoint(ServerInfo serverInfo, boolean clientInitiatedOnly, List trustStore,
+ ClientEndpointToolbox toolbox) {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ LwM2mServer server = provider.createEndpoint(serverInfo, clientInitiatedOnly, trustStore, toolbox);
+ if (server != null) {
+ return server;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Collection createEndpoints(Collection extends ServerInfo> serverInfo,
+ boolean clientInitiatedOnly, List trustStore, ClientEndpointToolbox toolbox) {
+ // not implemented yet ...
+ return null;
+ }
+
+ @Override
+ public void destroyEndpoints() {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ provider.destroyEndpoints();
+ }
+ }
+
+ @Override
+ public void start() {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ provider.start();
+ }
+ }
+
+ @Override
+ public List getEndpoints() {
+ List endpoints = new ArrayList<>();
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ endpoints.addAll(provider.getEndpoints());
+ }
+ return endpoints;
+ }
+
+ @Override
+ public LwM2mClientEndpoint getEndpoint(LwM2mServer server) {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ LwM2mClientEndpoint endpoint = provider.getEndpoint(server);
+ if (endpoint != null) {
+ return endpoint;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void stop() {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ provider.stop();
+ }
+
+ }
+
+ @Override
+ public void destroy() {
+ for (LwM2mClientEndpointsProvider provider : providers) {
+ provider.destroy();
+ }
+ }
+
+ @Override
+ public Collection getProviders() {
+ return providers;
+ }
+}
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 bcef53caeb..03045c1a60 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
@@ -291,7 +291,7 @@ protected DtlsConnectorConfig.Builder createRootDtlsConnectorConfigBuilder(
// Create client
LeshanClientBuilder builder = new LeshanClientBuilder(cli.main.endpoint);
builder.setObjects(enablers);
- builder.setEndpointsProvider(endpointsBuilder.build());
+ builder.setEndpointsProviders(endpointsBuilder.build());
builder.setDataSenders(new ManualDataSender());
if (cli.identity.isx509())
builder.setTrustStore(cli.identity.getX509().trustStore);
diff --git a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/ServerOnlySecurityTest.java b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/ServerOnlySecurityTest.java
index ad8d7926d3..8e64c8744b 100644
--- a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/ServerOnlySecurityTest.java
+++ b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/ServerOnlySecurityTest.java
@@ -147,7 +147,7 @@ protected Builder createEffectiveDtlsConnectorConfigBuilder(InetSocketAddress ad
};
CaliforniumClientEndpointsProvider endpointsProvider = new CaliforniumClientEndpointsProvider.Builder(
coapsProtocolProvider).build();
- givenClient.setEndpointsProvider(endpointsProvider);
+ givenClient.setEndpointsProviders(endpointsProvider);
}
@AfterEach
diff --git a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java
index aa04b0190b..1145ce3935 100644
--- a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java
+++ b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java
@@ -248,17 +248,17 @@ public static LeshanTestClientBuilder givenClient() {
}
public LeshanTestClientBuilder with(LwM2mClientEndpointsProvider endpointsProvider) {
- setEndpointsProvider(endpointsProvider);
+ setEndpointsProviders(endpointsProvider);
return this;
}
public LeshanTestClientBuilder with(String endpointProvider) {
if (endpointProvider.equals("Californium")) {
- setEndpointsProvider(
+ setEndpointsProviders(
new CaliforniumClientEndpointsProvider.Builder(getCaliforniumProtocolProvider(protocolToUse))
.build());
} else if (endpointProvider.equals("Californium-OSCORE")) {
- setEndpointsProvider(new CaliforniumClientEndpointsProvider.Builder(
+ setEndpointsProviders(new CaliforniumClientEndpointsProvider.Builder(
getCaliforniumProtocolProviderSupportingOscore(protocolToUse)).build());
}
return this;