eclipse-leshan / leshan

Java Library for LWM2M
https://www.eclipse.org/leshan/
BSD 3-Clause "New" or "Revised" License
653 stars 407 forks source link

How to set the SessionStore with the new LwM2mServerEndpointsProvider mechanism ? #1383

Closed cyril2maq closed 1 year ago

cyril2maq commented 1 year ago

Question

It seems that with the new TransportLayer architecture APIS, it is not possible anymore to set a SessionStore (handling DTLS sessions) to a LwM2mServerEndpointsProvider.

In previous version (M10) we could set it with LeshanServerBuilder.

This is important, because overriding this SessionStore is the only way for now to handle multi-instance implementation (by creating ou own 'RedisSessionStore').

The workaround can be to create our own CoapsServerProtocolProvider and CoapsServerEndpointFactory which will handle this SessionStore; but it seems quite tedious.

For information, it is the same situation for the bootstrap counterpart LeshanBootstrapServerBuilder.

sbernard31 commented 1 year ago

Thx for testing and taking time to report feedback about new Transport Layer Abstraction ! :pray:

Let me know if I'm wrong, with 2.0.0-M10 codes looks like :

LeshanServerBuilder serverBuiler = new LeshanServerBuilder();

Configuration coapConfig = LeshanServerBuilder.createDefaultCoapConfiguration();
serverBuiler.setCoapConfig(coapConfig);

Builder dtlsConnectorConfig = new DtlsConnectorConfig.Builder(coapConfig);
dtlsConnectorConfig.setSessionStore(new CustomSessionStore());

serverBuiler.setDtlsConfig(dtlsConnectorConfig);

With Transport Layer Abstraction, you can set a SessionStore like this :

LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

// This way all CoAPs endpoints created will use the CustomSessionStore.
CoapsServerProtocolProvider coapsProtocolProvider = new CoapsServerProtocolProvider() {
    @Override
    public CaliforniumServerEndpointFactory createDefaultEndpointFactory(URI uri) {
        return new CoapsServerEndpointFactory(uri) {
            @Override
            protected void setUpDtlsConfig(Builder dtlsConfigBuilder, InetSocketAddress address,
                    ServerSecurityInfo serverSecurityInfo, LeshanServer server) {
                super.setUpDtlsConfig(dtlsConfigBuilder, address, serverSecurityInfo, server);
                dtlsConfigBuilder.setSessionStore(new CustomSessionStore());
            }
        };
    }
};

CaliforniumServerEndpointsProvider.Builder endpointsBuilder = //
        new CaliforniumServerEndpointsProvider.Builder(coapsProtocolProvider);

serverBuilder.setEndpointsProvider(endpointsBuilder.build());

OR

LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

CoapsServerProtocolProvider coapsProtocolProvider = new CoapsServerProtocolProvider();
CaliforniumServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumServerEndpointsProvider.Builder(coapsProtocolProvider);

Configuration configuration = endpointsBuilder.createDefaultConfiguration();
endpointsBuilder.setConfiguration(configuration);

// This way only the endpoint created below will use the CustomSessionStore.
endpointsBuilder.addEndpoint(new CoapsServerEndpointFactory(coapsProtocolProvider.getDefaultUri(configuration)) {
    @Override
    protected void setUpDtlsConfig(Builder dtlsConfigBuilder, InetSocketAddress address,
            ServerSecurityInfo serverSecurityInfo, LeshanServer server) {
        super.setUpDtlsConfig(dtlsConfigBuilder, address, serverSecurityInfo, server);
        dtlsConfigBuilder.setSessionStore(new CustomSessionStore());
    }
});
serverBuilder.setEndpointsProvider(endpointsBuilder.build());

OR (less verbose but will not use CoapConfig.COAP_SECURE_PORT to set default coaps port)

LeshanServerBuilder serverBuilder = new LeshanServerBuilder();
CaliforniumServerEndpointsProvider.Builder endpointsBuilder = new CaliforniumServerEndpointsProvider.Builder(
        new CoapsServerProtocolProvider());

endpointsBuilder.addEndpoint(new CoapsServerEndpointFactory(EndpointUriUtil.createUri("coaps", new InetSocketAddress(5684))) {
    @Override
    protected void setUpDtlsConfig(Builder dtlsConfigBuilder, InetSocketAddress address,
            ServerSecurityInfo serverSecurityInfo, LeshanServer server) {
        super.setUpDtlsConfig(dtlsConfigBuilder, address, serverSecurityInfo, server);
        dtlsConfigBuilder.setSessionStore(new CustomSessionStore());
    }
});
serverBuilder.setEndpointsProvider(endpointsBuilder.build());

As I wanted to avoid to create wrapper around each Californium Builder (CoapEndpoint.Builder, DtlsConnectorConfig.Builder, ... ), I came to this solution which seemed to me a very flexible one.

But I agree this is a bit verbose... I don't know how we can improve this maybe playing with some java 8 lambda :thinking:

Do you have any idea in mind ?

cyril2maq commented 1 year ago

Thanks a lot for your time looking into it. Yes your first proposal seems like the simplest one to me, and it does work. It's a drawback to lose the ease to setup the sessionStore; but I do not see how to seemlessly implement it as the 'Configuration' POJO used to set other configuration parameters does not fit this usage.

sbernard31 commented 1 year ago

If I find something better with java lambda, I will let you know this way you will be able to give your opinion.

Waiting if you have any idea, do not hesitate to share :wink:

sbernard31 commented 1 year ago

Maybe something like this ?

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());

(I code a POC at 32048906a99e1554ca509571c160364c669dbc5d)

sbernard31 commented 1 year ago

@cyril2maq I tried to think about how to improve API to create CaliforniumServerEndpointsProvider I created an issue, if you have any opinions please to not hesitate to comment at #1395

sbernard31 commented 1 year ago

1407 PR should solve this issue. Let me know if you plan to provide review OR feedback about it.

(If you don't, I will probably integrate it on Monday)

sbernard31 commented 1 year ago

1407 is now integrated in master so I think we can close this issue.