eclipse-californium / californium

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

Californium Proxy implementation #1182

Closed farid4all87 closed 4 years ago

farid4all87 commented 4 years ago

Hi, I am doing a project creating a CoAP network with Californium as a proxy. I have CoAP server nodes and an RPL border router node acting as a gateway for the network.They all have ipv6 address assign to them. I would like to know, how i can add the nodes and their resources available to access through the proxy? (I already tried to modify the ExampleCrossProxy.java to create the proxy server but i was unsuccessful to make the nodes and their resources available through proxy) Thanks

package org.eclipse.californium.examples; import java.net.*; import java.net.URI; import java.io.IOException; import org.eclipse.californium.core.CoapHandler; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.CoapResource; import org.eclipse.californium.core.CoapClient; import org.eclipse.californium.core.CoapResponse; import org.eclipse.californium.core.CoapServer; import org.eclipse.californium.core.network.config.NetworkConfig; import org.eclipse.californium.core.server.resources.CoapExchange;

import org.eclipse.californium.proxy.DirectProxyCoapResolver; import org.eclipse.californium.proxy.ProxyHttpServer; import org.eclipse.californium.proxy.resources.ForwardingResource; import org.eclipse.californium.proxy.resources.ProxyCoapClientResource; import org.eclipse.californium.proxy.resources.ProxyHttpClientResource;

public class ExampleCrossProxy {

private static final int PORT = NetworkConfig.getStandard().getInt(NetworkConfig.Keys.COAP_PORT);

private CoapServer targetServerA;

public ExampleCrossProxy() throws IOException {
    ForwardingResource coap2coap = new ProxyCoapClientResource("aaaa::212:7400:13e3:46c1/sensors/light:5683");
    ForwardingResource coap2http = new ProxyHttpClientResource("coap2http");

    // Create CoAP Server on PORT with proxy resources form CoAP to CoAP and HTTP
    targetServerA = new CoapServer(PORT);
    targetServerA.add(coap2coap);
    targetServerA.add(coap2http);
    targetServerA.add(new TargetResource("target"));
    targetServerA.start();

    /*ProxyHttpServer httpServer = new ProxyHttpServer(8080);
    httpServer.setProxyCoapResolver(new DirectProxyCoapResolver(coap2coap));

    System.out.println("CoAP resource \"target\" available over HTTP at: http://localhost:8080/proxy/coap://localhost:PORT/target");
}

/**
 * A simple resource that responds to GET requests with a small response
 * containing the resource's name.
 */
private static class TargetResource extends CoapResource {

    private int counter = 0;

    public TargetResource(String name) {
        super(name);
    }

    @Override
    public void handleGET(final CoapExchange exchange) {

     try{   
        Request request = exchange.advanced().getRequest();
            System.out.println("Requested URI: " + request.getURI());
        URI uri = new URI(request.getURI());
        CoapClient client = new CoapClient (new URI("aaaa::212:7400:13e3:46c1:5683/sensors/light"));
        client.get(new CoapHandler() {
        @Override
        public void onLoad(CoapResponse response) {
            exchange.respond(response.getCode(), response.getPayload());
        }

        @Override
        public void onError() {
            exchange.respond("No response received.");
        }
        });
     } catch(URISyntaxException e){
            System.err.println("Failed to initialize URI: " + e.getMessage());

    }
   }
}

public static void main(String[] args) throws Exception {
    new ExampleCrossProxy();
}

}

boaks commented 4 years ago

There are many, many flavors for proxies. The common thing is, that some peer request something for an other peer. That maybe done in a generic way, the original request contains all information required for the resulting request, or in a transparent way, where the proxy knows how to convert the original into the resulting request.

There are also at least 2 RFCs about that: RFC7252, CoAP-Proxies RFC8075, HTTP-2-CoAP

So, in order to provide the proper information, I would need a more precise description, what you want to do.

coap2coap? http2coap? coap2http?

I spend some time into cleanup the proxy, so maybe you be the first to test the new one, see PR #1176.

farid4all87 commented 4 years ago

I am trying to implement a coap2coap proxy so i can access the servers from the copper browser.

boaks commented 4 years ago

OK. Especially the generic approach is updated in PR #1176, so please test that!

Fetch and checkout PR #1176

git fetch origin pull/1176/head:proxy
git checkout proxy

Build it

mvn clean install

cd to "demo-apps/run" or "demo-apps/cf-proxy/target"

Run the example cross proxy:

java -jar cf-proxy-2.1.0-SNAPSHOT.jar

That starts the proxy on port 5685. For easier/faster first steps, you may start the included coap-target-server providing the argument "coap".

java -jar cf-proxy-2.1.0-SNAPSHOT.jar coap

** CoAP Proxy at: coap://localhost:5685/coap2http
** CoAP Proxy at: coap://localhost:5685/coap2coap
** HTTP Proxy at: http://localhost:8080/proxy/
** HTTP Local at: http://localhost:8080/local/
Started CoAP server on port 5683
Request: coap://localhost:5683/coap-target
CoAP Proxy at: coap://localhost:5685/coap2coap and coap://localhost:5683/coap-target
HTTP Proxy at: http://localhost:8080/proxy/coap://localhost:5683/coap-target
ExampleCrossProxy started (7239MB heap) ...

To use the proxy to delegate a request:

Proxy-request, coap2coap

CoapClient client = new CoapClient();
request = Request.newGet();
request.setDestinationContext(new AddressEndpointContext(new InetSocketAddress("localhost", 5685))); // adapt "localhost" and port according your proxy
request.setURI("coap://localhost:5683/coap-target"); // adapt "localhost" and port according your coap-server
CoapResponse response = client.advanced(request);
if (response != null) {
    System.out.println(response.getResponseText());
}

So far, I didn't check the use of a IPv6 literal address as CoAP-URI destination. I would assume, it works. If not, don't hesitate, to report that!

farid4all87 commented 4 years ago

Sorry i forgot to mention that, I am using eclipse ide to run the proxy. Is the process still same for that ?

boaks commented 4 years ago

Sure, should work accordingly. Run "Maven build ..." with "clean install" (required, though it's a special local snapshot and not the one from the eclipse repo). Then run the ExamplCrossProxy (maybe with "coap" as argument".

boaks commented 4 years ago

from the copper browser.

Using Copper you place the address of the proxy in the browser address field, e.g. "coap://proxy:5685". The URI for the proxy's request is then sent via the "Proxy-Uri"-option, or the "Proxy-Scheme"-option, the "Uri-Host"-option, the "Uri-Port"-option and the path from the browsers address.

e.g. use the Proxy-URI-option "coap://[aaaa::212:7400:13e3:46c1]:5683/sensors/light". (IPv6 literal addresses uses [...] around the address in URIs before the port.)

farid4all87 commented 4 years ago

public class ExampleCrossProxy {

private static final int PORT = NetworkConfig.getStandard().getInt(NetworkConfig.Keys.COAP_PORT);

private CoapServer targetServerA;

public ExampleCrossProxy() throws IOException {
    ForwardingResource coap2coap = new ProxyCoapClientResource("coap2coap");
    ForwardingResource coap2http = new ProxyHttpClientResource("coap2http");

    // Create CoAP Server on PORT with proxy resources form CoAP to CoAP and HTTP
    targetServerA = new CoapServer(PORT);
    targetServerA.add(coap2coap);
    targetServerA.add(coap2http);
    targetServerA.add(new TargetResource("target"));
    targetServerA.start();

    ProxyHttpServer httpServer = new ProxyHttpServer(8080);
    httpServer.setProxyCoapResolver(new DirectProxyCoapResolver(coap2coap));

    System.out.println("CoAP resource \"target\" available over HTTP at: http://localhost:8080/proxy/coap://localhost:PORT/target");
}

/**
 * A simple resource that responds to GET requests with a small response
 * containing the resource's name.
 */
private static class TargetResource extends CoapResource {

   try{
    Request request = exchange.advanced().getRequest();
        System.out.println("Requested URI: " + request.getURI());
    URI uri = new URI(request.getURI());
    CoapClient client = new CoapClient();
    request = Request.newGet();
    request.setDestinationContext(new AddressEndpointContext(new InetSocketAddress("localhost", 5685))); // adapt "localhost" and port according your proxy
    request.setURI("coap://[aaaa::212:7400:13e3]:46c1/sensors/light:5683"); // adapt "localhost" and port according your coap-server
    CoapResponse response = client.advanced(request);
    if (response != null) {
        System.out.println(response.getResponseText());
    }
   } catch(URISyntaxException e){
        System.err.println("Failed to initialize");

   }

}

public static void main(String[] args) throws Exception {
    new ExampleCrossProxy();
}

} image

The code is not compling and showing "illegal start of type" error for try and catch function

boaks commented 4 years ago

I'm not sure, which version you're using. the one I recommended, is that.

ExampleCrossProxy

"coap://[aaaa::212:7400:13e3]:46c1/sensors/light:5683"

That's mixed up.

I don't know, why you want to implement the proxy as "none generic" one. With the PR I recommended, you may use the ExampleCrossProxy "out-of-the-box".

boaks commented 4 years ago
private static class TargetResource extends CoapResource {

   try{
    Request request = exchange.advanced().getRequest();
        System.out.println("Requested URI: " + request.getURI());
    URI uri = new URI(request.getURI());
    CoapClient client = new CoapClient();
    request = Request.newGet();
    request.setDestinationContext(new AddressEndpointContext(new InetSocketAddress("localhost", 5685))); // adapt "localhost" and port according your proxy
    request.setURI("coap://[aaaa::212:7400:13e3]:46c1/sensors/light:5683"); // adapt "localhost" and port according your coap-server
    CoapResponse response = client.advanced(request);
    if (response != null) {
        System.out.println(response.getResponseText());
    }
   } catch(URISyntaxException e){
        System.err.println("Failed to initialize");

   }

}

is no valid java. Nor a valid CoapResource implementation. I would recommend, that you use the ExampleCrossProxy of PR 1176.

(If you prefer to use the ExampleCrossProxy of the current master or release 2.0.0, the browser URI must be "coap://proxy:5683/coap2coap" replacing "proxy" with the address or hostname of your proxy.)

farid4all87 commented 4 years ago

[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.004 s - in org.eclipse.californium.core.test.ClientSynchronousTest [INFO] Running org.eclipse.californium.core.network.interceptors.AnonymizedOriginTracerTest [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.711 s - in org.eclipse.californium.core.network.interceptors.AnonymizedOriginTracerTest [INFO] [INFO] Results: [INFO] [ERROR] Failures: [ERROR] DeduplicationTest.testGET:136 Expected: is <2L> but: was <1L> [INFO] [ERROR] Tests run: 126, Failures: 1, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] Californium (Cf) Parent ............................ SUCCESS [ 5.416 s] [INFO] Californium (Cf) Custom Assembly Descriptors ....... SUCCESS [ 2.912 s] [INFO] Californium (Cf) Legal Documents ................... SUCCESS [ 1.040 s] [INFO] Californium (Cf) Demo Certificates ................. SUCCESS [ 0.551 s] [INFO] Californium (Cf) Element Connector ................. SUCCESS [ 35.165 s] [INFO] Scandium (Sc) Core ................................. SUCCESS [02:44 min] [INFO] Californium (Cf) Element Connector TCP netty ....... SUCCESS [ 42.506 s] [INFO] Californium (Cf) Core .............................. FAILURE [01:36 min] [INFO] Californium (Cf) Demo Applications ................. SKIPPED [INFO] Cf-NAT ............................................. SKIPPED [INFO] Californium (Cf) Integration Tests ................. SKIPPED [INFO] Californium (Cf) Proxy ............................. SKIPPED [INFO] Californium (Cf) OSGi .............................. SKIPPED [INFO] Cf-BenchmarkServer ................................. SKIPPED [INFO] Cf-ObserveBenchmarkClient .......................... SKIPPED [INFO] Cf-CoCoAClient ..................................... SKIPPED [INFO] Cf-PlugtestClient .................................. SKIPPED [INFO] Cf-ExtendedPlugtestClient .......................... SKIPPED [INFO] Cf-PlugtestServer .................................. SKIPPED [INFO] Cf-ExtendedPlugtestServer .......................... SKIPPED [INFO] Cf-HelloWorldClient ................................ SKIPPED [INFO] Cf-HelloWorldServer ................................ SKIPPED [INFO] Cf-PlugtestChecker ................................. SKIPPED [INFO] Cf-ExampleCrossProxy ............................... SKIPPED [INFO] Cf-SecureServer .................................... SKIPPED [INFO] Cf-SimpleFileServer ................................ SKIPPED [INFO] Californium (Cf) Demo Setup for Unix ............... SKIPPED [INFO] Sc-DTLS-Example-Client ............................. SKIPPED [INFO] Sc-DTLS-Example-Server ............................. SKIPPED [INFO] Cf-OSCORE .......................................... SKIPPED [INFO] Cf-PubSub .......................................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 05:53 min [INFO] Finished at: 2020-01-15T18:43:16-08:00 [INFO] Final Memory: 51M/190M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.1:test (medium-tests) on project californium-core: There are test failures.

when i run "mvn clean install" it fails to build.

boaks commented 4 years ago

Please, I still don't know, if you use the master or PR 1176.

The failure is a race condition in the new unit tests. You may either skip the tests with "-DskipTest=true" (in Eclipse IDE there is even a checkbox for that), or try to rerun the build.