Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
cyril2maq opened this issue Jan 24, 2023 · 7 comments
Labels
question Any question about leshan

Comments

@cyril2maq
Copy link

cyril2maq commented Jan 24, 2023

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.

@cyril2maq cyril2maq added the question Any question about leshan label Jan 24, 2023
@sbernard31
Copy link
Contributor

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

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 🤔

Do you have any idea in mind ?

@cyril2maq
Copy link
Author

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
Copy link
Contributor

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 😉

@sbernard31
Copy link
Contributor

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 3204890)

@sbernard31
Copy link
Contributor

sbernard31 commented Feb 3, 2023

@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
Copy link
Contributor

#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
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Any question about leshan
Projects
None yet
Development

No branches or pull requests

2 participants