All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.leshan.client.californium.LeshanClientBuilder Maven / Gradle / Ivy

There is a newer version: 2.0.0-M15
Show newest version
/*******************************************************************************
 * Copyright (c) 2015 Sierra Wireless and others.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 * 
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v20.html
 * and the Eclipse Distribution License is available at
 *    http://www.eclipse.org/org/documents/edl-v10.html.
 * 
 * Contributors:
 *     Sierra Wireless - initial API and implementation
 *******************************************************************************/
package org.eclipse.leshan.client.californium;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;

import org.eclipse.californium.core.CoapServer;
import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.eclipse.californium.core.network.config.NetworkConfig.Keys;
import org.eclipse.californium.elements.Connector;
import org.eclipse.californium.elements.UDPConnector;
import org.eclipse.californium.scandium.DTLSConnector;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder;
import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory;
import org.eclipse.leshan.client.engine.RegistrationEngine;
import org.eclipse.leshan.client.engine.RegistrationEngineFactory;
import org.eclipse.leshan.client.object.Device;
import org.eclipse.leshan.client.object.Security;
import org.eclipse.leshan.client.object.Server;
import org.eclipse.leshan.client.resource.LwM2mObjectEnabler;
import org.eclipse.leshan.client.resource.ObjectsInitializer;
import org.eclipse.leshan.core.LwM2mId;
import org.eclipse.leshan.core.californium.DefaultEndpointFactory;
import org.eclipse.leshan.core.californium.EndpointFactory;
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder;
import org.eclipse.leshan.core.node.codec.LwM2mNodeDecoder;
import org.eclipse.leshan.core.node.codec.LwM2mNodeEncoder;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.request.BootstrapRequest;
import org.eclipse.leshan.core.util.Validate;

/**
 * Helper class to build and configure a Californium based Leshan Lightweight M2M client.
 */
public class LeshanClientBuilder {

    private final String endpoint;

    private InetSocketAddress localAddress;
    private List objectEnablers;

    private NetworkConfig coapConfig;
    private Builder dtlsConfigBuilder;

    private LwM2mNodeEncoder encoder;
    private LwM2mNodeDecoder decoder;

    private EndpointFactory endpointFactory;
    private RegistrationEngineFactory engineFactory;
    private Map additionalAttributes;

    private ScheduledExecutorService executor;

    /** @since 1.1 */
    protected Map bsAdditionalAttributes;

    /**
     * Creates a new instance for setting the configuration options for a {@link LeshanClient} instance.
     * 
     * The builder is initialized with the following default values:
     * 
    *
  • local address: a local address and an ephemeral port (picked up during binding)
  • *
  • object enablers: *
      *
    • Security(0) with one instance (DM server security): uri=coap://leshan.eclipseprojects.io:5683, * mode=NoSec
    • *
    • Server(1) with one instance (DM server): id=12345, lifetime=5minutes
    • *
    • Device(3): manufacturer=Eclipse Leshan, modelNumber=model12345, serialNumber=12345
    • *
    *
  • *
* * @param endpoint the end-point to identify the client on the server */ public LeshanClientBuilder(String endpoint) { Validate.notEmpty(endpoint); this.endpoint = endpoint; } /** * Sets the local address to use. */ public LeshanClientBuilder setLocalAddress(String hostname, int port) { if (hostname == null) { this.localAddress = new InetSocketAddress(port); } else { this.localAddress = new InetSocketAddress(hostname, port); } return this; } /** * Sets the list of objects enablers. *

* The easier way to create {@link LwM2mObjectEnabler} is to use the {@link ObjectsInitializer} but you can * implement your own {@link LwM2mObjectEnabler} if you need more flexibility. */ public LeshanClientBuilder setObjects(List objectEnablers) { this.objectEnablers = objectEnablers; return this; } /** * Set the {@link LwM2mNodeEncoder} which will encode {@link LwM2mNode} with supported content format. *

* By default the {@link DefaultLwM2mNodeEncoder} is used. It supports Text, Opaque, TLV and JSON format. */ public LeshanClientBuilder setEncoder(LwM2mNodeEncoder encoder) { this.encoder = encoder; return this; } /** * Set the {@link LwM2mNodeDecoder} which will decode data in supported content format to create {@link LwM2mNode}. *

* By default the {@link DefaultLwM2mNodeDecoder} is used. It supports Text, Opaque, TLV and JSON format. */ public LeshanClientBuilder setDecoder(LwM2mNodeDecoder decoder) { this.decoder = decoder; return this; } /** * Set the Californium/CoAP {@link NetworkConfig}. */ public LeshanClientBuilder setCoapConfig(NetworkConfig config) { this.coapConfig = config; return this; } /** * Set the Scandium/DTLS Configuration : {@link DtlsConnectorConfig}. */ public LeshanClientBuilder setDtlsConfig(DtlsConnectorConfig.Builder config) { this.dtlsConfigBuilder = config; return this; } /** * Advanced setter used to create custom CoAP endpoint. *

* An {@link UDPConnector} is expected for unsecured endpoint and a {@link DTLSConnector} is expected for secured * endpoint. * * @param endpointFactory An {@link EndpointFactory}, you can extends {@link DefaultEndpointFactory}. * @return the builder for fluent client creation. */ public LeshanClientBuilder setEndpointFactory(EndpointFactory endpointFactory) { this.endpointFactory = endpointFactory; return this; } /** * Set the {@link RegistrationEngineFactory} which is responsible to create the {@link RegistrationEngine}. *

* The {@link RegistrationEngine} is responsible to manage all the client lifecycle * (bootstrap/register/update/deregister ...) *

* By default a {@link DefaultRegistrationEngineFactory} is used. Look at this class to change some default timeout * value. * * @return the builder for fluent client creation. */ public LeshanClientBuilder setRegistrationEngineFactory(RegistrationEngineFactory engineFactory) { this.engineFactory = engineFactory; return this; } /** * Set the additionalAttributes for {@link org.eclipse.leshan.core.request.RegisterRequest}. */ public LeshanClientBuilder setAdditionalAttributes(Map additionalAttributes) { this.additionalAttributes = additionalAttributes; return this; } /** * Set the additionalAttributes for {@link BootstrapRequest} * @since 1.1 */ public LeshanClientBuilder setBootstrapAdditionalAttributes(Map additionalAttributes) { this.bsAdditionalAttributes = additionalAttributes; return this; } /** * Set a shared executor. This executor will be used everywhere it is possible. This is generally used when you want * to limit the number of thread to use or if you want to simulate a lot of clients sharing the same thread pool. *

* Currently UDP and DTLS receiver and sender thread could not be share meaning that you will at least consume 2 * thread by client + the number of thread available in the shared executor (see californium#1203 issue) *

* Executor will not be shutdown automatically on {@link LeshanClient#destroy(boolean)}, this should be done * manually. * * @param executor the executor to share. * @return the builder for fluent client creation. */ public LeshanClientBuilder setSharedExecutor(ScheduledExecutorService executor) { this.executor = executor; return this; } public static NetworkConfig createDefaultNetworkConfig() { NetworkConfig networkConfig = new NetworkConfig(); networkConfig.set(Keys.MID_TRACKER, "NULL"); networkConfig.set(Keys.MAX_ACTIVE_PEERS, 10); networkConfig.set(Keys.PROTOCOL_STAGE_THREAD_COUNT, 1); return networkConfig; } /** * Creates an instance of {@link LeshanClient} based on the properties set on this builder. */ public LeshanClient build() { if (localAddress == null) { localAddress = new InetSocketAddress(0); } if (objectEnablers == null) { ObjectsInitializer initializer = new ObjectsInitializer(); initializer.setInstancesForObject(LwM2mId.SECURITY, Security.noSec("coap://leshan.eclipseprojects.io:5683", 12345)); initializer.setInstancesForObject(LwM2mId.SERVER, new Server(12345, 5 * 60, BindingMode.U, false)); initializer.setInstancesForObject(LwM2mId.DEVICE, new Device("Eclipse Leshan", "model12345", "12345", "U")); objectEnablers = initializer.createAll(); } if (encoder == null) encoder = new DefaultLwM2mNodeEncoder(); if (decoder == null) decoder = new DefaultLwM2mNodeDecoder(); if (coapConfig == null) { coapConfig = createDefaultNetworkConfig(); } if (engineFactory == null) { engineFactory = new DefaultRegistrationEngineFactory(); } if (endpointFactory == null) { endpointFactory = new DefaultEndpointFactory("LWM2M Client") { @Override protected Connector createSecuredConnector(DtlsConnectorConfig dtlsConfig) { DTLSConnector dtlsConnector = new DTLSConnector(dtlsConfig); if (executor != null) { dtlsConnector.setExecutor(executor); } return dtlsConnector; } }; } // handle dtlsConfig if (dtlsConfigBuilder == null) { dtlsConfigBuilder = new DtlsConnectorConfig.Builder(); } DtlsConnectorConfig incompleteConfig = dtlsConfigBuilder.getIncompleteConfig(); // Handle secure address if (incompleteConfig.getAddress() == null) { if (localAddress == null) { localAddress = new InetSocketAddress(0); } dtlsConfigBuilder.setAddress(localAddress); } else if (localAddress != null && !localAddress.equals(incompleteConfig.getAddress())) { throw new IllegalStateException(String.format( "Configuration conflict between LeshanBuilder and DtlsConnectorConfig.Builder for address: %s != %s", localAddress, incompleteConfig.getAddress())); } // Handle active peers if (incompleteConfig.getMaxConnections() == null) dtlsConfigBuilder.setMaxConnections(coapConfig.getInt(Keys.MAX_ACTIVE_PEERS)); if (incompleteConfig.getStaleConnectionThreshold() == null) dtlsConfigBuilder.setStaleConnectionThreshold(coapConfig.getLong(Keys.MAX_PEER_INACTIVITY_PERIOD)); // Use only 1 thread to handle DTLS connection by default if (incompleteConfig.getConnectionThreadCount() == null) { dtlsConfigBuilder.setConnectionThreadCount(1); } // Use only 1 thread to receive DTLS data by default if (incompleteConfig.getReceiverThreadCount() == null) { dtlsConfigBuilder.setReceiverThreadCount(1); } // Deactivate SNI by default // TODO should we support SNI ? if (incompleteConfig.isSniEnabled() == null) { dtlsConfigBuilder.setSniEnabled(false); } return createLeshanClient(endpoint, localAddress, objectEnablers, coapConfig, dtlsConfigBuilder, endpointFactory, engineFactory, additionalAttributes, encoder, decoder, executor); } /** * Create the LeshanClient. *

* You can extend LeshanClientBuilder and override this method to create a new builder which will be * able to build an extended LeshanClient . *

* See all the setters of this builder for more documentation about parameters. * * @param endpoint The endpoint name for this client. * @param localAddress The local address used for unsecured connection. * @param objectEnablers The list of object enablers. An enabler adds to support for a given LWM2M object to the * client. * @param coapConfig The coap config used to create {@link CoapEndpoint} and {@link CoapServer}. * @param dtlsConfigBuilder The dtls config used to create the {@link DTLSConnector}. * @param endpointFactory The factory which will create the {@link CoapEndpoint}. * @param engineFactory The factory which will create the {@link RegistrationEngine}. * @param additionalAttributes Some extra (out-of-spec) attributes to add to the register request. * @param encoder used to encode request payload. * @param decoder used to decode response payload. * @param sharedExecutor an optional shared executor. * * @return the new {@link LeshanClient} */ protected LeshanClient createLeshanClient(String endpoint, InetSocketAddress localAddress, List objectEnablers, NetworkConfig coapConfig, Builder dtlsConfigBuilder, EndpointFactory endpointFactory, RegistrationEngineFactory engineFactory, Map additionalAttributes, LwM2mNodeEncoder encoder, LwM2mNodeDecoder decoder, ScheduledExecutorService sharedExecutor) { return new LeshanClient(endpoint, localAddress, objectEnablers, coapConfig, dtlsConfigBuilder, endpointFactory, engineFactory, additionalAttributes, bsAdditionalAttributes, encoder, decoder, executor); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy