eclipse-leshan / leshan

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

How to test a leshan-spring server and parse objects in californium? #1576

Closed maxkraft7 closed 6 months ago

maxkraft7 commented 7 months ago

Question

So I'm working with spring to run a leshan server. This class constructs the server:

@Configuration
public class LeshanServerConfig {

    // https://github.com/eclipse-leshan/leshan/wiki/Adding-new-objects#leshan-server
    void loadModels(LeshanServerBuilder builder) throws InvalidModelException, InvalidDDFFileException, IOException {
        // load the core models (Security, Server, Device ...)
        List<ObjectModel> models = ObjectLoader.loadDefault();

        // todo move path properties file
        String modelPath = "classpath:/models/";

        // load all files in the models directory that end in .xml
        models.addAll(ObjectLoader.loadObjectsFromDir(new File(modelPath)));

        // then add it to builder
        LwM2mModelProvider modelProvider = new StaticModelProvider(models);
        builder.setObjectModelProvider(modelProvider);
    }

    @Bean
    LeshanServer leshanServer() throws InvalidModelException, InvalidDDFFileException, IOException {
        LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

        CaliforniumServerEndpointsProvider.Builder providerBuilder = new CaliforniumServerEndpointsProvider.Builder();

        // Add endpoints
        providerBuilder.addEndpoint("coap://0.0.0.0:5683/msr");
        // todo providerBuilder.addEndpoint(eventually_your_coaps_uri);
        CaliforniumServerEndpointsProvider provider = providerBuilder.build();

        serverBuilder.setEndpointsProviders(provider);
        LeshanServer server = serverBuilder.build();

        loadModels(serverBuilder);

        // this should be done after the serverBuilder.build() or getCoapServer will return null because not yet created...
        provider.getCoapServer().add(new MeasurementResource());

        return server;
    }
}

I start it with a command line runner:

@Bean
    CommandLineRunner leshanServerRunner(LeshanServer server) {
        return new CommandLineRunner() {
            @Override
            @Async
            public void run(String... args) throws Exception {
                server.start();
            }
        };
    }

And in my coap (californium) measurement resource I for now just print the payload:

class MeasurementResource extends CoapResource {
    public MeasurementResource() {
        // set resource identifier
        super("msr");

        // set display name
        getAttributes().setTitle("Measurement Resource");
    }

    @Override
    public void handlePUT(CoapExchange exchange) {

        var payload = exchange.getRequestPayload();
        log.info("PUT /msr request received");
        log.info("Payload: " + Arrays.toString(payload));

        // todo parse lwM2M payload via leshan and the loaded models

        // todo store payload in database via jpa

    }
}

So for now I'm pretty stuck on how to properly test this (very early) setup. How would I write a unittest that sends a LwM2M Payload to this endpoint? On the Wiki I haven't found anything about it. If the handling of the payload is in californium (and decoupled from leshan) how would I parse the payload into an object that could reasonably be stored in the database?

sbernard31 commented 7 months ago

I see some code which sounds not good :

// This :  
providerBuilder.addEndpoint("coap://0.0.0.0:5683/msr"); // /msr should not be there !
// should rather be : 
providerBuilder.addEndpoint("coap://0.0.0.0:5683");
// or eventually : 
providerBuilder.addEndpoint(new InetSocketAddress(5683) , Protocol.COAP));
// I don't know spring so maybe I'm wrong but, I bet maybe this : 
String modelPath = "classpath:/models/";
// should rather be like :
List<ObjectModel> models = ObjectLoader.loadAllDefault(); // not mandatory but generally needed
models.addAll(ObjectLoader.loadDdfResources("/models/", your_string_array_of_models_name)); // see LeshanServerDemo as example
 // (at least this is the non spring way to load model from classpath)

So for now I'm pretty stuck on how to properly test this (very early) setup. How would I write a unittest that sends a LwM2M Payload to this endpoint? On the Wiki I haven't found anything about it.

This question is very unclear to me :point_up:, so I can not really answer :grimacing: Maybe you can look at leshan-integration-tests ? Or look at some Californium tests ?

If the handling of the payload is in californium (and decoupled from Leshan) how would I parse the payload into an object that could reasonably be stored in the database?

// todo parse lwM2M payload via leshan and the loaded models

How could I know which kind of payload your client will send to the server and so how could I answer ? Especially as this seems clearly not be part of the LWM2M specification ? sorry :shrug:

sbernard31 commented 6 months ago

Should we close this issue ?

sbernard31 commented 6 months ago

@maxkraft7 did you succeed to do what you try to achieve ?