resource registry for CoAP servers
Project: http://git-wip-us.apache.org/repos/asf/mina/repo Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/48773262 Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/48773262 Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/48773262 Branch: refs/heads/trunk Commit: 487732628f2378205120fbc04985164a4e1ba89c Parents: f180462 Author: jvermillard <[email protected]> Authored: Sun May 26 17:15:05 2013 +0200 Committer: jvermillard <[email protected]> Committed: Sun May 26 17:15:05 2013 +0200 ---------------------------------------------------------------------- .../org/apache/mina/coap/codec/CoapDecoder.java | 6 +- .../org/apache/mina/coap/codec/CoapEncoder.java | 2 +- .../coap/resource/AbstractResourceHandler.java | 53 +++++++ .../apache/mina/coap/resource/CoapResponse.java | 74 ++++++++++ .../apache/mina/coap/resource/ResourceHandler.java | 35 +++++ .../mina/coap/resource/ResourceRegistry.java | 114 +++++++++++++++ 6 files changed, 280 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/codec/CoapDecoder.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/codec/CoapDecoder.java b/coap/src/main/java/org/apache/mina/coap/codec/CoapDecoder.java index 772a107..e47e93b 100644 --- a/coap/src/main/java/org/apache/mina/coap/codec/CoapDecoder.java +++ b/coap/src/main/java/org/apache/mina/coap/codec/CoapDecoder.java @@ -60,10 +60,10 @@ public class CoapDecoder implements StatelessProtocolDecoder<ByteBuffer, CoapMes */ @Override public CoapMessage decode(ByteBuffer input, Void context) { - // LOG.debug("decode"); + LOG.debug("decode"); if (input.remaining() <= 0) { - // LOG.debug("nothing to decode"); + LOG.debug("nothing to decode"); return null; } int byte0 = input.get() & 0xFF; @@ -142,7 +142,7 @@ public class CoapDecoder implements StatelessProtocolDecoder<ByteBuffer, CoapMes return value; } else if (value == 13) { // if (LOG.isDebugEnabled()) { - int val = input.get(input.position()) & 0xFF; + // int val = input.get(input.position()) & 0xFF; // LOG.debug("byte : {}", val); // } return (input.get() & 0xFF) + 13; http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/codec/CoapEncoder.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/codec/CoapEncoder.java b/coap/src/main/java/org/apache/mina/coap/codec/CoapEncoder.java index 1e15da3..63ab87f 100644 --- a/coap/src/main/java/org/apache/mina/coap/codec/CoapEncoder.java +++ b/coap/src/main/java/org/apache/mina/coap/codec/CoapEncoder.java @@ -55,7 +55,7 @@ public class CoapEncoder implements StatelessProtocolEncoder<CoapMessage, ByteBu @Override public ByteBuffer encode(CoapMessage message, Void context) { - // LOG.debug("encoding {}", message); + LOG.debug("encoding {}", message); // compute size of the needed buffer int size = HEADER_SIZE + message.getToken().length; http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/resource/AbstractResourceHandler.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/resource/AbstractResourceHandler.java b/coap/src/main/java/org/apache/mina/coap/resource/AbstractResourceHandler.java new file mode 100644 index 0000000..4885a99 --- /dev/null +++ b/coap/src/main/java/org/apache/mina/coap/resource/AbstractResourceHandler.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.coap.resource; + +/** + * + * @author <a href="http://mina.apache.org">Apache MINA Project</a> + */ +public abstract class AbstractResourceHandler implements ResourceHandler { + + /** + * {@inheritDoc} + */ + @Override + public String getInterface() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getResourceType() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getTittle() { + // TODO Auto-generated method stub + return null; + } + +} http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/resource/CoapResponse.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/resource/CoapResponse.java b/coap/src/main/java/org/apache/mina/coap/resource/CoapResponse.java new file mode 100644 index 0000000..c788837 --- /dev/null +++ b/coap/src/main/java/org/apache/mina/coap/resource/CoapResponse.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.coap.resource; + +import java.util.Arrays; + +import org.apache.mina.coap.CoapOption; + +/** + * Response to a coap request. + * + * @author <a href="http://mina.apache.org">Apache MINA Project</a> + */ +public class CoapResponse { + + public int code; + public byte[] content; + + public CoapOption[] options; + + public CoapResponse(int code, byte[] content, CoapOption... options) { + super(); + this.code = code; + this.content = content; + this.options = options; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public byte[] getContent() { + return content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + public CoapOption[] getOptions() { + return options; + } + + public void setOptions(CoapOption[] options) { + this.options = options; + } + + @Override + public String toString() { + return "CoapResponse [code=" + code + ", content=" + Arrays.toString(content) + ", options=" + + Arrays.toString(options) + "]"; + } +} http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/resource/ResourceHandler.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/resource/ResourceHandler.java b/coap/src/main/java/org/apache/mina/coap/resource/ResourceHandler.java new file mode 100644 index 0000000..fa9aa32 --- /dev/null +++ b/coap/src/main/java/org/apache/mina/coap/resource/ResourceHandler.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.coap.resource; + +import org.apache.mina.coap.CoapMessage; + +public interface ResourceHandler { + + public String getPath(); + + public String getTittle(); + + public String getInterface(); + + public String getResourceType(); + + public CoapResponse handle(CoapMessage request); +} http://git-wip-us.apache.org/repos/asf/mina/blob/48773262/coap/src/main/java/org/apache/mina/coap/resource/ResourceRegistry.java ---------------------------------------------------------------------- diff --git a/coap/src/main/java/org/apache/mina/coap/resource/ResourceRegistry.java b/coap/src/main/java/org/apache/mina/coap/resource/ResourceRegistry.java new file mode 100644 index 0000000..5e74da0 --- /dev/null +++ b/coap/src/main/java/org/apache/mina/coap/resource/ResourceRegistry.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.coap.resource; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.mina.coap.CoapCode; +import org.apache.mina.coap.CoapMessage; +import org.apache.mina.coap.CoapOption; +import org.apache.mina.coap.CoapOptionType; +import org.apache.mina.coap.MessageType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceRegistry { + + private static final Logger LOG = LoggerFactory.getLogger(ResourceRegistry.class); + + private Map<String, ResourceHandler> handlers = new HashMap<String, ResourceHandler>(); + + public void register(ResourceHandler handler) { + handlers.put(handler.getPath(), handler); + } + + public CoapMessage respond(CoapMessage request) { + // find the URI + StringBuilder urlBuilder = new StringBuilder(""); + for (CoapOption opt : request.getOptions()) { + if (opt.getType() == CoapOptionType.URI_PATH) { + if (urlBuilder.length() > 0) { + urlBuilder.append("/"); + } + urlBuilder.append(opt.getData()); + } + } + + String url = urlBuilder.toString(); + LOG.debug("requested URL : {}", url); + + if (url.length() < 1) { + // 4.00 ! + return new CoapMessage(1, MessageType.ACK, CoapCode.BAD_REQUEST.getCode(), request.getId(), + request.getToken(), new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT, + new byte[] { 0 }) }, "no URL !".getBytes()); + } + if (".well-known/core".equalsIgnoreCase(url)) { + // discovery ! + return new CoapMessage(1, MessageType.ACK, CoapCode.CONTENT.getCode(), request.getId(), request.getToken(), + new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT, new byte[] { 40 }) }, + getDiscovery()); + } else { + ResourceHandler handler = handlers.get(url); + if (handler == null) { + // 4.04 ! + return new CoapMessage(1, MessageType.ACK, CoapCode.NOT_FOUND.getCode(), request.getId(), + request.getToken(), new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT, + new byte[] { 0 }) }, "meh !".getBytes()); + } else { + CoapResponse response = handler.handle(request); + return new CoapMessage(1, request.getType() == MessageType.CONFIRMABLE ? MessageType.ACK + : MessageType.NON_CONFIRMABLE, response.getCode(), request.getId(), request.getToken(), + response.getOptions(), response.getContent()); + } + } + } + + private byte[] getDiscovery() { + StringBuilder b = new StringBuilder(); + boolean first = true; + for (Map.Entry<String, ResourceHandler> e : handlers.entrySet()) { + // ex :</link1>;if="If1";rt="Type1 Type2";title="Link test resource", + if (first) { + first = false; + } else { + b.append(","); + } + ResourceHandler h = e.getValue(); + b.append("</").append(h.getPath()).append(">"); + if (h.getInterface() != null) { + b.append(";if=\"").append(h.getInterface()).append("\""); + } + if (h.getResourceType() != null) { + b.append(";rt=\"").append(h.getResourceType()).append("\""); + } + if (h.getTittle() != null) { + b.append(";title=\"").append(h.getTittle()).append("\""); + } + } + try { + return b.toString().getBytes("UTF-8"); + } catch (UnsupportedEncodingException e1) { + throw new IllegalStateException("no UTF-8 codec", e1); + } + } +}
