diff --git a/leshan-bsserver-demo/src/main/java/org/eclipse/leshan/server/bootstrap/demo/LeshanBootstrapServerDemo.java b/leshan-bsserver-demo/src/main/java/org/eclipse/leshan/server/bootstrap/demo/LeshanBootstrapServerDemo.java index e36bf88e0f..58076931e8 100755 --- a/leshan-bsserver-demo/src/main/java/org/eclipse/leshan/server/bootstrap/demo/LeshanBootstrapServerDemo.java +++ b/leshan-bsserver-demo/src/main/java/org/eclipse/leshan/server/bootstrap/demo/LeshanBootstrapServerDemo.java @@ -199,7 +199,7 @@ public static LeshanBootstrapServer createBsLeshanServer(LeshanBsServerDemoCLI c endpointsBuilder.addEndpoint(coapsAddr, Protocol.COAPS); // Create LWM2M server - builder.setEndpointsProvider(endpointsBuilder.build()); + builder.setEndpointsProviders(endpointsBuilder.build()); return builder.build(); } diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerBuilderTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerBuilderTest.java index c5a33556f6..d70be2fd24 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerBuilderTest.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerBuilderTest.java @@ -104,7 +104,7 @@ public BootstrapConfig get(BootstrapSession session) { @Test public void create_server_with_default_californiumEndpointsProvider() { - builder.setEndpointsProvider(new CaliforniumBootstrapServerEndpointsProvider()); + builder.setEndpointsProviders(new CaliforniumBootstrapServerEndpointsProvider()); server = builder.build(); assertEquals(1, server.getEndpoints().size()); @@ -115,7 +115,7 @@ public void create_server_with_default_californiumEndpointsProvider() { public void create_server_without_securityStore() { Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder( new CoapBootstrapServerProtocolProvider(), new CoapsBootstrapServerProtocolProvider()); - builder.setEndpointsProvider(endpointsBuilder.build()); + builder.setEndpointsProviders(endpointsBuilder.build()); server = builder.build(); assertEquals(1, server.getEndpoints().size()); @@ -127,7 +127,7 @@ public void create_server_without_securityStore() { public void create_server_with_securityStore() { Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder( new CoapBootstrapServerProtocolProvider(), new CoapsBootstrapServerProtocolProvider()); - builder.setEndpointsProvider(endpointsBuilder.build()); + builder.setEndpointsProviders(endpointsBuilder.build()); builder.setSecurityStore(new BootstrapSecurityStore() { @Override public SecurityInfo getByIdentity(String pskIdentity) { @@ -156,7 +156,7 @@ public SecurityInfo getByOscoreIdentity(OscoreIdentity oscoreIdentity) { public void create_server_with_coaps_only() { Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder( new CoapsBootstrapServerProtocolProvider()); - builder.setEndpointsProvider(endpointsBuilder.build()); + builder.setEndpointsProviders(endpointsBuilder.build()); builder.setSecurityStore(new BootstrapSecurityStore() { @Override public SecurityInfo getByIdentity(String pskIdentity) { @@ -187,7 +187,7 @@ public void create_server_without_psk_cipher() { endpointsBuilder.setConfiguration(c -> { c.setAsList(DtlsConfig.DTLS_CIPHER_SUITES, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); }); - builder.setEndpointsProvider(endpointsBuilder.build()); + builder.setEndpointsProviders(endpointsBuilder.build()); builder.setPrivateKey(privateKey); builder.setPublicKey(publicKey); diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerTest.java index b6c4412f8b..7d1b7616a3 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerTest.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/bootstrap/LeshanBootstrapServerTest.java @@ -63,7 +63,7 @@ public BootstrapConfig get(BootstrapSession session) { return config; } }); - builder.setEndpointsProvider(new CaliforniumBootstrapServerEndpointsProvider()); + builder.setEndpointsProviders(new CaliforniumBootstrapServerEndpointsProvider()); return builder.build(); } diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServer.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServer.java index 82377a998e..f451842a12 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServer.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServer.java @@ -16,8 +16,8 @@ *******************************************************************************/ package org.eclipse.leshan.server.bootstrap; -import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.eclipse.leshan.core.Destroyable; @@ -29,11 +29,13 @@ import org.eclipse.leshan.core.node.codec.LwM2mEncoder; import org.eclipse.leshan.core.util.Validate; import org.eclipse.leshan.server.bootstrap.endpoint.BootstrapServerEndpointToolbox; +import org.eclipse.leshan.server.bootstrap.endpoint.CompositeBootstrapServerEndpointsProvider; import org.eclipse.leshan.server.bootstrap.endpoint.LwM2mBootstrapServerEndpoint; import org.eclipse.leshan.server.bootstrap.endpoint.LwM2mBootstrapServerEndpointsProvider; import org.eclipse.leshan.server.bootstrap.request.BootstrapDownlinkRequestSender; import org.eclipse.leshan.server.bootstrap.request.DefaultBootstrapDownlinkRequestSender; import org.eclipse.leshan.server.bootstrap.request.DefaultBootstrapUplinkRequestReceiver; +import org.eclipse.leshan.server.endpoint.CompositeServerEndpointsProvider; import org.eclipse.leshan.server.security.BootstrapSecurityStore; import org.eclipse.leshan.server.security.ServerSecurityInfo; import org.slf4j.Logger; @@ -148,9 +150,10 @@ public List getEndpoints() { } public Collection getEndpointsProvider() { - // TODO current we support only 1 endpoints provider but we will add support for multiple endpoints provider - // soon - return Arrays.asList(endpointsProvider); + if (endpointsProvider instanceof CompositeServerEndpointsProvider) { + return ((CompositeBootstrapServerEndpointsProvider) endpointsProvider).getProviders(); + } + return Collections.singleton(endpointsProvider); } public LwM2mBootstrapServerEndpoint getEndpoint(Protocol protocol) { diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServerBuilder.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServerBuilder.java index d659ba90ed..0fca22bfb2 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServerBuilder.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LeshanBootstrapServerBuilder.java @@ -21,6 +21,8 @@ import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; import org.eclipse.leshan.core.link.lwm2m.DefaultLwM2mLinkParser; import org.eclipse.leshan.core.link.lwm2m.LwM2mLinkParser; @@ -29,6 +31,7 @@ import org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder; import org.eclipse.leshan.core.node.codec.LwM2mDecoder; import org.eclipse.leshan.core.node.codec.LwM2mEncoder; +import org.eclipse.leshan.server.bootstrap.endpoint.DefaultCompositeBootstrapServerEndpointsProvider; import org.eclipse.leshan.server.bootstrap.endpoint.LwM2mBootstrapServerEndpointsProvider; import org.eclipse.leshan.server.bootstrap.request.BootstrapDownlinkRequestSender; import org.eclipse.leshan.server.model.LwM2mBootstrapModelProvider; @@ -255,8 +258,31 @@ public LeshanBootstrapServerBuilder setAuthorizer(BootstrapAuthorizer authorizer return this; } - public LeshanBootstrapServerBuilder setEndpointsProvider(LwM2mBootstrapServerEndpointsProvider endpointsProvider) { - this.endpointsProvider = endpointsProvider; + /** + * By default LeshanBootstrapServer doesn't support any protocol. Users need to provide 1 or several + * {@link LwM2mBootstrapServerEndpointsProvider} implementation. + *

+ * Leshan project provides {@code coap} and {@code coaps} support based on Californium/Scandium in + * leshan-server-cf. + */ + public LeshanBootstrapServerBuilder setEndpointsProviders( + LwM2mBootstrapServerEndpointsProvider... endpointsProvider) { + return setEndpointsProviders(Arrays.asList(endpointsProvider)); + } + + /** + * @see #setEndpointsProviders(LwM2mBootstrapServerEndpointsProvider...) + */ + public LeshanBootstrapServerBuilder setEndpointsProviders( + Collection providers) { + if (providers == null || providers.isEmpty()) { + throw new IllegalStateException("At least one endpoint provider should be set"); + } + if (providers.size() == 1) { + this.endpointsProvider = providers.iterator().next(); + } else { + this.endpointsProvider = new DefaultCompositeBootstrapServerEndpointsProvider(providers); + } return this; } diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/CompositeBootstrapServerEndpointsProvider.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/CompositeBootstrapServerEndpointsProvider.java new file mode 100644 index 0000000000..35926b4621 --- /dev/null +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/CompositeBootstrapServerEndpointsProvider.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.server.bootstrap.endpoint; + +import java.util.Collection; + +import org.eclipse.leshan.server.endpoint.LwM2mServerEndpointsProvider; + +/** + * A {@link LwM2mBootstrapServerEndpointsProvider} composed of several internal + * {@link LwM2mBootstrapServerEndpointsProvider}. + *

+ * Implementation should allow to use several {@link LwM2mBootstrapServerEndpointsProvider}. + * + * @see DefaultCompositeBootstrapServerEndpointsProvider + */ +public interface CompositeBootstrapServerEndpointsProvider extends LwM2mBootstrapServerEndpointsProvider { + + /** + * @return all internal {@link LwM2mServerEndpointsProvider}. + */ + Collection getProviders(); +} diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/DefaultCompositeBootstrapServerEndpointsProvider.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/DefaultCompositeBootstrapServerEndpointsProvider.java new file mode 100644 index 0000000000..7257a8f17b --- /dev/null +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/endpoint/DefaultCompositeBootstrapServerEndpointsProvider.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * 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.server.bootstrap.endpoint; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.leshan.core.util.Validate; +import org.eclipse.leshan.server.bootstrap.LeshanBootstrapServer; +import org.eclipse.leshan.server.bootstrap.request.BootstrapUplinkRequestReceiver; +import org.eclipse.leshan.server.security.ServerSecurityInfo; + +/** + * Default implementation of {@link CompositeBootstrapServerEndpointsProvider}. + *

+ * It allows to use several {@link LwM2mBootstrapServerEndpointsProvider} on same Leshan server. + */ +public class DefaultCompositeBootstrapServerEndpointsProvider implements CompositeBootstrapServerEndpointsProvider { + + private final List providers; + + public DefaultCompositeBootstrapServerEndpointsProvider(LwM2mBootstrapServerEndpointsProvider... providers) { + this(Arrays.asList(providers)); + } + + public DefaultCompositeBootstrapServerEndpointsProvider( + Collection providers) { + Validate.notEmpty(providers); + this.providers = Collections.unmodifiableList(new ArrayList<>(providers)); + } + + @Override + public List getEndpoints() { + List endpoints = new ArrayList<>(); + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + endpoints.addAll(provider.getEndpoints()); + } + return endpoints; + } + + @Override + public LwM2mBootstrapServerEndpoint getEndpoint(URI uri) { + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + LwM2mBootstrapServerEndpoint endpoint = provider.getEndpoint(uri); + if (endpoint != null) { + return endpoint; + } + } + return null; + } + + @Override + public void createEndpoints(BootstrapUplinkRequestReceiver requestReceiver, BootstrapServerEndpointToolbox toolbox, + ServerSecurityInfo serverSecurityInfo, LeshanBootstrapServer server) { + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + provider.createEndpoints(requestReceiver, toolbox, serverSecurityInfo, server); + } + } + + @Override + public void start() { + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + provider.start(); + } + } + + @Override + public void stop() { + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + provider.stop(); + } + } + + @Override + public void destroy() { + for (LwM2mBootstrapServerEndpointsProvider provider : providers) { + provider.destroy(); + } + } + + @Override + public Collection getProviders() { + return providers; + } +}