import org.iotivity.cloud.base.device.IRequestChannel;
import org.iotivity.cloud.base.exception.ServerException;
import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
-import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
import org.iotivity.cloud.base.protocols.MessageBuilder;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
CoapDevice coapDevice = (CoapDevice) ctx.channel()
.attr(keyDevice).get();
- if (coapDevice.getIssuedTime() != null
- && coapDevice.isExpiredTime()) {
+ if (coapDevice.isExpiredTime()) {
throw new UnAuthorizedException("token is expired");
}
ResponseStatus responseStatus = t instanceof ServerException
? ((ServerException) t).getErrorResponse()
: ResponseStatus.INTERNAL_SERVER_ERROR;
- ctx.channel().writeAndFlush(MessageBuilder
+ ctx.writeAndFlush(MessageBuilder
.createResponse((CoapRequest) msg, responseStatus));
- ctx.channel().close();
+ ctx.close();
}
}
}
}
+ CoapLifecycleHandler mLifeCycleHandler = new CoapLifecycleHandler();
+
@Sharable
class CoapAuthHandler extends ChannelDuplexHandler {
private Cbor<HashMap<String, Object>> mCbor = new Cbor<HashMap<String, Object>>();
ChannelPromise promise) {
try {
+
if (!(msg instanceof CoapResponse)) {
throw new BadRequestException(
"this msg type is not CoapResponse");
// Once the response is valid, add this to deviceList
CoapResponse response = (CoapResponse) msg;
- if (response.getUriPath()
- .equals("/" + OCFConstants.PREFIX_WELL_KNOWN + "/"
- + OCFConstants.PREFIX_OCF + "/"
- + OCFConstants.ACCOUNT_URI + "/"
- + OCFConstants.SESSION_URI)) {
+ switch (response.getUriPath()) {
- if (response.getStatus() != ResponseStatus.CHANGED) {
- throw new UnAuthorizedException();
- }
+ case OCFConstants.ACCOUNT_SESSION_FULL_URI:
- HashMap<String, Object> payloadData = mCbor
- .parsePayloadFromCbor(response.getPayload(),
- HashMap.class);
- int remainTime = (int) payloadData
- .get(Constants.EXPIRES_IN);
+ if (response.getStatus() != ResponseStatus.CHANGED) {
+ throw new UnAuthorizedException();
+ }
- Device device = ctx.channel().attr(keyDevice).get();
- ((CoapDevice) device).setExpiredPolicy(remainTime);
+ HashMap<String, Object> payloadData = mCbor
+ .parsePayloadFromCbor(response.getPayload(),
+ HashMap.class);
+ int remainTime = (int) payloadData
+ .get(Constants.EXPIRES_IN);
- // Remove current auth handler
- ctx.channel().pipeline().remove(this);
+ Device device = ctx.channel().attr(keyDevice).get();
+ ((CoapDevice) device).setExpiredPolicy(remainTime);
- // Raise event that we have Authenticated device
- ctx.fireChannelActive();
+ // Remove current auth handler and replace to
+ // LifeCycleHandler
+ ctx.channel().pipeline().replace(this,
+ "LifeCycleHandler", mLifeCycleHandler);
+
+ // Raise event that we have Authenticated device
+ ctx.fireChannelActive();
+
+ break;
}
ctx.writeAndFlush(msg);
// And check first response is VALID then add or cut
CoapRequest request = (CoapRequest) msg;
+ HashMap<String, Object> authPayload = null;
+ Device device = null;
+
switch (request.getUriPath()) {
- // Check whether first request is about account
- case "/" + OCFConstants.PREFIX_WELL_KNOWN + "/"
- + OCFConstants.PREFIX_OCF + "/"
- + OCFConstants.ACCOUNT_URI:
-
- case "/" + OCFConstants.PREFIX_WELL_KNOWN + "/"
- + OCFConstants.PREFIX_OCF + "/"
- + OCFConstants.ACCOUNT_URI + "/"
- + OCFConstants.SESSION_URI:
+ // Check whether request is about account
+ case OCFConstants.ACCOUNT_FULL_URI:
+ case OCFConstants.ACCOUNT_TOKENREFRESH_FULL_URI:
+
+ if (ctx.channel().attr(keyDevice).get() == null) {
+ // Create device first and pass to upperlayer
+ device = new CoapDevice(ctx);
+ ctx.channel().attr(keyDevice).set(device);
+ }
+
+ break;
+
+ case OCFConstants.ACCOUNT_SESSION_FULL_URI:
+
+ authPayload = mCbor.parsePayloadFromCbor(
+ request.getPayload(), HashMap.class);
+
+ device = ctx.channel().attr(keyDevice).get();
+
+ if (device == null) {
+ device = new CoapDevice(ctx);
+ ctx.channel().attr(keyDevice).set(device);
+ }
+
+ ((CoapDevice) device).updateDevice(
+ (String) authPayload.get(Constants.DEVICE_ID),
+ (String) authPayload.get(Constants.USER_ID),
+ (String) authPayload
+ .get(Constants.ACCESS_TOKEN));
+
break;
- case "/" + OCFConstants.PREFIX_OIC + "/"
- + OCFConstants.KEEP_ALIVE_URI:
+ case OCFConstants.KEEP_ALIVE_FULL_URI:
// TODO: Pass ping request to upper layer
- ctx.fireChannelRead(msg);
- return;
+ break;
default:
throw new UnAuthorizedException(
"authentication required first");
}
- HashMap<String, Object> authPayload = mCbor
- .parsePayloadFromCbor(request.getPayload(),
- HashMap.class);
-
- if (authPayload.containsKey("di") == false) {
- throw new PreconditionFailedException(
- "di property is not included");
- }
-
- CoapDevice device = new CoapDevice(ctx,
- (String) authPayload.get(Constants.DEVICE_ID),
- (String) authPayload.get(Constants.USER_ID),
- (String) authPayload.get(Constants.ACCESS_TOKEN));
-
- // Create device first and pass to upperlayer
- ctx.channel().attr(keyDevice).set(device);
-
ctx.fireChannelRead(msg);
} catch (Throwable t) {
ResponseStatus responseStatus = t instanceof ServerException
? ((ServerException) t).getErrorResponse()
: ResponseStatus.UNAUTHORIZED;
- ctx.channel().writeAndFlush(MessageBuilder
+ ctx.writeAndFlush(MessageBuilder
.createResponse((CoapRequest) msg, responseStatus));
Log.f(ctx.channel(), t);
}
public void addServer(Server server) {
if (server instanceof CoapServer) {
server.addHandler(new CoapAuthHandler());
- server.addHandler(new CoapLifecycleHandler());
}
if (server instanceof HttpServer) {
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
switch (request.getMethod()) {
case GET:
response = handleGetPingConfig(request);
- mConnectionPool.put(srcDevice, System.currentTimeMillis()
- + (mIntervals[0] * (long) 60000));
break;
case PUT:
HashMap<String, Integer> payloadData = mCbor
.parsePayloadFromCbor(request.getPayload(), HashMap.class);
- if (payloadData != null) {
- if (payloadData.containsKey("in")) {
- mConnectionPool.put(srcDevice, System.currentTimeMillis()
- + (payloadData.get("in") * (long) 60000));
- }
+
+ if (payloadData.containsKey("in")) {
+ mConnectionPool.put(srcDevice, System.currentTimeMillis()
+ + (payloadData.get("in") * (long) 60000));
}
+
return MessageBuilder.createResponse(request, ResponseStatus.VALID);
}
public void run() {
Map<Device, Long> map = Collections
.synchronizedMap(mConnectionPool);
- Set<Device> keySet = map.keySet();
- ArrayList<Device> deleteList = new ArrayList<>();
- Iterator<Device> iterator = null;
+
+ List<Device> deleteList = new ArrayList<>();
+
synchronized (map) {
- iterator = keySet.iterator();
Long currentTime = System.currentTimeMillis();
- // check interval
- while (iterator.hasNext()) {
- Device key = iterator.next();
- if (map.containsKey(key)) {
- if (map.get(key) != null) {
- Long lifeTime = (Long) map.get(key);
- if (lifeTime != null) {
- if (lifeTime < currentTime) {
- deleteList.add(key);
- }
- }
- }
+ for (Device device : map.keySet()) {
+ Long lifeTime = (Long) map.get(device);
+ if (lifeTime < currentTime) {
+ deleteList.add(device);
}
}
-
}
- iterator = deleteList.iterator();
- // remove session
- while (iterator.hasNext()) {
- Device key = iterator.next();
- mConnectionPool.remove(key);
- key.getCtx().fireChannelInactive();
- key.getCtx().close();
+
+ for (Device device : deleteList) {
+ mConnectionPool.remove(device);
+ device.getCtx().fireChannelInactive();
+ device.getCtx().close();
}
}
}
@Test
public void testAddDevice() throws Exception {
- CoapDevice coapDevice = new CoapDevice(null, di, userId, accessToken);
+ CoapDevice coapDevice = new CoapDevice(null);
+ coapDevice.updateDevice(di, userId, accessToken);
CoapDevicePool devicePool = deviceServerSystem.getDevicePool();
devicePool.addDevice(coapDevice);
}
@Test
public void testRemoveNotRegisteredDevice() throws Exception {
- CoapDevice coapDevice = new CoapDevice(null, di, userId, accessToken);
+ CoapDevice coapDevice = new CoapDevice(null);
+ coapDevice.updateDevice(di, userId, accessToken);
CoapDevicePool devicePool = deviceServerSystem.getDevicePool();
devicePool.removeDevice(coapDevice);
}
@Test
public void testRemoveDevice() throws Exception {
- CoapDevice coapDevice = new CoapDevice(null, di, userId, accessToken);
+ CoapDevice coapDevice = new CoapDevice(null);
+ coapDevice.updateDevice(di, userId, accessToken);
CoapDevicePool devicePool = deviceServerSystem.getDevicePool();
devicePool.addDevice(coapDevice);
devicePool.removeDevice(coapDevice);
@Test
public void testQueryDevice() throws Exception {
- CoapDevice coapDevice = new CoapDevice(null, di, userId, accessToken);
+ CoapDevice coapDevice = new CoapDevice(null);
+ coapDevice.updateDevice(di, userId, accessToken);
CoapDevicePool devicePool = deviceServerSystem.getDevicePool();
devicePool.addDevice(coapDevice);
devicePool.queryDevice(di);
deviceId.insert(13, '-');
deviceId.insert(18, '-');
deviceId.insert(23, '-');
- Device device = new CoapDevice(ctx, deviceId.toString(), null,
- null);
+ CoapDevice device = new CoapDevice(ctx);
+ device.updateDevice(deviceId.toString(), null, null);
ctx.channel().attr(keyDevice).set(device);
device.onConnected();
Device targetDevice = ctx.channel().attr(keyDevice).get();
if (targetDevice == null) {
- throw new InternalServerErrorException();
+ throw new InternalServerErrorException(
+ "Unable to find device");
}
if (msg instanceof CoapRequest) {
}
} catch (ServerException e) {
- ctx.channel().writeAndFlush(MessageBuilder.createResponse(msg,
+ ctx.writeAndFlush(MessageBuilder.createResponse(msg,
e.getErrorResponse()));
Log.f(ctx.channel(), e);
} catch (ClientException e) {
} catch (Throwable t) {
Log.f(ctx.channel(), t);
if (msg instanceof CoapRequest) {
- ctx.channel().writeAndFlush(MessageBuilder.createResponse(
- msg, ResponseStatus.INTERNAL_SERVER_ERROR));
+ ctx.writeAndFlush(MessageBuilder.createResponse(msg,
+ ResponseStatus.INTERNAL_SERVER_ERROR));
}
}
}