eclipse-californium / californium

CoAP/DTLS Java Implementation
https://www.eclipse.org/californium/
Other
723 stars 361 forks source link

Resource /msr not found #2210

Closed maxkraft7 closed 7 months ago

maxkraft7 commented 7 months ago

When I run coap-client -m put coap://localhost/msr I get the following error message on the server:

ServerMessageDeliverer    : did not find resource /msr requested by 127.0.0.1:33601

Even though I created this resource:

class MeasurementResource extends CoapResource {

        public MeasurementResource() {
            // set resource identifier
            super("msr");
            setPath("msr");

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

And registered it in the following way:

    @Bean
    CoapServer coapServer() {

        Configuration config = Configuration.createStandardWithoutFile();
        CoapServer server = new CoapServer(config);

        server.getRoot().add(new MeasurementResource());

        return server;
    }

I use spring and Leshan so I stared the CoapServer with a CommandLineRunner and some Leshan config:

@Bean
    LeshanServer leshanServer(CoapServer coapServer) {

        LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

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

        for (var endpoint : coapServer.getEndpoints()) {
            providerBuilder.addEndpoint(endpoint.getUri());
        }

        serverBuilder.setEndpointsProviders(providerBuilder.build());

        return serverBuilder.build();
    }

    @Bean
    CommandLineRunner leshanServerRunner(LeshanServer server) {

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

What am I doing wrong? Why can't this resource be found?

sbernard31 commented 7 months ago

I'm not sure I get what you try to do but if you want to add a CoapResource to the Internal Coap Server, I'm not sure this is the right way to do.

Let me few minutes to investigate this.

boaks commented 7 months ago

Adding your MeasurementResource to the demo-apps/HelloWorldServer with:

    /*
     * Constructor for a new Hello-World server. Here, the resources of the
     * server are initialized.
     */
    public HelloWorldServer() throws SocketException {

        // provide an instance of a Hello-World resource
        add(new HelloWorldResource());
        add(new PubSubResource());
        add(new MyIpResource(MyIpResource.RESOURCE_NAME, true));
        add(new MeasurementResource());
    }
...
    static class MeasurementResource extends CoapResource {

        public MeasurementResource() {
            // set resource identifier
            super("msr");
            setPath("msr");

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

works on "my machine". Using the cf-browser shows with "DISCOVER":

Bildschirmfoto vom 2024-01-19 14-47-17

By the way, you don't need to set the path, that's anyway overwritten when adding the resource to a parent resource.

And you will need to add/implement the intended handle??? methods.

boaks commented 7 months ago

Lets wait on Simon's results.

maxkraft7 commented 7 months ago

Maybe you can reproduce the error when using libCoap: https://libcoap.net/doc/reference/4.3.1/man_coap-client.html . In my own code I added some handle methods of course, this is just a minimal example. Would it return 4.04 if my resource is not responding? Even though the handleGET Method got overridden?

sbernard31 commented 7 months ago

Again I'm not sure I get what you try to do but if you want to add a CoapResource to the Internal CoapServer of LeshanServer, you can try :

LeshanServerBuilder serverBuilder = new LeshanServerBuilder();

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

// Add your endpoints
providerBuilder.addEndpoint(your_coap_uri);
providerBuilder.addEndpoint(eventually_your_coaps_uri);
CaliforniumServerEndpointsProvider provider = providerBuilder.build();

serverBuilder.setEndpointsProviders(provider);

LeshanServer server = serverBuilder.build();

// 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 didn't test it, if it doesn't work maybe better to talk about it at Leshan repository)

I'm aware this is not so elegant since code modification related to the refactoring about new transport layer abstraction.

Maybe we should improve this adding new API(s) ?

1) By adding a getter on Leshan Server I don't know exactly how ? maybe like this ?

Collection<CaliforniumServerEndpointsProvider> providers =  server.getProviders(CaliforniumServerEndpointsProvider.class) 
providers.iterator().next().getCoapServer().add(new MeasurementResource());

(not so clean but no need to keep a ref to the provider and CoapServer could be access at any moment)

2) By adding a way to tweak CoapServer via CaliforniumServerEndpointsProvider.Builder

providerBuilder.configureCoapServer( coapServer -> coapServer.add(new MeasurementResource()));

(more elegant but could only be used to tweak server at creation)

In my own code I added some handle methods of course, this is just a minimal example. Would it return 4.04 if my resource is not responding? Even though the handleGET Method got overridden?

Maybe because with your way you don't really attach the CoapResource to the Internal CoapServer of LeshanServer. So try my way :point_up: and if this is not what you want to do, please what you try to achieve :pray:

boaks commented 7 months ago

Maybe you can reproduce the error when using libCoap

:-) :-) then it would be an error of libCoap :-) :-)

The be frank: If you create an issue for Californium you get some information ahead how to provide your case. Among them the wiki-page - Logs and IP Capturing ‐ How To Provide The Right Information.

If you just ignore that and then ask me to reproduce something, then I guess this will fail.

So, if you want some information about your server setup and libcoap, then please provide the wireshark capture. The capture, not picture.

boaks commented 7 months ago

$ coap-client -m put coap://localhost/msr 4.05 $ coap-client -m put coap://localhost/msr2 4.04

4.05 METHOD_NOT_ALLOWED 4.04 NOT_FOUND

So everything as expected. I guess, you need to follow Simon's instructions.

maxkraft7 commented 7 months ago

@sbernard31 this code works🥳. I think the providerBuilder.addEndpoint(your_coap_uri); was missing from my code. Thank you!

boaks commented 7 months ago

Thanks!