Eclipse Californium CoAP通配符作为URL路径 [英] Eclipse Californium CoAP wildcard as url path

查看:492
本文介绍了Eclipse Californium CoAP通配符作为URL路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Eclipse Californium进行CoAP应用程序,它将仅显式声明根资源路径,其余的资源应通过通配符 / root / * 就像在REST API或servlet上一样。



有没有办法实现?

解决方案

好的,我设法做到了。



所以经过几个小时挖掘他们的源代码,这里是最后做的。



注意它是有效的,但它只是为了显示如何完成,它仍然是一个进步的工作(我在3h中这样做),因为我删除了一些代码,如观察者等等。



一旦我有一段时间,我将更多地挖掘到Californium Api,并进行通用和优化,我将创建一个Github项目和链接在这里。



1:创建一个模型类



  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:创建一个应该注入通配符的抽象CoapResource列表



  public abstract class AbstractResource extends CoapResource {

private LinkedList< String>通配符;

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

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

public LinkedList< String> getWildcards(){
返回通配符;
}

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



3:创建一个扩展AbstractResource的温度资源



  public class TemperatureResource extends AbstractResource {

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

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

@Override
public void handleGET(CoapExchange exchange){
String response =温度;
if(getWildcard()!= null){
response + =of+ getWildcard().get(0)+on+ getWildcard().get(1);
}
回复+ =是:25度C;

exchange.respond(response);
}
}



4:在我的根目录下创建一个资源目录eclipse项目,我的资源的json conf文件



  {
动词:get,
终点:/ houses / * / rooms / * / sensors / temperature,

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



5:创建资源加载程序(将加载资源的规范定义的类,并独立实例化它们,在服务器上创建一个树)



  public class ResourcesLoader {

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

私人列表< ProxyRes> resourcesList;

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

文件资源=新建文件(路径);
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:创建自定义MessageDelieverer



  public class DynamicMessageDeliverer implements MessageDeliverer {

private final List< ProxyRes>资源;

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

public void deliverRequest(final Exchange exchange){
请求请求= exchange.getRequest();
列表< String> path = request.getOptions().getUriPath();

final资源资源= registerResources(path);
if(resource!= null){
executeResource(exchange,resource);
} else {
exchange.sendResponse(new Response(ResponseCode.NOT_FOUND));
throw new RuntimeException(没有找到资源+ path.toString()+请求+ request.getSource()+:+ request.getSourcePort());
}
}

private void executeResource(最终Exchange交换,最终资源资源){
//获取执行程序并让其处理请求
执行者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> (名单);
String flatRequestedEndpoint = Arrays.toString(path.toArray());
LinkedList< String> wildcards = new LinkedList< String> ();
ProxyRes reservedResource = null;

(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)){
retainResource = proxyRes;
break;
}

boolean match = true; (int i = 0; i< length; i ++){
String str = res [i];


if(str.equals(*)){
wildcards.add(path.get(i));
继续;
}

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

if(!match){
wildcards.clear();
继续;
}

retainResource = proxyRes;
break;
}

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

((AbstractResource)retainResource.getCoapRes())。setWildcard(通配符);
return retainResource.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);
请求请求= exchange.getRequest();
列表< String> path = request.getOptions().getUriPath();
System.out.println(Path retrieval:+ Arrays.toString(path.toArray()));
}
}



7:创建服务器



  public class WildCoapServer扩展CoapServer {

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

public WildCoapServer()throws Exception {

//在所有IP地址上添加端点
addEndpoints();

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

setMessageDeliverer(new DynamicMessageDeliverer(resources));
}

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

//添加在所有网络接口的所有IPv4地址上侦听默认CoAP端口的各个端点。
private void addEndpoints(){
for(InetAddress addr:EndpointManager.getEndpointManager().getNetworkInterfaces()){
//仅绑定到IPv4地址和localhost
if(addr instanceof Inet4Address || addr.isLoopbackAddress()){
InetSocketAddress bindToAddress = new InetSocketAddress(addr,COAP_PORT);
addEndpoint(new CoapEndpoint(bindToAddress));
}
}
}
}



8 :启动服务器



  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:消耗温度资源从客户端



  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(\\\
ADVANCED\\\
);
//访问高级API,通过.advanced()获取更多详细信息
System.out.println(Utils.prettyPrint(response));

} else {
System.out.println(没有收到回复);
}
}
}

希望帮助某人。 / p>

I'm working on a CoAP app using Eclipse Californium that will declare explicitly only the root resource path, and the rest of the resources should be served and resolved through a wildcard /root/* just like on REST APIs or servlets.

Is there any way to achieve that ?

解决方案

Ok I managed to do it.

So after a few hours of digging on their Source code here is what ended up doing.

Note that it works but it's only to show how it could be done, it's still a work on progress (I did this in 3h) as I removed some code like observer etc..

As soon as I have some time, I'll digg onto the Californium Api more and make this generic and optimized I'll create a Github project and link it here.

1 : Create a model class

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 : Create an abstract CoapResource that should inject the Wildcards list

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 : Create a Temperature Resource extending AbstractResource

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 : Create a resources directory on the root of my eclipse project, with json conf files of my resources

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

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

5 : Create a Resources Loader (class that will load the specs definition of the resources and instantiate them independently instead of creating a Tree on the server)

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 : Create a Custom 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 : Create the 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 : Start the 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 : Consume the Temperature resource from a 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.");
        }       
    }
}

Hope that helps someone.

这篇关于Eclipse Californium CoAP通配符作为URL路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆