Commit 8341f133 authored by Björn Butzin's avatar Björn Butzin
Browse files

removed

 - CoapChannelListener.java -> empty and unused (updated CoapClient and CoapServer accordingly)
modified
 - documentation (CoapResource)
 - cleanup (CoapResponseCode, CoapRequestCode, CoapPacketType )
 - added first test setting (InterfaceTest)
 - ResourceServer Interface now extends CoapServer (instead of being parallel)
 - ToDo's: removed already finished ToDo's, added some Fixme's for potential null pointer access
parent 93e1d23f
......@@ -115,7 +115,6 @@ public class BasicCoapChannelManager implements CoapChannelManager {
e.printStackTrace();
}
} else {
/* TODO: (solved?) raise exception: address already in use */
throw new IllegalStateException("address already in use");
}
}
......
......@@ -397,6 +397,7 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
return;
} else {
msg.setChannel( channel );
//FIXME channel may be null
channel.handleMCResponse(msg, addr.getAddress(), addr.getPort() );
return;
}
......
......@@ -30,7 +30,6 @@ public interface CoapChannel {
*/
public void sendMessage(CoapMessage msg);
/* TODO: close when finished, & abort() */
/**
*
*/
......
/* Copyright 2015 University of Rostock
*
* Licensed 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.ws4d.coap.interfaces;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
*/
public interface CoapChannelListener {
}
......@@ -63,7 +63,6 @@ public interface CoapChannelManager {
* @param port
* @return
*/
// TODO: (solved?) allow client to bind to a special port
public CoapClientChannel connect(CoapClient client, InetAddress addr,
int port);
......
......@@ -20,7 +20,7 @@ import java.net.InetAddress;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
*/
public interface CoapClient extends CoapChannelListener {
public interface CoapClient{
/**
* This is a callback method which allows to handle a response at the application layer.
......
......@@ -18,7 +18,7 @@ package org.ws4d.coap.interfaces;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
*/
public interface CoapServer extends CoapChannelListener {
public interface CoapServer{
/**
*
......
......@@ -25,6 +25,7 @@ import org.apache.log4j.Logger;
import org.ws4d.coap.connection.BasicCoapChannelManager;
import org.ws4d.coap.interfaces.CoapChannel;
import org.ws4d.coap.interfaces.CoapMessage;
import org.ws4d.coap.tools.Encoder;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
......@@ -178,6 +179,7 @@ public abstract class AbstractCoapMessage implements CoapMessage {
/* copy serialized options to the final array */
int offset = HEADER_LENGTH + tokenLength;
for (int i = 0; i < optionsLength; i++)
//FIXME optionsArray may be null
serializedPacket[i + offset] = optionsArray[i];
/* insert payload marker */
......@@ -237,10 +239,7 @@ public abstract class AbstractCoapMessage implements CoapMessage {
@Override
public CoapMediaType getContentType(){
CoapHeaderOption option = options.getOption(CoapHeaderOptionType.Content_Format);
if (option == null){
/* not content type TODO: return UNKNOWN ?*/
return null;
}
if (option == null) return CoapMediaType.UNKNOWN;
/* no need to check length, CoapMediaType parse function will do*/
int mediaTypeCode = (int) coapUint2Long(options.getOption(CoapHeaderOptionType.Content_Format).getOptionData());
return CoapMediaType.parse(mediaTypeCode);
......@@ -679,6 +678,7 @@ public abstract class AbstractCoapMessage implements CoapMessage {
@Override
public String toString() {
String test = Encoder.ByteToString(optionData);
char[] printableOptionValue = new char[optionData.length];
for (int i = 0; i < optionData.length; i++)
printableOptionValue[i] = (char) optionData[i];
......
......@@ -66,6 +66,6 @@ public enum CoapPacketType {
* @return The packetType of the ENUM element.
*/
public int getValue() {
return packetType;
return this.packetType;
}
}
......@@ -36,7 +36,7 @@ public enum CoapRequestCode {
* @return The method code of the ENUM element.
*/
public int getValue() {
return code;
return this.code;
}
/**
......@@ -54,20 +54,4 @@ public enum CoapRequestCode {
throw new IllegalArgumentException("Invalid Request Code");
}
}
//TODO can be removed as it is the same as the super implementation
// @Override
// public String toString() {
// switch (this) {
// case GET:
// return "GET";
// case POST:
// return "POST";
// case PUT:
// return "PUT";
// case DELETE:
// return "DELETE";
// }
// return null;
// }
}
......@@ -21,7 +21,6 @@ package org.ws4d.coap.messages;
* @author Bjoern Konieczek <bjoern.konieczek@uni-rostock.de>
* @author Christian Lerche <christian.lerche@uni-rostock.de>
*/
public enum CoapResponseCode {
//Success 2.xx
......@@ -31,7 +30,7 @@ public enum CoapResponseCode {
Changed_204(68),
Content_205(69),
//FIXME: Where is it defined? NOT part of rfc7252!
//Block-wise transfers in CoAP draft-ietf-core-block-18
Continue_231(95),
//Client Error 4.xx
......@@ -42,6 +41,7 @@ public enum CoapResponseCode {
Not_Found_404(132),
Method_Not_Allowed_405(133),
Not_Acceptable_406(134),
//TODO correct? Request_Entity_Incomplete_408(?136?),
Precondition_Failed_412(140),
Request_Entity_To_Large_413(141),
Unsupported_Media_Type_415(143),
......@@ -102,9 +102,8 @@ public enum CoapResponseCode {
default:
if (codeValue >= 64 && codeValue <= 191) {
return UNKNOWN;
} else {
throw new IllegalArgumentException("Invalid Response Code");
}
throw new IllegalArgumentException("Invalid Response Code");
}
}
......@@ -112,37 +111,7 @@ public enum CoapResponseCode {
* @return The codeValue of the ENUM element.
*/
public int getValue() {
return code;
}
//FIXME: can be removed as it is the same as the super implementation
@Override
public String toString() {
switch (this) {
case Created_201: return "Created_201";
case Deleted_202: return "Deleted_202";
case Valid_203: return "Valid_203";
case Changed_204: return "Changed_204";
case Content_205: return "Content_205";
case Continue_231: return "Continue_231";
case Bad_Request_400: return "Bad_Request_400";
case Unauthorized_401: return "Unauthorized_401";
case Bad_Option_402: return "Bad_Option_402";
case Forbidden_403: return "Forbidden_403";
case Not_Found_404: return "Not_Found_404";
case Method_Not_Allowed_405: return "Method_Not_Allowed_405";
case Not_Acceptable_406: return "Not_Acceptable_406";
case Precondition_Failed_412: return "Precondition_Failed_412";
case Request_Entity_To_Large_413: return "Request_Entity_To_Large_413";
case Unsupported_Media_Type_415: return "Unsupported_Media_Type_415";
case Internal_Server_Error_500: return "Internal_Server_Error_500";
case Not_Implemented_501: return "Not_Implemented_501";
case Bad_Gateway_502: return "Bad_Gateway_502";
case Service_Unavailable_503: return "Service_Unavailable_503";
case Gateway_Timeout_504: return "Gateway_Timeout_504";
case Proxying_Not_Supported_505: return "Proxying_Not_Supported_505";
default: return "Unknown_Response_Code";
}
return this.code;
}
}
......
......@@ -22,6 +22,9 @@ import org.ws4d.coap.interfaces.CoapRequest;
import org.ws4d.coap.messages.CoapMediaType;
/**
* A CoapResource takes care of the resources content, its permissions and observers.
* In order to be served over a network connection it needs to be added to a {@link ResourceServer}
*
* @author Nico Laum <nico.laum@uni-rostock.de>
* @author Christian Lerche <christian.lerche@uni-rostock.de>
* @author Björn Butzin <bjoern.butzin@uni-rostock.de>
......
......@@ -44,7 +44,7 @@ import org.ws4d.coap.messages.CoapResponseCode;
* @author Bjrn Konieczek <bjoern.konieczek@uni-rostock.de>
* @author Bjrn Butzin <bjoern.butzin@uni-rostock.de>
*/
public class CoapResourceServer implements CoapServer, ResourceServer {
public class CoapResourceServer implements ResourceServer {
private final static Logger logger = Logger.getLogger(CoapResourceServer.class);
private int port = 0;
private Map<String, byte[]> etags = new HashMap<String, byte[]>();
......@@ -141,6 +141,7 @@ public class CoapResourceServer implements CoapServer, ResourceServer {
this.resources.clear();
this.etags.clear();
this.coreResource = null;
//FIXME causes java.nio.channels.ClosedChannelException when starting the server again
BasicCoapChannelManager.getInstance().removeServerListener(this, this.port);
}
......
......@@ -19,16 +19,16 @@ import java.net.URI;
import java.util.Map;
import org.ws4d.coap.interfaces.CoapRequest;
import org.ws4d.coap.interfaces.CoapServer;
/**
* A ResourceServer provides network access to resources via a network protocol
* such as HTTP or CoAP.
* A ResourceServer manages resources, takes care of resource permissions and handles GET, POST, PUT and DELETE requests.
*
* @author Nico Laum <nico.laum@uni-rostock.de>
* @author Christian Lerche <christian.lerche@uni-rostock.de>
* @author Björn Butzin <bjoern.butzin@uni-rostock.de>
*/
public interface ResourceServer {
public interface ResourceServer extends CoapServer {
/**
* Creates a resource. Resource must not exist.
......@@ -66,13 +66,13 @@ public interface ResourceServer {
public boolean deleteResource(String path);
/**
* Start the ResourceServer. This usually opens network ports and makes the
* Start the ResourceServer. This usually opens network connections and makes the
* resources available through a certain network protocol.
*/
public void start() throws Exception;
/**
* Stops the ResourceServer. This usually closes network ports and makes the
* Stops the ResourceServer. This usually closes network connections and makes the
* resources unavailable through on the network.
*/
public void stop();
......
......@@ -26,21 +26,12 @@ import org.ws4d.coap.rest.CoapResource;
import org.ws4d.coap.rest.CoapResourceServer;
/**
* Tests for jCoAP.
*
* @author Bjrn Butzin <bjoern.butzin[at]uni-rostock.de>
*/
public class BasicResourceTest {
private static CoapResourceServer resourceServer;
// @Test //indicates a test method
// @Test(expected= IndexOutOfBoundsException.class) //indicates a test
// method expecting an exception
// @Test(timeout=1000) //indicates a test method that fails after 1000
// milliseconds execution time
// org.junit.Assert.* // compare result & expectation
/*
* ########################################################################
* General Test preparations
......@@ -84,6 +75,12 @@ public class BasicResourceTest {
/*
* ########################################################################
* Tests
*
* @Test
* @Test(expected= IndexOutOfBoundsException.class)
* @Test(timeout=1000) - fails after 1000 milliseconds
* org.junit.Assert.* - compare result & expectation
*
* ########################################################################
*/
......
......@@ -20,35 +20,33 @@ import java.net.UnknownHostException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ws4d.coap.Constants;
import org.ws4d.coap.connection.BasicCoapChannelManager;
import org.ws4d.coap.interfaces.CoapChannelManager;
import org.ws4d.coap.interfaces.CoapClient;
import org.ws4d.coap.interfaces.CoapClientChannel;
import org.ws4d.coap.interfaces.CoapRequest;
import org.ws4d.coap.interfaces.CoapResponse;
import org.ws4d.coap.messages.CoapMediaType;
import org.ws4d.coap.messages.CoapRequestCode;
import org.ws4d.coap.rest.BasicCoapResource;
import org.ws4d.coap.rest.CoapResourceServer;
import org.ws4d.coap.tools.Encoder;
/**
* Tests for jCoAP.
*
* @author Bjrn Butzin <bjoern.butzin[at]uni-rostock.de>
*/
public class InterfaceTest {
private static CoapResourceServer resourceServer;
private static CoapClientChannel clientChannel;
private static ClientDummy client;
private static CoapChannelManager channelManager;
private static InetAddress inetAddress;
private ClientDummy client;
//private static CoapChannelManager channelManager;
//private static InetAddress inetAddress;
// @Test //indicates a test method
// @Test(expected= IndexOutOfBoundsException.class) //indicates a test
// method expecting an exception
// @Test(timeout=1000) //indicates a test method that fails after 1000
// milliseconds execution time
// org.junit.Assert.* // compare result & expectation
static CoapResponse receivedResponse = null;
/*
* ########################################################################
......@@ -62,7 +60,6 @@ public class InterfaceTest {
resourceServer.stop();
}
resourceServer = new CoapResourceServer();
}
@AfterClass
......@@ -77,15 +74,15 @@ public class InterfaceTest {
@Before
public void setUp() {
// set up client
receivedResponse = null;
this.client = new ClientDummy();
try {
client = new ClientDummy();
clientChannel = BasicCoapChannelManager.getInstance()
.connect(client, InetAddress.getByName("127.0.0.1"), Constants.COAP_DEFAULT_PORT);
.connect(this.client, InetAddress.getByName("127.0.0.1"), Constants.COAP_DEFAULT_PORT);
} catch (UnknownHostException e) {
System.err.println(e.getLocalizedMessage());
System.exit(-1);
}
// set up server
try {
resourceServer.start();
......@@ -102,8 +99,7 @@ public class InterfaceTest {
clientChannel.close();
clientChannel = null;
}
client = null;
this.client = null;
// reset server
resourceServer.stop();
}
......@@ -111,12 +107,67 @@ public class InterfaceTest {
/*
* ########################################################################
* Tests
*
* @Test
* @Test(expected= IndexOutOfBoundsException.class)
* @Test(timeout=1000) - fails after 1000 milliseconds
* org.junit.Assert.* - compare result & expectation
*
* ########################################################################
*
* Considerations: (/.well-known/core) (GET / OBSERVE, POST, PUT, DELETE)
* Blockwise Transfer
* (/.well-known/core)
* full query
* query filter
* rt - single multiple
* if - single multiple
* href - single multiple
* combinations
* encoding
* + %
* GET
* without eTag
* with eTag
* matching
* non matching
* POST
* PUT
* If-Match
* If-Non-Match
* DELETE
*/
@Test
public void wellKnownFull() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1","content1", CoapMediaType.text_plain)
.setResourceType("resource1Type")
.setInterfaceDescription("resource1Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core");
clientChannel.sendMessage(request);
while(null == receivedResponse) Thread.sleep(10);
Assert.assertEquals("</.well-known/core>,</resource1>;rt=\"resource1Type\";if=\"resource1Description\"", Encoder.ByteToString(receivedResponse.getPayload()));
}
@Test
public void wellKnownRT() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1","content1", CoapMediaType.text_plain)
.setResourceType("resource1Type")
.setInterfaceDescription("resource1Description"));
resourceServer.createResource(new BasicCoapResource("/resource2","content2", CoapMediaType.text_plain)
.setResourceType("resource2Type")
.setInterfaceDescription("resource2Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core?rt=resource1Type");
clientChannel.sendMessage(request);
while(null == receivedResponse) Thread.sleep(10);
Assert.assertEquals("</resource1>;rt=\"resource1Type\";if=\"resource1Description\"", Encoder.ByteToString(receivedResponse.getPayload()));
}
/*
......@@ -126,25 +177,24 @@ public class InterfaceTest {
*/
private class ClientDummy implements CoapClient {
public ClientDummy(){
// This is intended to be empty
}
@Override
public void onResponse(CoapClientChannel channel, CoapResponse response) {
public ClientDummy() {
// This is intended to be empty
}
@Override
public void onMCResponse(CoapClientChannel channel, CoapResponse response, InetAddress srcAddress,
int srcPort) {
// This is intended to be empty
}
@Override
public void onConnectionFailed(CoapClientChannel channel, boolean notReachable, boolean resetByServer) {
// This is intended to be empty
}
public void onResponse(CoapClientChannel channel, CoapResponse response) {
InterfaceTest.receivedResponse = response;
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment