Repository: eclipse/leshan
Pull request #1407 (2023-03-03 10:39:49)

Some API enhancement to create `CaliforniumServerEndpointsProvider`
This aims to implements #1395.

I know that names are very long and I know that Builder of Factory sounds a bit heavy ... :disappointed:  but didn't find better name for now. 

API can be changed again if we find better idea/naming/design !

----------------------------------------------------

**1st Improvement :** shortcut to set `Configuration` at `CaliforniumServerEndpointsProvider` level

This allow to avoid to first create  config then set it.  It looks like : 

```java
endpointsBuilder.setConfiguration(c -> {
          c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
          c.set(CoapConfig.ACK_TIMEOUT , 1, TimeUnit.SECONDS);
      });
```
instead of 
```java
Configuration c = endpointsBuilder.createDefaultConfiguration();
c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
endpointsBuilder.setConfiguration(c);
```
(this :point_up:  API is not removed)

----------------------------------------------------------
**2nd Improvement :** Builder to create Endpoint Factory 

This allow to customize the factory easily. 

```java
endpointsBuilder.addEndpoint(new CoapsServerEndpointFactoryBuilder() //
        .setURI(5784) //
        .setConfiguration(c -> c.set(CoapConfig.ACK_TIMEOUT  , 1, TimeUnit.SECONDS)) //
        .setLoggingTagPrefix("Custom Coaps") //
        .setDtlsConnectorConfig(c -> c.setSessionStore(new CustomSessionStore())) //
        .setCoapEndpointConfig(c -> c.setTokenGenerator(new CustomTokenGenerator())) //
        .build());
```

----------------------------------------------------------

**3rd Improvement :**  Being able to set `DtlsConnectorConfig` at Protocol Provider level 

This aims to solve : https://github.com/eclipse/leshan/issues/1383

```java
LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

CaliforniumServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumServerEndpointsProvider.Builder(
        // add CoAP protocol Provider
        new CoapServerProtocolProvider(),

        // add CoAPS protocol Provider.
        new CoapsServerProtocolProvider(dtlsConfigBuilder -> {
            dtlsConfigBuilder.setSessionStore(new CustomSessionStore());
        }));

serverBuilder.setEndpointsProvider(endpointsBuilder.build());
```

sbernard31: It's me OR there is serious Github Action issue those days.
Current "Code check : Started 4h 31s ago" ... and also issues faced at https://github.com/eclipse/leshan/pull/1404#issuecomment-1452044775 ... boring :expressionless: 
github-actions[bot]: :information_source: Some tips : 
 - Once you fix your issues locally, **do not create a new PR**, see [how to refine your PR](https://github.com/eclipse/leshan/wiki/How-to-contribute#refine-it).
 - See [How to contribute](https://github.com/eclipse/leshan/wiki/How-to-contribute) guide and some [Code & design guidelines](https://github.com/eclipse/leshan/wiki/Code-&-design-guidelines). 

If documentation or those automatic comments are not clear enough, please [create a new issue](https://github.com/eclipse/leshan/issues/new) to discus about how to enhance it.
<!-- Sticky Pull Request Commentbuildstatus -->
github-actions[bot]: :x: **Java Import are not sorted !** [(more details)](https://github.com/eclipse/leshan/actions/runs/4322609431)

Ensure your code build locally using: 
```
mvn clean install
```
Or just validate java import with : 
```
mvn impsort:check
```
You can sort Java import with : 
```
mvn impsort:sort
```
See also [How configure your IDE](https://github.com/eclipse/leshan/wiki/Code-&-design-guidelines#configure-your-ide).
<!-- Sticky Pull Request Commentsortimport -->

Patch:
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 20d5f110..e36bf88e 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
@@ -21,14 +21,12 @@ package org.eclipse.leshan.server.bootstrap.demo;
 import java.io.File;
 import java.io.PrintWriter;
 import java.net.InetSocketAddress;
-import java.net.URI;
 import java.security.cert.Certificate;
 import java.util.List;
 
 import org.eclipse.californium.core.config.CoapConfig;
 import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.scandium.config.DtlsConfig;
-import org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
@@ -45,12 +43,9 @@ import org.eclipse.leshan.server.bootstrap.demo.cli.LeshanBsServerDemoCLI;
 import org.eclipse.leshan.server.bootstrap.demo.servlet.BootstrapServlet;
 import org.eclipse.leshan.server.bootstrap.demo.servlet.EventServlet;
 import org.eclipse.leshan.server.bootstrap.demo.servlet.ServerServlet;
-import org.eclipse.leshan.server.californium.bootstrap.endpoint.BootstrapServerProtocolProvider;
-import org.eclipse.leshan.server.californium.bootstrap.endpoint.CaliforniumBootstrapServerEndpointFactory;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.CaliforniumBootstrapServerEndpointsProvider;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.coap.CoapBootstrapServerProtocolProvider;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.coap.CoapOscoreBootstrapServerEndpointFactory;
-import org.eclipse.leshan.server.californium.bootstrap.endpoint.coaps.CoapsBootstrapServerEndpointFactory;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.coaps.CoapsBootstrapServerProtocolProvider;
 import org.eclipse.leshan.server.core.demo.json.servlet.SecurityServlet;
 import org.eclipse.leshan.server.model.VersionedBootstrapModelProvider;
@@ -149,29 +144,18 @@ public class LeshanBootstrapServerDemo {
 
         // Create Californium Endpoints Provider:
         // ------------------
-        // Create Custom CoAPS protocol provider to add MDC logger :
-        BootstrapServerProtocolProvider coapsProtocolProvider = new CoapsBootstrapServerProtocolProvider() {
-            @Override
-            public CaliforniumBootstrapServerEndpointFactory createDefaultEndpointFactory(URI uri) {
-                return new CoapsBootstrapServerEndpointFactory(uri) {
-
-                    @Override
-                    protected Builder createDtlsConnectorConfigBuilder(Configuration configuration) {
-                        Builder dtlsConfigBuilder = super.createDtlsConnectorConfigBuilder(configuration);
-
-                        // Add MDC for connection logs
-                        if (cli.helpsOptions.getVerboseLevel() > 0)
-                            dtlsConfigBuilder.setConnectionListener(new PrincipalMdcConnectionListener());
-
-                        return dtlsConfigBuilder;
-                    }
-                };
-            }
-        };
-
         // Create Bootstrap Server Endpoints Provider
         CaliforniumBootstrapServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder(
-                new CoapBootstrapServerProtocolProvider(), coapsProtocolProvider);
+                // Add coap Protocol support
+                new CoapBootstrapServerProtocolProvider(),
+
+                // Add coaps protocol support
+                new CoapsBootstrapServerProtocolProvider(c -> {
+                    // Add MDC for connection logs
+                    if (cli.helpsOptions.getVerboseLevel() > 0)
+                        c.setConnectionListener(new PrincipalMdcConnectionListener());
+
+                }));
 
         // Create Californium Configuration
         Configuration serverCoapConfig = endpointsBuilder.createDefaultConfiguration();
diff --git a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coap/CoapClientEndpointFactory.java b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coap/CoapClientEndpointFactory.java
index aa1f2851..d3f1411a 100644
--- a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coap/CoapClientEndpointFactory.java
+++ b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coap/CoapClientEndpointFactory.java
@@ -60,7 +60,7 @@ public class CoapClientEndpointFactory implements CaliforniumClientEndpointFacto
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, uri);
         } else {
-            return String.format("[%s-%s]", uri);
+            return String.format("[%s]", uri);
         }
     }
 
diff --git a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coaps/CoapsClientEndpointFactory.java b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coaps/CoapsClientEndpointFactory.java
index 3571df67..a1fadc75 100644
--- a/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coaps/CoapsClientEndpointFactory.java
+++ b/leshan-client-cf/src/main/java/org/eclipse/leshan/client/californium/endpoint/coaps/CoapsClientEndpointFactory.java
@@ -103,7 +103,7 @@ public class CoapsClientEndpointFactory extends CoapClientEndpointFactory {
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, uri);
         } else {
-            return String.format("[%s-%s]", uri);
+            return String.format("[%s]", uri);
         }
     }
 
diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/endpoint/EndpointUriUtil.java b/leshan-core/src/main/java/org/eclipse/leshan/core/endpoint/EndpointUriUtil.java
index 193655b1..67908f36 100644
--- a/leshan-core/src/main/java/org/eclipse/leshan/core/endpoint/EndpointUriUtil.java
+++ b/leshan-core/src/main/java/org/eclipse/leshan/core/endpoint/EndpointUriUtil.java
@@ -55,15 +55,15 @@ public class EndpointUriUtil {
         Validate.notNull(uri);
 
         if (uri.getScheme() == null) {
-            throw new IllegalArgumentException("URI Scheme MUST NOT be null");
+            throw new IllegalArgumentException(String.format("Invalid URI[%s]: Scheme MUST NOT be null", uri));
         }
 
         if (uri.getHost() == null) {
-            throw new IllegalArgumentException("URI Host MUST NOT be null");
+            throw new IllegalArgumentException(String.format("Invalid URI[%s]: Host MUST NOT be null", uri));
         }
 
         if (uri.getPort() == -1) {
-            throw new IllegalArgumentException("URI Post MUST NOT be undefined");
+            throw new IllegalArgumentException(String.format("Invalid URI[%s]: Post MUST NOT be undefined", uri));
         }
     }
 }
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/CaliforniumBootstrapServerEndpointsProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/CaliforniumBootstrapServerEndpointsProvider.java
index 0029b93d..6d3b52c2 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/CaliforniumBootstrapServerEndpointsProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/CaliforniumBootstrapServerEndpointsProvider.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 import org.eclipse.californium.core.CoapServer;
 import org.eclipse.californium.core.network.CoapEndpoint;
@@ -45,6 +46,7 @@ import org.eclipse.leshan.server.bootstrap.endpoint.LwM2mBootstrapServerEndpoint
 import org.eclipse.leshan.server.bootstrap.request.BootstrapUplinkRequestReceiver;
 import org.eclipse.leshan.server.californium.RootResource;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.coap.CoapBootstrapServerProtocolProvider;
+import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;
 import org.eclipse.leshan.server.security.ServerSecurityInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -175,7 +177,23 @@ public class CaliforniumBootstrapServerEndpointsProvider implements LwM2mBootstr
         }
 
         /**
-         * create Default CoAP Server Configuration.
+         * Create Californium {@link Configuration} with all Module Definitions needed for protocols provided by this
+         * endpointProvider.
+         * <p>
+         * Once, you create the configuration you should use {@link #setConfiguration(Configuration)}
+         *
+         * <pre>
+         * // Create Builder
+         * CaliforniumBootstrapServerEndpointsProvider.Builder builder = new CaliforniumBootstrapServerEndpointsProvider.Builder(
+         *         new CoapBootstrapServerProtocolProvider(), //
+         *         new CoapsBootstrapServerProtocolProvider());
+         *
+         * // Set custom Californium Configuration :
+         * Configuration c = builder.createDefaultConfiguration();
+         * c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         * c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * builder.setConfiguration(c);
+         * </pre>
          */
         public Configuration createDefaultConfiguration() {
             // Get all Californium modules
@@ -197,13 +215,49 @@ public class CaliforniumBootstrapServerEndpointsProvider implements LwM2mBootstr
         }
 
         /**
-         * @param serverConfiguration the @{link Configuration} used by the {@link CoapServer}.
+         * Set {@link Configuration} used by the {@link CoapServer}. It will be shared by all endpoints created by this
+         * endpoints provider.
+         * <p>
+         * {@link Configuration} provided SHOULD be created with {@link #createDefaultConfiguration()}.
+         * <p>
+         * It should generally not be used with {@link #setConfiguration(Consumer)}
          */
         public Builder setConfiguration(Configuration serverConfiguration) {
             this.serverConfiguration = serverConfiguration;
             return this;
         }
 
+        /**
+         * Create Californium {@link Configuration} with all needed Module Definitions for protocol provided by
+         * {@link ServerProtocolProvider}s, then apply given consumer to it.
+         *
+         * <pre>
+         * {@code
+         * endpointsBuilder.setConfiguration(c -> {
+         *     c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         *     c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * });
+         * }
+         * </pre>
+         *
+         * This is like doing :
+         *
+         * <pre>
+         * Configuration c = endpointsBuilder.createDefaultConfiguration();
+         * c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         * c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * endpointsBuilder.setConfiguration(c);
+         * </pre>
+         */
+        public Builder setConfiguration(Consumer<Configuration> configurationSetter) {
+            Configuration cfg = createDefaultConfiguration();
+            configurationSetter.accept(cfg);
+
+            // we set config once all is done without exception.
+            this.serverConfiguration = cfg;
+            return this;
+        }
+
         public Builder addEndpoint(String uri) {
             return addEndpoint(EndpointUriUtil.createUri(uri));
         }
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactory.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactory.java
index 85c56b1c..b0d47f53 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactory.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactory.java
@@ -17,12 +17,20 @@ package org.eclipse.leshan.server.californium.bootstrap.endpoint.coap;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
 
+import org.eclipse.californium.core.config.CoapConfig;
+import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.core.network.CoapEndpoint;
 import org.eclipse.californium.core.network.CoapEndpoint.Builder;
 import org.eclipse.californium.elements.Connector;
 import org.eclipse.californium.elements.UDPConnector;
 import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.elements.config.SystemConfig;
+import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.leshan.core.californium.DefaultExceptionTranslator;
 import org.eclipse.leshan.core.californium.ExceptionTranslator;
 import org.eclipse.leshan.core.californium.identity.DefaultCoapIdentityHandler;
@@ -35,21 +43,41 @@ import org.eclipse.leshan.server.security.ServerSecurityInfo;
 
 public class CoapBootstrapServerEndpointFactory implements CaliforniumBootstrapServerEndpointFactory {
 
+    public static Protocol getSupportedProtocol() {
+        return Protocol.COAP;
+    }
+
+    public static void applyDefaultValue(Configuration configuration) {
+        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+    }
+
+    public static List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS);
+    }
+
+    protected final URI endpointUri;
     protected final String loggingTagPrefix;
-    protected URI endpointUri = null;
+    protected final Configuration configuration;
+    protected final Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer;
 
     public CoapBootstrapServerEndpointFactory(URI uri) {
-        this(uri, "Bootstrap Server");
+        this(uri, null, null, null);
     }
 
-    public CoapBootstrapServerEndpointFactory(URI uri, String loggingTagPrefix) {
+    public CoapBootstrapServerEndpointFactory(URI uri, String loggingTagPrefix, Configuration configuration,
+            Consumer<Builder> coapEndpointConfigInitializer) {
+        EndpointUriUtil.validateURI(uri);
+
         this.endpointUri = uri;
-        this.loggingTagPrefix = loggingTagPrefix;
+        this.loggingTagPrefix = loggingTagPrefix == null ? "Bootstrap Server" : loggingTagPrefix;
+        this.configuration = configuration;
+        this.coapEndpointConfigInitializer = coapEndpointConfigInitializer;
+
     }
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAP;
+        return getSupportedProtocol();
     }
 
     @Override
@@ -61,14 +89,25 @@ public class CoapBootstrapServerEndpointFactory implements CaliforniumBootstrapS
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, getUri().toString());
         } else {
-            return String.format("[%s-%s]", getUri().toString());
+            return String.format("[%s]", getUri().toString());
         }
     }
 
     @Override
     public CoapEndpoint createCoapEndpoint(Configuration defaultConfiguration, ServerSecurityInfo serverSecurityInfo,
             LeshanBootstrapServer server) {
-        return createEndpointBuilder(EndpointUriUtil.getSocketAddr(endpointUri), defaultConfiguration, server).build();
+
+        // defined Configuration to use
+        Configuration configurationToUse;
+        if (configuration == null) {
+            // if specific configuration for this endpoint is null, used the default one which is the coapServer
+            // Configuration shared with all endpoints by default.
+            configurationToUse = defaultConfiguration;
+        } else {
+            configurationToUse = configuration;
+        }
+
+        return createEndpointBuilder(EndpointUriUtil.getSocketAddr(endpointUri), configurationToUse, server).build();
     }
 
     /**
@@ -85,6 +124,10 @@ public class CoapBootstrapServerEndpointFactory implements CaliforniumBootstrapS
         builder.setConnector(createConnector(address, coapConfig));
         builder.setConfiguration(coapConfig);
         builder.setLoggingTag(getLoggingTag());
+
+        if (coapEndpointConfigInitializer != null)
+            coapEndpointConfigInitializer.accept(builder);
+
         return builder;
     }
 
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactoryBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactoryBuilder.java
new file mode 100644
index 00000000..d8788974
--- /dev/null
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerEndpointFactoryBuilder.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.californium.bootstrap.endpoint.coap;
+
+import java.util.List;
+
+import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.leshan.core.endpoint.Protocol;
+import org.eclipse.leshan.server.californium.endpoint.AbstractEndpointFactoryBuilder;
+import org.eclipse.leshan.server.californium.endpoint.coap.CoapServerEndpointFactory;
+
+public class CoapBootstrapServerEndpointFactoryBuilder extends
+        AbstractEndpointFactoryBuilder<CoapBootstrapServerEndpointFactoryBuilder, CoapBootstrapServerEndpointFactory> {
+
+    @Override
+    protected Protocol getSupportedProtocol() {
+        return CoapServerEndpointFactory.getSupportedProtocol();
+    }
+
+    @Override
+    public void applyDefaultValue(Configuration configuration) {
+        CoapServerEndpointFactory.applyDefaultValue(configuration);
+
+    }
+
+    @Override
+    public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return CoapServerEndpointFactory.getModuleDefinitionsProviders();
+    }
+
+    @Override
+    public CoapBootstrapServerEndpointFactory build() {
+        return new CoapBootstrapServerEndpointFactory(uri, loggingTagPrefix, configuration,
+                coapEndpointConfigInitializer);
+    }
+}
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerProtocolProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerProtocolProvider.java
index 4629e549..6b3fcfd5 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerProtocolProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coap/CoapBootstrapServerProtocolProvider.java
@@ -17,15 +17,11 @@ package org.eclipse.leshan.server.californium.bootstrap.endpoint.coap;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.util.Arrays;
 import java.util.List;
 
 import org.eclipse.californium.core.config.CoapConfig;
-import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
-import org.eclipse.californium.elements.config.SystemConfig;
-import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
 import org.eclipse.leshan.core.endpoint.Protocol;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.BootstrapServerProtocolProvider;
@@ -35,17 +31,17 @@ public class CoapBootstrapServerProtocolProvider implements BootstrapServerProto
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAP;
+        return CoapBootstrapServerEndpointFactory.getSupportedProtocol();
     }
 
     @Override
     public void applyDefaultValue(Configuration configuration) {
-        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+        CoapBootstrapServerEndpointFactory.applyDefaultValue(configuration);
     }
 
     @Override
     public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
-        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS);
+        return CoapBootstrapServerEndpointFactory.getModuleDefinitionsProviders();
     }
 
     @Override
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactory.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactory.java
index 6bd1275a..4c693c57 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactory.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactory.java
@@ -19,12 +19,16 @@ import java.net.InetSocketAddress;
 import java.net.URI;
 import java.security.Principal;
 import java.security.PublicKey;
+import java.util.Arrays;
 import java.util.List;
+import java.util.function.Consumer;
 
 import javax.security.auth.x500.X500Principal;
 
 import org.eclipse.californium.core.coap.Message;
 import org.eclipse.californium.core.coap.Request;
+import org.eclipse.californium.core.config.CoapConfig;
+import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.core.network.CoapEndpoint;
 import org.eclipse.californium.core.network.CoapEndpoint.Builder;
 import org.eclipse.californium.elements.AddressEndpointContext;
@@ -39,8 +43,12 @@ import org.eclipse.californium.elements.auth.PreSharedKeyIdentity;
 import org.eclipse.californium.elements.auth.RawPublicKeyIdentity;
 import org.eclipse.californium.elements.auth.X509CertPath;
 import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.elements.config.SystemConfig;
+import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.californium.scandium.DTLSConnector;
 import org.eclipse.californium.scandium.config.DtlsConfig;
+import org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole;
 import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 import org.eclipse.californium.scandium.dtls.CertificateType;
 import org.eclipse.californium.scandium.dtls.DtlsHandshakeTimeoutException;
@@ -68,21 +76,45 @@ public class CoapsBootstrapServerEndpointFactory implements CaliforniumBootstrap
 
     private static final Logger LOG = LoggerFactory.getLogger(CoapsBootstrapServerEndpointFactory.class);
 
+    public static Protocol getSupportedProtocol() {
+        return Protocol.COAPS;
+    }
+
+    public static void applyDefaultValue(Configuration configuration) {
+        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+        configuration.set(DtlsConfig.DTLS_ROLE, DtlsRole.SERVER_ONLY);
+    }
+
+    public static List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS,
+                DtlsConfig.DEFINITIONS);
+    }
+
+    protected final URI endpointUri;
     protected final String loggingTagPrefix;
-    protected URI endpointUri = null;
+    protected final Configuration configuration;
+    protected final Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+    protected final Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer;
 
     public CoapsBootstrapServerEndpointFactory(URI uri) {
-        this(uri, "Bootstrap Server");
+        this(uri, null, null, null, null);
     }
 
-    public CoapsBootstrapServerEndpointFactory(URI uri, String loggingTagPrefix) {
+    public CoapsBootstrapServerEndpointFactory(URI uri, String loggingTagPrefix, Configuration configuration,
+            Consumer<org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer,
+            Consumer<Builder> coapEndpointConfigInitializer) {
+        EndpointUriUtil.validateURI(uri);
+
         this.endpointUri = uri;
-        this.loggingTagPrefix = loggingTagPrefix;
+        this.loggingTagPrefix = loggingTagPrefix == null ? "Bootstrap Server" : loggingTagPrefix;
+        this.configuration = configuration;
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+        this.coapEndpointConfigInitializer = coapEndpointConfigInitializer;
     }
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAPS;
+        return getSupportedProtocol();
     }
 
     @Override
@@ -94,7 +126,7 @@ public class CoapsBootstrapServerEndpointFactory implements CaliforniumBootstrap
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, getUri().toString());
         } else {
-            return String.format("[%s-%s]", getUri().toString());
+            return String.format("[%s]", getUri().toString());
         }
     }
 
@@ -106,8 +138,18 @@ public class CoapsBootstrapServerEndpointFactory implements CaliforniumBootstrap
             return null;
         }
 
+        // defined Configuration to use
+        Configuration configurationToUse;
+        if (configuration == null) {
+            // if specific configuration for this endpoint is null, used the default one which is the coapServer
+            // Configuration shared with all endpoints by default.
+            configurationToUse = defaultConfiguration;
+        } else {
+            configurationToUse = configuration;
+        }
+
         // create DTLS connector Config
-        DtlsConnectorConfig.Builder dtlsConfigBuilder = createDtlsConnectorConfigBuilder(defaultConfiguration);
+        DtlsConnectorConfig.Builder dtlsConfigBuilder = createDtlsConnectorConfigBuilder(configurationToUse);
         setUpDtlsConfig(dtlsConfigBuilder, EndpointUriUtil.getSocketAddr(endpointUri), serverSecurityInfo, server);
         DtlsConnectorConfig dtlsConfig;
         try {
@@ -118,13 +160,16 @@ public class CoapsBootstrapServerEndpointFactory implements CaliforniumBootstrap
         }
 
         // create CoAP endpoint
-        CoapEndpoint endpoint = createEndpointBuilder(dtlsConfig, defaultConfiguration).build();
+        CoapEndpoint endpoint = createEndpointBuilder(dtlsConfig, configurationToUse).build();
 
         return endpoint;
     }
 
     protected DtlsConnectorConfig.Builder createDtlsConnectorConfigBuilder(Configuration configuration) {
-        return new DtlsConnectorConfig.Builder(configuration);
+        DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(configuration);
+        if (dtlsConnectorConfigInitializer != null)
+            dtlsConnectorConfigInitializer.accept(builder);
+        return builder;
     }
 
     protected void setUpDtlsConfig(DtlsConnectorConfig.Builder dtlsConfigBuilder, InetSocketAddress address,
@@ -215,6 +260,9 @@ public class CoapsBootstrapServerEndpointFactory implements CaliforniumBootstrap
         builder.setConfiguration(coapConfig);
         builder.setLoggingTag(getLoggingTag());
         builder.setEndpointContextMatcher(createEndpointContextMatcher());
+
+        if (coapEndpointConfigInitializer != null)
+            coapEndpointConfigInitializer.accept(builder);
         return builder;
     }
 
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactoryBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactoryBuilder.java
new file mode 100644
index 00000000..65b24e76
--- /dev/null
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerEndpointFactoryBuilder.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.californium.bootstrap.endpoint.coaps;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
+import org.eclipse.leshan.core.endpoint.Protocol;
+import org.eclipse.leshan.server.californium.endpoint.AbstractEndpointFactoryBuilder;
+
+public class CoapsBootstrapServerEndpointFactoryBuilder extends
+        AbstractEndpointFactoryBuilder<CoapsBootstrapServerEndpointFactoryBuilder, CoapsBootstrapServerEndpointFactory> {
+
+    protected Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+
+    @Override
+    protected Protocol getSupportedProtocol() {
+        return CoapsBootstrapServerEndpointFactory.getSupportedProtocol();
+    }
+
+    @Override
+    public void applyDefaultValue(Configuration configuration) {
+        CoapsBootstrapServerEndpointFactory.applyDefaultValue(configuration);
+
+    }
+
+    @Override
+    public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return CoapsBootstrapServerEndpointFactory.getModuleDefinitionsProviders();
+    }
+
+    public CoapsBootstrapServerEndpointFactoryBuilder setDtlsConnectorConfig(
+            Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer) {
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+        return this;
+    }
+
+    @Override
+    public CoapsBootstrapServerEndpointFactory build() {
+        return new CoapsBootstrapServerEndpointFactory(uri, loggingTagPrefix, configuration,
+                dtlsConnectorConfigInitializer, coapEndpointConfigInitializer);
+    }
+}
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerProtocolProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerProtocolProvider.java
index 9f4d7b8b..e145ede2 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerProtocolProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/bootstrap/endpoint/coaps/CoapsBootstrapServerProtocolProvider.java
@@ -17,17 +17,13 @@ package org.eclipse.leshan.server.californium.bootstrap.endpoint.coaps;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.util.Arrays;
 import java.util.List;
+import java.util.function.Consumer;
 
 import org.eclipse.californium.core.config.CoapConfig;
-import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
-import org.eclipse.californium.elements.config.SystemConfig;
-import org.eclipse.californium.elements.config.UdpConfig;
-import org.eclipse.californium.scandium.config.DtlsConfig;
-import org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
 import org.eclipse.leshan.core.endpoint.Protocol;
 import org.eclipse.leshan.server.californium.bootstrap.endpoint.BootstrapServerProtocolProvider;
@@ -35,26 +31,34 @@ import org.eclipse.leshan.server.californium.bootstrap.endpoint.CaliforniumBoots
 
 public class CoapsBootstrapServerProtocolProvider implements BootstrapServerProtocolProvider {
 
+    protected Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+
+    public CoapsBootstrapServerProtocolProvider() {
+    }
+
+    public CoapsBootstrapServerProtocolProvider(Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer) {
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+    }
+
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAPS;
+        return CoapsBootstrapServerEndpointFactory.getSupportedProtocol();
     }
 
     @Override
     public void applyDefaultValue(Configuration configuration) {
-        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
-        configuration.set(DtlsConfig.DTLS_ROLE, DtlsRole.SERVER_ONLY);
+        CoapsBootstrapServerEndpointFactory.applyDefaultValue(configuration);
     }
 
     @Override
     public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
-        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS,
-                DtlsConfig.DEFINITIONS);
+        return CoapsBootstrapServerEndpointFactory.getModuleDefinitionsProviders();
     }
 
     @Override
     public CaliforniumBootstrapServerEndpointFactory createDefaultEndpointFactory(URI uri) {
-        return new CoapsBootstrapServerEndpointFactory(uri);
+        return new CoapsBootstrapServerEndpointFactoryBuilder().setURI(uri)
+                .setDtlsConnectorConfig(dtlsConnectorConfigInitializer).build();
     }
 
     @Override
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/AbstractEndpointFactoryBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/AbstractEndpointFactoryBuilder.java
new file mode 100644
index 00000000..b56fca6b
--- /dev/null
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/AbstractEndpointFactoryBuilder.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.californium.endpoint;
+
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
+import org.eclipse.leshan.core.endpoint.Protocol;
+
+public abstract class AbstractEndpointFactoryBuilder<SELF extends AbstractEndpointFactoryBuilder<SELF, TTarget>, TTarget> {
+
+    protected URI uri;
+    protected String loggingTagPrefix;
+    protected Configuration configuration;
+    protected Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer;
+
+    @SuppressWarnings("unchecked")
+    private SELF self() {
+        return (SELF) this;
+    }
+
+    protected abstract Protocol getSupportedProtocol();
+
+    protected abstract void applyDefaultValue(Configuration configuration);
+
+    protected abstract List<ModuleDefinitionsProvider> getModuleDefinitionsProviders();
+
+    public abstract TTarget build();
+
+    public SELF setURI(URI uri) {
+        EndpointUriUtil.validateURI(uri);
+        this.uri = uri;
+        return self();
+    }
+
+    public SELF setURI(int port) {
+        return setURI(new InetSocketAddress(port));
+    }
+
+    public SELF setURI(InetSocketAddress addr) {
+        this.uri = EndpointUriUtil.createUri(getSupportedProtocol().getUriScheme(), addr);
+        return self();
+    }
+
+    public SELF setURI(String uriAsString) {
+        URI uri = EndpointUriUtil.createUri(uriAsString);
+        EndpointUriUtil.validateURI(uri);
+
+        if (!getSupportedProtocol().getUriScheme().equals(uri.getScheme())) {
+            throw new IllegalArgumentException(String.format("Invalid URI[%s]: Protocol Scheme MUST NOT be [%s]", uri,
+                    getSupportedProtocol().getUriScheme()));
+        }
+
+        return self();
+    }
+
+    public SELF setLoggingTagPrefix(String loggingTagPrefix) {
+        this.loggingTagPrefix = loggingTagPrefix;
+        return self();
+    }
+
+    public SELF setConfiguration(Consumer<Configuration> configurationInitializer) {
+        // Create Configuration
+        List<ModuleDefinitionsProvider> moduleDefinitions = getModuleDefinitionsProviders();
+        Configuration configuration = new Configuration(
+                moduleDefinitions.toArray(new ModuleDefinitionsProvider[moduleDefinitions.size()]));
+        // Apply default value
+        applyDefaultValue(configuration);
+
+        // Apply initializer
+        configurationInitializer.accept(configuration);
+
+        // if all OK, save configuration
+        this.configuration = configuration;
+        return self();
+    }
+
+    public SELF setCoapEndpointConfig(Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer) {
+        this.coapEndpointConfigInitializer = coapEndpointConfigInitializer;
+        return self();
+    }
+
+}
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/CaliforniumServerEndpointsProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/CaliforniumServerEndpointsProvider.java
index 011dbd65..bd4679e5 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/CaliforniumServerEndpointsProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/CaliforniumServerEndpointsProvider.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 import org.eclipse.californium.core.CoapServer;
 import org.eclipse.californium.core.coap.Request;
@@ -225,7 +226,23 @@ public class CaliforniumServerEndpointsProvider implements LwM2mServerEndpointsP
         }
 
         /**
-         * create Default CoAP Server Configuration.
+         * Create Californium {@link Configuration} with all Module Definitions needed for protocols provided by this
+         * endpoints provider.
+         * <p>
+         * Once, you create the configuration you should use {@link #setConfiguration(Configuration)}
+         *
+         * <pre>
+         * // Create Builder
+         * CaliforniumServerEndpointsProvider.Builder builder = new CaliforniumServerEndpointsProvider.Builder(
+         *         new CoapServerProtocolProvider(), //
+         *         new CoapsServerProtocolProvider());
+         *
+         * // Set custom Californium Configuration :
+         * Configuration c = builder.createDefaultConfiguration();
+         * c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         * c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * builder.setConfiguration(c);
+         * </pre>
          */
         public Configuration createDefaultConfiguration() {
             // Get all Californium modules
@@ -247,13 +264,49 @@ public class CaliforniumServerEndpointsProvider implements LwM2mServerEndpointsP
         }
 
         /**
-         * @param serverConfiguration the @{link Configuration} used by the {@link CoapServer}.
+         * Set {@link Configuration} used by the {@link CoapServer}. It will be shared by all endpoints created by this
+         * endpoints provider.
+         * <p>
+         * {@link Configuration} provided SHOULD be created with {@link #createDefaultConfiguration()}.
+         * <p>
+         * It should generally not be used with {@link #setConfiguration(Consumer)}
          */
         public Builder setConfiguration(Configuration serverConfiguration) {
             this.serverConfiguration = serverConfiguration;
             return this;
         }
 
+        /**
+         * Create Californium {@link Configuration} with all needed Module Definitions for protocol provided by
+         * {@link ServerProtocolProvider}s, then apply given consumer to it.
+         *
+         * <pre>
+         * {@code
+         * endpointsBuilder.setConfiguration(c -> {
+         *     c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         *     c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * });
+         * }
+         * </pre>
+         *
+         * This is like doing :
+         *
+         * <pre>
+         * Configuration c = endpointsBuilder.createDefaultConfiguration();
+         * c.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, true);
+         * c.set(CoapConfig.ACK_TIMEOUT, 1, TimeUnit.SECONDS);
+         * endpointsBuilder.setConfiguration(c);
+         * </pre>
+         */
+        public Builder setConfiguration(Consumer<Configuration> configurationSetter) {
+            Configuration cfg = createDefaultConfiguration();
+            configurationSetter.accept(cfg);
+
+            // we set config once all is done without exception.
+            this.serverConfiguration = cfg;
+            return this;
+        }
+
         public Builder addEndpoint(String uri) {
             return addEndpoint(EndpointUriUtil.createUri(uri));
         }
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactory.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactory.java
index 46567e2f..9b54b463 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactory.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactory.java
@@ -17,7 +17,12 @@ package org.eclipse.leshan.server.californium.endpoint.coap;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
 
+import org.eclipse.californium.core.config.CoapConfig;
+import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.core.network.CoapEndpoint;
 import org.eclipse.californium.core.network.CoapEndpoint.Builder;
 import org.eclipse.californium.core.network.serialization.UdpDataParser;
@@ -25,6 +30,9 @@ import org.eclipse.californium.core.network.serialization.UdpDataSerializer;
 import org.eclipse.californium.elements.Connector;
 import org.eclipse.californium.elements.UDPConnector;
 import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.elements.config.SystemConfig;
+import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.leshan.core.californium.DefaultExceptionTranslator;
 import org.eclipse.leshan.core.californium.ExceptionTranslator;
 import org.eclipse.leshan.core.californium.identity.DefaultCoapIdentityHandler;
@@ -40,21 +48,40 @@ import org.eclipse.leshan.server.security.ServerSecurityInfo;
 
 public class CoapServerEndpointFactory implements CaliforniumServerEndpointFactory {
 
+    public static Protocol getSupportedProtocol() {
+        return Protocol.COAP;
+    }
+
+    public static void applyDefaultValue(Configuration configuration) {
+        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+    }
+
+    public static List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS);
+    }
+
+    protected final URI endpointUri;
     protected final String loggingTagPrefix;
-    protected URI endpointUri = null;
+    protected final Configuration configuration;
+    protected final Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer;
 
     public CoapServerEndpointFactory(URI uri) {
-        this(uri, "LWM2M Server");
+        this(uri, null, null, null);
     }
 
-    public CoapServerEndpointFactory(URI uri, String loggingTagPrefix) {
+    public CoapServerEndpointFactory(URI uri, String loggingTagPrefix, Configuration configuration,
+            Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer) {
+        EndpointUriUtil.validateURI(uri);
+
         this.endpointUri = uri;
-        this.loggingTagPrefix = loggingTagPrefix;
+        this.loggingTagPrefix = loggingTagPrefix == null ? "LWM2M Server" : loggingTagPrefix;
+        this.configuration = configuration;
+        this.coapEndpointConfigInitializer = coapEndpointConfigInitializer;
     }
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAP;
+        return getSupportedProtocol();
     }
 
     @Override
@@ -66,14 +93,25 @@ public class CoapServerEndpointFactory implements CaliforniumServerEndpointFacto
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, getUri().toString());
         } else {
-            return String.format("[%s-%s]", getUri().toString());
+            return String.format("[%s]", getUri().toString());
         }
     }
 
     @Override
     public CoapEndpoint createCoapEndpoint(Configuration defaultConfiguration, ServerSecurityInfo serverSecurityInfo,
             LwM2mNotificationReceiver notificationReceiver, LeshanServer server) {
-        return createEndpointBuilder(EndpointUriUtil.getSocketAddr(endpointUri), defaultConfiguration,
+
+        // defined Configuration to use
+        Configuration configurationToUse;
+        if (configuration == null) {
+            // if specific configuration for this endpoint is null, used the default one which is the coapServer
+            // Configuration shared with all endpoints by default.
+            configurationToUse = defaultConfiguration;
+        } else {
+            configurationToUse = configuration;
+        }
+
+        return createEndpointBuilder(EndpointUriUtil.getSocketAddr(endpointUri), configurationToUse,
                 notificationReceiver, server).build();
     }
 
@@ -95,6 +133,10 @@ public class CoapServerEndpointFactory implements CaliforniumServerEndpointFacto
 
         builder.setObservationStore(new LwM2mObservationStore(server.getRegistrationStore(), notificationReceiver,
                 new ObservationSerDes(new UdpDataParser(), new UdpDataSerializer())));
+
+        if (coapEndpointConfigInitializer != null)
+            coapEndpointConfigInitializer.accept(builder);
+
         return builder;
     }
 
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactoryBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactoryBuilder.java
new file mode 100644
index 00000000..5c19e956
--- /dev/null
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerEndpointFactoryBuilder.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.californium.endpoint.coap;
+
+import java.util.List;
+
+import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.leshan.core.endpoint.Protocol;
+import org.eclipse.leshan.server.californium.endpoint.AbstractEndpointFactoryBuilder;
+
+public class CoapServerEndpointFactoryBuilder
+        extends AbstractEndpointFactoryBuilder<CoapServerEndpointFactoryBuilder, CoapServerEndpointFactory> {
+
+    @Override
+    protected Protocol getSupportedProtocol() {
+        return CoapServerEndpointFactory.getSupportedProtocol();
+    }
+
+    @Override
+    public void applyDefaultValue(Configuration configuration) {
+        CoapServerEndpointFactory.applyDefaultValue(configuration);
+
+    }
+
+    @Override
+    public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return CoapServerEndpointFactory.getModuleDefinitionsProviders();
+    }
+
+    @Override
+    public CoapServerEndpointFactory build() {
+        return new CoapServerEndpointFactory(uri, loggingTagPrefix, configuration, coapEndpointConfigInitializer);
+    }
+}
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerProtocolProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerProtocolProvider.java
index 38a7bb39..8847928b 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerProtocolProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coap/CoapServerProtocolProvider.java
@@ -17,15 +17,11 @@ package org.eclipse.leshan.server.californium.endpoint.coap;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.util.Arrays;
 import java.util.List;
 
 import org.eclipse.californium.core.config.CoapConfig;
-import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
-import org.eclipse.californium.elements.config.SystemConfig;
-import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
 import org.eclipse.leshan.core.endpoint.Protocol;
 import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointFactory;
@@ -35,17 +31,17 @@ public class CoapServerProtocolProvider implements ServerProtocolProvider {
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAP;
+        return CoapServerEndpointFactory.getSupportedProtocol();
     }
 
     @Override
     public void applyDefaultValue(Configuration configuration) {
-        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+        CoapServerEndpointFactory.applyDefaultValue(configuration);
     }
 
     @Override
     public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
-        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS);
+        return CoapServerEndpointFactory.getModuleDefinitionsProviders();
     }
 
     @Override
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactory.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactory.java
index 428e4a32..084fd0f2 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactory.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactory.java
@@ -19,12 +19,16 @@ import java.net.InetSocketAddress;
 import java.net.URI;
 import java.security.Principal;
 import java.security.PublicKey;
+import java.util.Arrays;
 import java.util.List;
+import java.util.function.Consumer;
 
 import javax.security.auth.x500.X500Principal;
 
 import org.eclipse.californium.core.coap.Message;
 import org.eclipse.californium.core.coap.Request;
+import org.eclipse.californium.core.config.CoapConfig;
+import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
 import org.eclipse.californium.core.network.CoapEndpoint;
 import org.eclipse.californium.core.network.CoapEndpoint.Builder;
 import org.eclipse.californium.core.network.serialization.UdpDataParser;
@@ -41,8 +45,12 @@ import org.eclipse.californium.elements.auth.PreSharedKeyIdentity;
 import org.eclipse.californium.elements.auth.RawPublicKeyIdentity;
 import org.eclipse.californium.elements.auth.X509CertPath;
 import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.elements.config.SystemConfig;
+import org.eclipse.californium.elements.config.UdpConfig;
 import org.eclipse.californium.scandium.DTLSConnector;
 import org.eclipse.californium.scandium.config.DtlsConfig;
+import org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole;
 import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 import org.eclipse.californium.scandium.dtls.CertificateType;
 import org.eclipse.californium.scandium.dtls.DtlsHandshakeTimeoutException;
@@ -78,21 +86,48 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
 
     private static final Logger LOG = LoggerFactory.getLogger(CoapsServerEndpointFactory.class);
 
+    public static Protocol getSupportedProtocol() {
+        return Protocol.COAPS;
+    }
+
+    public static void applyDefaultValue(Configuration configuration) {
+        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
+        // Do no allow Server to initiated Handshake by default, for U device request will be allowed to initiate
+        // handshake (see Registration.shouldInitiateConnection())
+        configuration.set(DtlsConfig.DTLS_DEFAULT_HANDSHAKE_MODE, DtlsEndpointContext.HANDSHAKE_MODE_NONE);
+        configuration.set(DtlsConfig.DTLS_ROLE, DtlsRole.BOTH);
+    }
+
+    public static List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS,
+                DtlsConfig.DEFINITIONS);
+    }
+
+    protected final URI endpointUri;
     protected final String loggingTagPrefix;
-    protected URI endpointUri = null;
+    protected final Configuration configuration;
+    protected final Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+    protected final Consumer<CoapEndpoint.Builder> coapEndpointConfigInitializer;
 
     public CoapsServerEndpointFactory(URI uri) {
-        this(uri, "LWM2M Server");
+        this(uri, null, null, null, null);
     }
 
-    public CoapsServerEndpointFactory(URI uri, String loggingTagPrefix) {
+    public CoapsServerEndpointFactory(URI uri, String loggingTagPrefix, Configuration configuration,
+            Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer,
+            Consumer<Builder> coapEndpointConfigInitializer) {
+        EndpointUriUtil.validateURI(uri);
+
         this.endpointUri = uri;
-        this.loggingTagPrefix = loggingTagPrefix;
+        this.loggingTagPrefix = loggingTagPrefix == null ? "LWM2M Server" : loggingTagPrefix;
+        this.configuration = configuration;
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+        this.coapEndpointConfigInitializer = coapEndpointConfigInitializer;
     }
 
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAPS;
+        return getSupportedProtocol();
     }
 
     @Override
@@ -104,7 +139,7 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
         if (loggingTagPrefix != null) {
             return String.format("[%s-%s]", loggingTagPrefix, getUri().toString());
         } else {
-            return String.format("[%s-%s]", getUri().toString());
+            return String.format("[%s]", getUri().toString());
         }
     }
 
@@ -117,8 +152,18 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
             return null;
         }
 
+        // defined Configuration to use
+        Configuration configurationToUse;
+        if (configuration == null) {
+            // if specific configuration for this endpoint is null, used the default one which is the coapServer
+            // Configuration shared with all endpoints by default.
+            configurationToUse = defaultConfiguration;
+        } else {
+            configurationToUse = configuration;
+        }
+
         // create DTLS connector Config
-        DtlsConnectorConfig.Builder dtlsConfigBuilder = createDtlsConnectorConfigBuilder(defaultConfiguration);
+        DtlsConnectorConfig.Builder dtlsConfigBuilder = createDtlsConnectorConfigBuilder(configurationToUse);
         setUpDtlsConfig(dtlsConfigBuilder, EndpointUriUtil.getSocketAddr(endpointUri), serverSecurityInfo, server);
         DtlsConnectorConfig dtlsConfig;
         try {
@@ -132,7 +177,7 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
         LwM2mObservationStore observationStore = createObservationStore(server, notificationReceiver);
 
         // create CoAP endpoint
-        CoapEndpoint endpoint = createEndpointBuilder(dtlsConfig, defaultConfiguration, observationStore).build();
+        CoapEndpoint endpoint = createEndpointBuilder(dtlsConfig, configurationToUse, observationStore).build();
 
         // create DTLS connection cleaner
         createConnectionCleaner(server.getSecurityStore(), endpoint);
@@ -140,7 +185,10 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
     }
 
     protected DtlsConnectorConfig.Builder createDtlsConnectorConfigBuilder(Configuration endpointConfiguration) {
-        return new DtlsConnectorConfig.Builder(endpointConfiguration);
+        DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(endpointConfiguration);
+        if (dtlsConnectorConfigInitializer != null)
+            dtlsConnectorConfigInitializer.accept(builder);
+        return builder;
     }
 
     protected void setUpDtlsConfig(DtlsConnectorConfig.Builder dtlsConfigBuilder, InetSocketAddress address,
@@ -243,6 +291,9 @@ public class CoapsServerEndpointFactory implements CaliforniumServerEndpointFact
         builder.setEndpointContextMatcher(createEndpointContextMatcher());
         builder.setObservationStore(store);
 
+        if (coapEndpointConfigInitializer != null)
+            coapEndpointConfigInitializer.accept(builder);
+
         return builder;
     }
 
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactoryBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactoryBuilder.java
new file mode 100644
index 00000000..1282abc3
--- /dev/null
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerEndpointFactoryBuilder.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.californium.endpoint.coaps;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.eclipse.californium.elements.config.Configuration;
+import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
+import org.eclipse.leshan.core.endpoint.Protocol;
+import org.eclipse.leshan.server.californium.endpoint.AbstractEndpointFactoryBuilder;
+
+public class CoapsServerEndpointFactoryBuilder
+        extends AbstractEndpointFactoryBuilder<CoapsServerEndpointFactoryBuilder, CoapsServerEndpointFactory> {
+
+    protected Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+
+    @Override
+    protected Protocol getSupportedProtocol() {
+        return CoapsServerEndpointFactory.getSupportedProtocol();
+    }
+
+    @Override
+    public void applyDefaultValue(Configuration configuration) {
+        CoapsServerEndpointFactory.applyDefaultValue(configuration);
+
+    }
+
+    @Override
+    public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
+        return CoapsServerEndpointFactory.getModuleDefinitionsProviders();
+    }
+
+    public CoapsServerEndpointFactoryBuilder setDtlsConnectorConfig(
+            Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer) {
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+        return this;
+    }
+
+    @Override
+    public CoapsServerEndpointFactory build() {
+        return new CoapsServerEndpointFactory(uri, loggingTagPrefix, configuration, dtlsConnectorConfigInitializer,
+                coapEndpointConfigInitializer);
+    }
+}
diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerProtocolProvider.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerProtocolProvider.java
index fe76fc1c..095f3cca 100644
--- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerProtocolProvider.java
+++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/endpoint/coaps/CoapsServerProtocolProvider.java
@@ -17,18 +17,13 @@ package org.eclipse.leshan.server.californium.endpoint.coaps;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.util.Arrays;
 import java.util.List;
+import java.util.function.Consumer;
 
 import org.eclipse.californium.core.config.CoapConfig;
-import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
-import org.eclipse.californium.elements.DtlsEndpointContext;
 import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
-import org.eclipse.californium.elements.config.SystemConfig;
-import org.eclipse.californium.elements.config.UdpConfig;
-import org.eclipse.californium.scandium.config.DtlsConfig;
-import org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
 import org.eclipse.leshan.core.endpoint.Protocol;
 import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointFactory;
@@ -36,29 +31,34 @@ import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;
 
 public class CoapsServerProtocolProvider implements ServerProtocolProvider {
 
+    protected Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer;
+
+    public CoapsServerProtocolProvider() {
+    }
+
+    public CoapsServerProtocolProvider(Consumer<DtlsConnectorConfig.Builder> dtlsConnectorConfigInitializer) {
+        this.dtlsConnectorConfigInitializer = dtlsConnectorConfigInitializer;
+    }
+
     @Override
     public Protocol getProtocol() {
-        return Protocol.COAPS;
+        return CoapsServerEndpointFactory.getSupportedProtocol();
     }
 
     @Override
     public void applyDefaultValue(Configuration configuration) {
-        configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
-        // Do no allow Server to initiated Handshake by default, for U device request will be allowed to initiate
-        // handshake (see Registration.shouldInitiateConnection())
-        configuration.set(DtlsConfig.DTLS_DEFAULT_HANDSHAKE_MODE, DtlsEndpointContext.HANDSHAKE_MODE_NONE);
-        configuration.set(DtlsConfig.DTLS_ROLE, DtlsRole.BOTH);
+        CoapsServerEndpointFactory.applyDefaultValue(configuration);
     }
 
     @Override
     public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
-        return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, UdpConfig.DEFINITIONS,
-                DtlsConfig.DEFINITIONS);
+        return CoapsServerEndpointFactory.getModuleDefinitionsProviders();
     }
 
     @Override
     public CaliforniumServerEndpointFactory createDefaultEndpointFactory(URI uri) {
-        return new CoapsServerEndpointFactory(uri);
+        return new CoapsServerEndpointFactoryBuilder().setURI(uri)
+                .setDtlsConnectorConfig(dtlsConnectorConfigInitializer).build();
     }
 
     @Override
diff --git a/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/LeshanServerDemo.java b/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/LeshanServerDemo.java
index 94f4234c..e9873ece 100644
--- a/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/LeshanServerDemo.java
+++ b/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/LeshanServerDemo.java
@@ -21,7 +21,6 @@ import java.io.File;
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.net.URI;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.List;
@@ -34,7 +33,6 @@ import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.elements.util.CertPathUtil;
 import org.eclipse.californium.scandium.config.DtlsConfig;
 import org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole;
-import org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
@@ -47,12 +45,9 @@ import org.eclipse.leshan.core.model.ObjectLoader;
 import org.eclipse.leshan.core.model.ObjectModel;
 import org.eclipse.leshan.server.LeshanServer;
 import org.eclipse.leshan.server.LeshanServerBuilder;
-import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointFactory;
 import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointsProvider;
-import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;
 import org.eclipse.leshan.server.californium.endpoint.coap.CoapOscoreServerEndpointFactory;
 import org.eclipse.leshan.server.californium.endpoint.coap.CoapServerProtocolProvider;
-import org.eclipse.leshan.server.californium.endpoint.coaps.CoapsServerEndpointFactory;
 import org.eclipse.leshan.server.californium.endpoint.coaps.CoapsServerProtocolProvider;
 import org.eclipse.leshan.server.core.demo.json.servlet.SecurityServlet;
 import org.eclipse.leshan.server.demo.cli.LeshanServerDemoCLI;
@@ -183,29 +178,18 @@ public class LeshanServerDemo {
 
         // Create Californium Endpoints Provider:
         // ------------------
-        // Create Custom CoAPS protocol provider to add MDC logger :
-        ServerProtocolProvider coapsProtocolProvider = new CoapsServerProtocolProvider() {
-            @Override
-            public CaliforniumServerEndpointFactory createDefaultEndpointFactory(URI uri) {
-                return new CoapsServerEndpointFactory(uri) {
-
-                    @Override
-                    protected Builder createDtlsConnectorConfigBuilder(Configuration endpointConfiguration) {
-                        Builder dtlsConfigBuilder = super.createDtlsConnectorConfigBuilder(endpointConfiguration);
-
-                        // Add MDC for connection logs
-                        if (cli.helpsOptions.getVerboseLevel() > 0)
-                            dtlsConfigBuilder.setConnectionListener(new PrincipalMdcConnectionListener());
-
-                        return dtlsConfigBuilder;
-                    }
-                };
-            }
-        };
-
         // Create Server Endpoints Provider
         CaliforniumServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumServerEndpointsProvider.Builder(
-                new CoapServerProtocolProvider(), coapsProtocolProvider);
+                // Add coap Protocol support
+                new CoapServerProtocolProvider(),
+
+                // Add coaps protocol support
+                new CoapsServerProtocolProvider(c -> {
+                    // Add MDC for connection logs
+                    if (cli.helpsOptions.getVerboseLevel() > 0)
+                        c.setConnectionListener(new PrincipalMdcConnectionListener());
+
+                }));
 
         // Create Californium Configuration
         Configuration serverCoapConfig = endpointsBuilder.createDefaultConfiguration();


Test patch:
diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/LeshanServerBuilderTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/LeshanServerBuilderTest.java
index b7541a7a..e8eb52ce 100644
--- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/LeshanServerBuilderTest.java
+++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/LeshanServerBuilderTest.java
@@ -34,7 +34,6 @@ import java.security.spec.InvalidKeySpecException;
 import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.KeySpec;
 
-import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.scandium.config.DtlsConfig;
 import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
 import org.eclipse.leshan.core.endpoint.Protocol;
@@ -140,9 +139,9 @@ public class LeshanServerBuilderTest {
     public void create_server_without_psk_cipher() {
         Builder endpointsBuilder = new CaliforniumServerEndpointsProvider.Builder(new CoapsServerProtocolProvider());
 
-        Configuration coapConfiguration = endpointsBuilder.createDefaultConfiguration();
-        coapConfiguration.setAsList(DtlsConfig.DTLS_CIPHER_SUITES, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-        endpointsBuilder.setConfiguration(coapConfiguration);
+        endpointsBuilder.setConfiguration(c -> {
+            c.setAsList(DtlsConfig.DTLS_CIPHER_SUITES, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+        });
 
         builder.setPrivateKey(privateKey);
         builder.setPublicKey(publicKey);
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 fb6d008b..bcd4833e 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
@@ -35,7 +35,6 @@ import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.KeySpec;
 import java.util.Iterator;
 
-import org.eclipse.californium.elements.config.Configuration;
 import org.eclipse.californium.scandium.config.DtlsConfig;
 import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
 import org.eclipse.leshan.core.endpoint.Protocol;
@@ -186,9 +185,9 @@ public class LeshanBootstrapServerBuilderTest {
     public void create_server_without_psk_cipher() {
         Builder endpointsBuilder = new CaliforniumBootstrapServerEndpointsProvider.Builder(
                 new CoapsBootstrapServerProtocolProvider());
-        Configuration coapConfiguration = endpointsBuilder.createDefaultConfiguration();
-        coapConfiguration.setAsList(DtlsConfig.DTLS_CIPHER_SUITES, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-        endpointsBuilder.setConfiguration(coapConfiguration);
+        endpointsBuilder.setConfiguration(c -> {
+            c.setAsList(DtlsConfig.DTLS_CIPHER_SUITES, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+        });
         builder.setEndpointsProvider(endpointsBuilder.build());
 
         builder.setPrivateKey(privateKey);