Commit 9e3abe1e authored by Björn Butzin's avatar Björn Butzin
Browse files

moved to maven build; changed to log4j2 aligned package structure to...

moved to maven build; changed to log4j2 aligned package structure to jcoap.core; adapt to jcoap.core changes
parent faa35acb
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry combineaccessrules="false" kind="src" path="/ws4d-jcoap"/>
<classpathentry kind="lib" path="Referenced Libraries/commons-codec-1.4.jar"/>
<classpathentry kind="lib" path="Referenced Libraries/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="Referenced Libraries/ehcache-core-2.4.3.jar"/>
<classpathentry kind="lib" path="Referenced Libraries/httpasyncclient-4.0-alpha2.jar" sourcepath="doc/httpcomponents-asyncclient-4.0-alpha2-javadoc.zip">
<classpathentry kind="src" output="target/classes" path="src">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/ws4d-jcoap-applications/doc/httpcomponents-asyncclient-4.0-alpha2-javadoc.zip!/"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="Referenced Libraries/slf4j-api-1.6.1.jar"/>
<classpathentry kind="lib" path="Referenced Libraries/slf4j-jdk14-1.6.1.jar"/>
<classpathentry kind="lib" path="/ws4d-jcoap/lib/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="/ws4d-jcoap/lib/commons-cli-1.2.jar"/>
<classpathentry kind="lib" path="Referenced Libraries/httpclient-4.2.jar" sourcepath="doc/httpcomponents-client-4.2-javadoc.zip">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/ws4d-jcoap-applications/doc/httpcomponents-client-4.2-javadoc.zip!/"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="Referenced Libraries/httpcore-4.2.jar" sourcepath="doc/httpcomponents-core-4.2-javadoc.zip">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/ws4d-jcoap-applications/doc/httpcomponents-core-4.2-javadoc.zip!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="Referenced Libraries/httpcore-nio-4.2.jar" sourcepath="doc/httpcomponents-core-4.2-javadoc.zip">
<classpathentry combineaccessrules="false" kind="src" path="/ws4d-jcoap"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/ws4d-jcoap-applications/doc/httpcomponents-core-4.2-javadoc.zip!/"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
/.settings
/bin
\ No newline at end of file
/bin
/target/
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ws4d-jcoap-applications</name>
<name>ws4d-jcoap-proxy</name>
<comment></comment>
<projects>
</projects>
......@@ -10,8 +10,14 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.ws4d.coap</groupId>
<artifactId>proxy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jCoAP Proxy</name>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2.2.21</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"><!-- ALL | DEBUG | INFO | WARN | ERROR | FATAL | OFF: -->
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="INFO"><!-- ALL | DEBUG | INFO | WARN | ERROR | FATAL | OFF: -->
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
package org.ws4d.coap.cache;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.util.Constants;
import org.ws4d.coap.core.CoapClient;
import org.ws4d.coap.core.CoapConstants;
import org.ws4d.coap.core.connection.BasicCoapChannelManager;
import org.ws4d.coap.core.connection.api.CoapChannelManager;
import org.ws4d.coap.core.connection.api.CoapClientChannel;
import org.ws4d.coap.core.enumerations.CoapRequestCode;
import org.ws4d.coap.core.messages.api.CoapRequest;
import org.ws4d.coap.core.messages.api.CoapResponse;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
/**
* 5.6. Caching
*
* CoAP endpoints MAY cache responses in order to reduce the response time and
* network bandwidth consumption on future, equivalent requests.
*
* The goal of caching in CoAP is to reuse a prior response message to satisfy a
* current request. In some cases, a stored response can be reused without the
* need for a network request, reducing latency and network round-trips; a
* "freshness" mechanism is used for this purpose (see Section 5.6.1). Even when
* a new request is required, it is often possible to reuse the payload of a
* prior response to satisfy the request, thereby reducing network bandwidth
* usage; a "validation" mechanism is used for this purpose (see Section 5.6.2).
*
* @author Björn Butzin <bjoern.butzin@uni-rostock.de>
*
*/
public class CoapCache2 implements CoapClient {
private static Cache cache;
private static final Logger logger = LogManager.getLogger();
public CoapCache2() {
cache = new Cache("Coap Cache", 0, null, false, null, false, 0, 0, false, 0, null, null, 0, 0, false, false,
false);
CacheManager.create().addCache(cache);
}
public List<CoapResponse> request(CoapRequest request) {
List<TimedCacheEntry<CoapResponse>> cacheHits = getFromCache(request);
List<CoapResponse> result = new ArrayList<>();
if (cacheHits.size() > 0) {
for (TimedCacheEntry<CoapResponse> cacheHit : cacheHits) {
// fresh?
if (cacheHit.getExpires() < System.currentTimeMillis()) {
CoapResponse response = cacheHit.getValue();
response.setMaxAge((int) (cacheHit.getExpires() - System.currentTimeMillis()));
result.add(response);
}
// revalidate
}
// if(Multicast){
// send request to server
// add results to cache
// }
} else {
// cache miss
// send request to server
// add results to cache
}
return result;
}
/**
* 5.6.1. Freshness Model
*
* When a response is "fresh" in the cache, it can be used to satisfy
* subsequent requests without contacting the origin server, thereby
* improving efficiency.
*
* The mechanism for determining freshness is for an origin server to
* provide an explicit expiration time in the future, using the Max-Age
* Option (see Section 5.10.5). The Max-Age Option indicates that the
* response is to be considered not fresh after its age is greater than the
* specified number of seconds.
*
* The Max-Age Option defaults to a value of 60. Thus, if it is not present
* in a cacheable response, then the response is considered not fresh after
* its age is greater than 60 seconds. If an origin server wishes to prevent
* caching, it MUST explicitly include a Max-Age Option with a value of zero
* seconds.
*
* If a client has a fresh stored response and makes a new request matching
* the request for that stored response, the new response invalidates the
* old response.
*/
private boolean isFresh(CoapResponse response) {
return false;
}
/**
* Unlike HTTP, the cacheability of CoAP responses does not depend on the
* request method, but it depends on the Response Code. The cacheability of
* each Response Code is defined along the Response Code definitions in
* Section 5.9. Response Codes that indicate success and are unrecognized by
* an endpoint MUST NOT be cached.
*
* For a presented request, a CoAP endpoint MUST NOT use a stored response,
* unless:
*
* the presented request method and that used to obtain the stored response
* match,
*
* all options match between those in the presented request and those of the
* request used to obtain the stored response (which includes the request
* URI), except that there is no need for a match of any request options
* marked as NoCacheKey (Section 5.4) or recognized by the Cache and fully
* interpreted with respect to its specified cache behavior (such as the
* ETag request option described in Section 5.10.6; see also Section 5.4.2),
* and
*
* the stored response is either fresh or successfully revalidated
*/
private boolean isCacheable(CoapResponse response) {
return false;
}
private List<TimedCacheEntry<CoapResponse>> getFromCache(CoapRequest request) {
return null;
}
private boolean addToCache(CoapRequest request, CoapResponse response) {
if (!isCacheable(response)) {
return false;
}
long expires = System.currentTimeMillis();
expires += (-1 == response.getMaxAge()) ? CoapConstants.COAP_DEFAULT_MAX_AGE_MS : response.getMaxAge();
TimedCacheEntry<CoapResponse> e = new TimedCacheEntry<>(expires, response);
if (null == getFromCache(request)) {
// add to cache
} else {
// update response
}
return true;
}
/**
* 5.6.2. Validation Model
*
* When an endpoint has one or more stored responses for a GET request, but
* cannot use any of them (e.g., because they are not fresh), it can use the
* ETag Option (Section 5.10.6) in the GET request to give the origin server
* an opportunity both to select a stored response to be used, and to update
* its freshness. This process is known as "validating" or "revalidating"
* the stored response.
*
* When sending such a request, the endpoint SHOULD add an ETag Option
* specifying the entity-tag of each stored response that is applicable.
*
* A 2.03 (Valid) response indicates the stored response identified by the
* entity-tag given in the response's ETag Option can be reused after
* updating it as described in Section 5.9.1.3.
*
* Any other Response Code indicates that none of the stored responses
* nominated in the request is suitable. Instead, the response SHOULD be
* used to satisfy the request and MAY replace the stored response.
*/
private void revalidate(CoapResponse response) {
if (null != response.getETag()) {
// FIXME where to get them
String sAddress = null;
int sPort = CoapConstants.COAP_DEFAULT_PORT;
CoapClientChannel clientChannel;
try {
clientChannel = BasicCoapChannelManager.getInstance().connect(this, InetAddress.getByName(sAddress),
sPort);
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/statistic");
request.addETag(response.getETag());
clientChannel.sendMessage(request);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void onResponse(CoapClientChannel channel, CoapResponse response) {
// TODO match request and response
// add to cache
}
public void onMCResponse(CoapClientChannel channel, CoapResponse response, InetAddress srcAddress, int srcPort) {
// TODO match request and response
// add to cache
}
public void onConnectionFailed(CoapClientChannel channel, boolean notReachable, boolean resetByServer) {
if (notReachable) {
logger.warn("Target not reachable");
} else if (resetByServer) {
logger.warn("Connection reset by the server");
}
logger.warn("Connection failed for unknown reason");
}
private class TimedCacheEntry<A> {
private final Long expires;
private final A value;
TimedCacheEntry(Long expires, A value) {
this.expires = expires;
this.value = value;
}
public Long getExpires() {
return this.expires;
}
public A getValue() {
return this.value;
}
}
}
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LFU">
<persistence strategy="localTempSwap"/>
</defaultCache>
</ehcache>
\ No newline at end of file
package org.ws4d.coap.client;
import java.net.InetAddress;
import java.net.UnknownHostException;
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.CoapBlockOption.CoapBlockSize;
import org.ws4d.coap.messages.CoapRequestCode;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
*/
public class BasicCoapBlockClient implements CoapClient {
private static final String SERVER_ADDRESS = "129.132.15.80";
private static final int PORT = Constants.COAP_DEFAULT_PORT;
static int counter = 0;
CoapChannelManager channelManager = null;
CoapClientChannel clientChannel = null;
public static void main(String[] args) {
System.out.println("Start CoAP Client");
BasicCoapBlockClient client = new BasicCoapBlockClient();
client.channelManager = BasicCoapChannelManager.getInstance();
client.runTestClient();
}
public void runTestClient(){
try {
this.clientChannel = this.channelManager.connect(this, InetAddress.getByName(SERVER_ADDRESS), PORT);
CoapRequest coapRequest = this.clientChannel.createRequest(true, CoapRequestCode.GET);
coapRequest.setUriPath("/large");
this.clientChannel.setMaxReceiveBlocksize(CoapBlockSize.BLOCK_64);
this.clientChannel.sendMessage(coapRequest);
System.out.println("Sent Request");
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
@Override
public void onConnectionFailed(CoapClientChannel channel, boolean notReachable, boolean resetByServer) {
System.out.println("Connection Failed");
}
@Override
public void onResponse(CoapClientChannel channel, CoapResponse response) {
System.out.println("Received response");
System.out.println(response.toString());
System.out.println(new String(response.getPayload()));
}
@Override
public void onMCResponse(CoapClientChannel channel, CoapResponse response, InetAddress srcAddress, int srcPort) {
System.out.println("Received response");
}
}
package org.ws4d.coap.client;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Random;
import org.ws4d.coap.Constants;
import org.ws4d.coap.connection.BasicCoapChannelManager;
import org.ws4d.coap.connection.BasicCoapClientChannel;
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.CoapBlockOption;
import org.ws4d.coap.messages.CoapBlockOption.CoapBlockSize;
import org.ws4d.coap.messages.CoapRequestCode;
/**
* @author Christian Lerche <christian.lerche@uni-rostock.de>
* Bjoern Konieczek <bjoern.konieczek@uni-rostock.de>
*/
public class BasicCoapClient implements CoapClient {
private String SERVER_ADDRESS;
private int PORT;
static int counter = 0;
private CoapChannelManager channelManager = null;
private BasicCoapClientChannel clientChannel = null;
private Random tokenGen = null;
public BasicCoapClient(String server_addr, int port ){
super();
this.SERVER_ADDRESS = server_addr;
this.PORT = port;
this.channelManager = BasicCoapChannelManager.getInstance();
this.tokenGen = new Random();
}
public BasicCoapClient(){
super();
this.SERVER_ADDRESS = "localhost";
this.PORT = Constants.COAP_DEFAULT_PORT;
this.tokenGen = new Random();
}
public boolean connect(){
try {
this.clientChannel = (BasicCoapClientChannel) this.channelManager.connect(this, InetAddress.getByName(this.SERVER_ADDRESS), this.PORT);
} catch( UnknownHostException e ){
e.printStackTrace();
return false;
}
return true;
}
public boolean connect( String server_addr, int port ){
this.SERVER_ADDRESS = server_addr;
this.PORT = port;
return this.connect();
}
public CoapRequest createRequest( boolean reliable, CoapRequestCode reqCode ) {
return this.clientChannel.createRequest( reliable, reqCode );
}
public void sendRequest( CoapRequest request ){
if( request.getRequestCode() == CoapRequestCode.PUT || request.getRequestCode() == CoapRequestCode.POST ){
if( ( this.clientChannel.getMaxSendBlocksize() != null || request.getBlock1() != null ) ) {
request = this.clientChannel.addBlockContext( request);
}
} else if( request.getRequestCode() == CoapRequestCode.GET && ( request.getBlock2() == null && this.clientChannel.getMaxReceiveBlocksize() != null )) {
CoapBlockOption block2 = new CoapBlockOption( 0, false, this.clientChannel.getMaxReceiveBlocksize() );
request.setBlock2( block2 );
}
this.clientChannel.sendMessage(request);
}
public void setReceiveBlockSize( CoapBlockSize size ){
if( this.clientChannel != null )
this.clientChannel.setMaxReceiveBlocksize( size );
}
public void setSendBlockSize( CoapBlockSize size ){
if( this.clientChannel != null )
this.clientChannel.setMaxSendBlocksize(size);
}
public byte[] generateRequestToken(int tokenLength ){
byte[] token = new byte[tokenLength];
this.tokenGen.nextBytes(token);
return token;
}
@Override
public void onConnectionFailed(CoapClientChannel channel, boolean notReachable, boolean resetByServer) {
System.out.println("Connection Failed");
}
@Override
public void onResponse(CoapClientChannel channel, CoapResponse response) {
System.out.println("Received response");
}
@Override
public void onMCResponse(CoapClientChannel channel, CoapResponse response, InetAddress srcAddress, int srcPort) {
System.out.println("Received response");
}
}
......@@ -28,43 +28,39 @@ import org.apache.http.nio.util.HeapByteBufferAllocator;
import org.apache.http.nio.util.SimpleInputBuffer;
/**
* This class is used to consume an entity and get the entity-data as byte-array.
* The only other class which implements ContentListener is SkipContentListener.
* SkipContentListener is ignoring all content.
* Look at Apache HTTP Components Core NIO Framework -> Java-Documentation of SkipContentListener.
*/
/**