2016-05-18 14 views
2

Ich arbeite an einer CoAP-App mit Eclipse Californium, die explizit nur den Root-Ressourcenpfad deklariert, und der Rest der Ressourcen sollte wie in REST durch einen Platzhalter /root/* bedient und aufgelöst werden APIs oder Servlets.Eclipse Californium CoAP Wildcard als URL-Pfad

Gibt es eine Möglichkeit, das zu erreichen?

Antwort

3

Ok, ich habe es geschafft.

Also nach ein paar Stunden des Grabens auf ihre Source-Code ist hier was getan.

Beachten Sie, dass es funktioniert, aber es ist nur zu zeigen, wie es getan werden könnte, es ist immer noch eine Arbeit über die Fortschritte (Ich tat dies in 3 h), wie ich einige Code wie Beobachter usw. entfernt ..

Sobald ich noch etwas Zeit, ich werde mir das Californium Api genauer anschauen und dieses generisch und optimiert machen Ich werde ein Github Projekt erstellen und hier verlinken.

1: Erstellen eines Modellklasse

public class ProxyRes { 

    public CoapResource coapRes; 
    public String path; 

    public ProxyRes() { 
    } 

    public CoapResource getCoapRes() { 
     return coapRes; 
    } 

    public void setCoapRes (CoapResource coapRes) { 
     this.coapRes = coapRes; 
    } 

    public String getPath() { 
     return path; 
    } 

    public void setPath (String path) { 
     this.path = path; 
    } 
} 

2: eine abstrakte CoapResource erstellen, die die Wildcards Liste

public abstract class AbstractResource extends CoapResource { 

    private LinkedList<String> wildcards; 

    protected AbstractResource (String name) { 
     super (name); 
    } 

    protected AbstractResource (String name, boolean visible) { 
     super (name, visible); 
    } 

    public LinkedList<String> getWildcards() { 
     return wildcards; 
    } 

    public void setWildcards (LinkedList<String> wildcards) { 
     this.wildcards = wildcards; 
    } 
} 

3 injizieren sollte: eine Temperatur Ressource erstellen Abstractverlauf

public class TemperatureResource extends AbstractResource { 

    public TemperatureResource() { 
     super (ResourceSpecs.House.Sensors.Temperature); 

     getAttributes().setTitle ("Temperature resource !"); 
    } 

    @Override 
    public void handleGET (CoapExchange exchange) { 
     String response = "The temperature"; 
     if (getWildcard() != null) { 
      response += " of the " + getWildcard().get (0) + " on the " + getWildcard().get (1); 
     } 
     response += " is : 25 degree C"; 

     exchange.respond (response); 
    } 
} 

4: Erstellen Sie ein Ressourcenverzeichnis im Stammverzeichnis meines Eclipse-Projekts mit j Sohn conf Dateien meiner Ressourcen

{ 
    "verb": "get", 
    "endpoint": "/houses/*/rooms/*/sensors/temperature", 

    "class": "com.wild.coap.resources.TemperatureResource" 
} 

5: eine Ressourcen Loader (Klasse, die die Spezifikationen Definition der Ressourcen geladen werden und sie unabhängig instanziiert stattdessen einen Baum auf dem Server zu erstellen) erstellen

public class ResourcesLoader { 

    private final static String Path = new File (".").getAbsolutePath() + File.separator + "resources"; 

    private List<ProxyRes> resourcesList; 

    public ResourcesLoader() throws Exception { 
     resourcesList = new ArrayList<ProxyRes>(); 

     File resources = new File (Path); 
     for (String resName : resources.list()) { 
      File resFile = new File (resources, resName); 
      InputStream is = new FileInputStream (resFile); 
      JsonObject o = new JsonObject (is); 

      resourcesArr.add (o); 
      resourcesList.add (buildObject (o)); 
     } 
    } 

    private ProxyRes buildObject (JsonObject o) throws ClassNotFoundException, InstantiationException, IllegalAccessException { 
     ProxyRes r = new ProxyRes(); 
     r.setPath (o.getString ("endpoint")); 

     Class<?> clazz = Class.forName (o.getString ("class")); 
     CoapResource coapRes = (CoapResource)clazz.newInstance(); 
     r.setCoapRes (coapRes); 

     return r; 
    } 

    public List<ProxyRes> getResourcesList() { 
     return resourcesList; 
    } 
} 

6: erstellen eines benutzerdefinierten MessageDelieverer

public class DynamicMessageDeliverer implements MessageDeliverer { 

    private final List<ProxyRes> resources; 

    public DynamicMessageDeliverer (List<ProxyRes> resources) { 
     this.resources = resources; 
    } 

    public void deliverRequest (final Exchange exchange) { 
     Request request   = exchange.getRequest(); 
     List<String> path  = request.getOptions().getUriPath(); 

     final Resource resource = registerResources (path);  
     if (resource != null) { 
      executeResource (exchange, resource);   
     } else { 
      exchange.sendResponse (new Response (ResponseCode.NOT_FOUND)); 
      throw new RuntimeException ("Did not find resource " + path.toString() + " requested by " + request.getSource()+":"+request.getSourcePort()); 
     } 
    } 

    private void executeResource (final Exchange exchange, final Resource resource) { 
     // Get the executor and let it process the request 
     Executor executor = resource.getExecutor(); 
     if (executor != null) { 
      exchange.setCustomExecutor(); 
      executor.execute (new Runnable() { 

       public void run() { 
        resource.handleRequest (exchange); 
       } 
      }); 
     } else { 
      resource.handleRequest (exchange); 
     } 
    } 

    private Resource registerResources (List<String> list) { 
     LinkedList<String> path   = new LinkedList<String> (list); 
     String flatRequestedEndpoint = Arrays.toString (path.toArray()); 
     LinkedList<String> wildcards = new LinkedList <String>(); 
     ProxyRes retainedResource  = null; 

     for (ProxyRes proxyRes : resources) { 
      String[] res = proxyRes.getPath().replaceFirst ("/", "").split ("/"); 

      int length = res.length; 
      if (length != path.size()) { 
       continue; 
      } 

      String flatResEndpoint = Arrays.toString (res); 
      if (flatResEndpoint.equals (flatRequestedEndpoint)) { 
       retainedResource = proxyRes; 
       break; 
      } 

      boolean match = true; 

      for (int i = 0; i < length; i ++) { 
       String str = res[i]; 
       if (str.equals ("*")) { 
        wildcards.add (path.get (i)); 
        continue; 
       } 

       if (!str.equals (path.get (i))) { 
        match = false; 
        break; 
       } 
      } 

      if (!match) { 
       wildcards.clear(); 
       continue; 
      } 

      retainedResource = proxyRes; 
      break; 
     } 

     if (retainedResource == null) { 
      return null; 
     } 

     ((AbstractResource)retainedResource.getCoapRes()).setWildcard (wildcards); 
     return retainedResource.getCoapRes(); 
    } 

    public void deliverResponse (Exchange exchange, Response response) { 
     if (response == null) throw new NullPointerException(); 
     if (exchange == null) throw new NullPointerException(); 
     if (exchange.getRequest() == null) throw new NullPointerException(); 
     exchange.getRequest().setResponse(response); 
     Request request   = exchange.getRequest(); 
     List<String> path  = request.getOptions().getUriPath(); 
     System.out.println ("Path retrieved : " + Arrays.toString (path.toArray())); 
    } 
} 

7: erstellen Sie den Server

public class WildCoapServer extends CoapServer { 

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

    public WildCoapServer() throws Exception { 

     // add endpoints on all IP addresses 
     addEndpoints(); 

     ResourcesLoader resLoader = new ResourcesLoader(); 
     List<ProxyRes> resources = resLoader.getResourcesList(); 

     setMessageDeliverer (new DynamicMessageDeliverer (resources)); 
    } 

    @Override 
    protected Resource createRoot() { 
     return new WildRootResource(); 
    } 

    // Add individual endpoints listening on default CoAP port on all IPv4 addresses of all network interfaces. 
    private void addEndpoints() { 
     for (InetAddress addr : EndpointManager.getEndpointManager().getNetworkInterfaces()) { 
      // only binds to IPv4 addresses and localhost 
      if (addr instanceof Inet4Address || addr.isLoopbackAddress()) { 
       InetSocketAddress bindToAddress = new InetSocketAddress (addr, COAP_PORT); 
       addEndpoint (new CoapEndpoint (bindToAddress)); 
      } 
     } 
    } 
} 

8: Starten Sie den Server

public class Main { 

    public static void main (String[] args) { 

     try { 
      WildCoapServer server = new WildCoapServer(); 
      server.start(); 
     } catch (Exception e) { 
      throw new RuntimeException (e.getMessage(), e); 
     } 
    } 
} 

9: Verbrauchen die Temperatur Ressource von einem Client

public class Client { 

    public static void main (String[] args) { 

     URI uri = null; 
     try { 
      uri = new URI ("coap://192.168.200.1:5683/houses/house1/rooms/kitchen/sensors/temperature"); 
     } catch (URISyntaxException e) { 
      throw new RuntimeException (e.getMessage(), e); 
     } 

     CoapClient client  = new CoapClient (uri); 

     CoapResponse response = client.get(); 

     if (response != null) { 

      System.out.println (response.getCode()); 
      System.out.println (response.getOptions()); 
      System.out.println (response.getResponseText()); 

      System.out.println ("\nADVANCED\n"); 
      // access advanced API with access to more details through .advanced() 
      System.out.println (Utils.prettyPrint (response)); 

     } else { 
      System.out.println ("No response received."); 
     }  
    } 
} 

Hoffnung, dass jemand hilft.