diff --git a/src/main/java/net/herit/iot/message/onem2m/OneM2mRequest.java b/src/main/java/net/herit/iot/message/onem2m/OneM2mRequest.java index 0d71f38..8a5697b 100644 --- a/src/main/java/net/herit/iot/message/onem2m/OneM2mRequest.java +++ b/src/main/java/net/herit/iot/message/onem2m/OneM2mRequest.java @@ -257,7 +257,8 @@ public enum RESOURCE_TYPE { MGMT_CMDH_LIMIT(1016, "eventLog"), MGMT_CMDH_NETWORK_ACCESS_RULES(1017, "eventLog"), MGMT_CMDH_NW_ACCESS_RULE(1018, "eventLog"), - MGMT_CMDH_BUFFER(1019, "eventLog"); // 90001 ~ : user defined + MGMT_CMDH_BUFFER(1019, "eventLog"), // 90001 ~ : user defined + AGGREGATED_RESPONSE(90010, "aggregatedResponse"); final int value; final String name; @@ -873,13 +874,6 @@ public void setRemoteHost(String host) { this.remoteHost = host; } -// public void setOriginator(String from, OneM2mContext context) { -// try { -// this.originator = new Originator(from, context); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } public void setOriginator(Originator value) { this.originator = value; @@ -931,11 +925,11 @@ public String toString() { // } // } catch (OneM2MException e) { // -// e.printStackTrace(); +// log.error("Exception", e); // // } catch (Exception e) { // -// e.printStackTrace(); +// log.error("Exception", e); // // } // diff --git a/src/main/java/net/herit/iot/message/onem2m/OneM2mResponse.java b/src/main/java/net/herit/iot/message/onem2m/OneM2mResponse.java index 81c8594..08065a2 100644 --- a/src/main/java/net/herit/iot/message/onem2m/OneM2mResponse.java +++ b/src/main/java/net/herit/iot/message/onem2m/OneM2mResponse.java @@ -371,7 +371,7 @@ public String toString() { try { bld.append(" Content: ").append(new String(content, "UTF-8")).append("\n"); } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + log.error("UnsupportedEncodingException", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulator.java b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulator.java new file mode 100644 index 0000000..c32398d --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulator.java @@ -0,0 +1,246 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.LGUAuthController; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData.Http; +import net.herit.iot.onem2m.core.convertor.ConvertorFactory; +import net.herit.iot.onem2m.core.convertor.XMLConvertor; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; + +public class AppEmulator { + + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(AppEmulator.class); + + // + // AE 정보 - 미리 가지고 있어야 함. + // + private String aeId = Constants.AS_ENTITY_ID; + private String aeName = Constants.AS_AE_NAME; + private String appId = Constants.AS_APP_ID; + private String appName = Constants.AS_APP_NAME; + + // + // AE가 접속할 CSE정보 - 미리 가지고 있어야 함. + // + private String cseAddr = Constants.CSE_ADDR; + private String csebase = Constants.CSE_ID +"/"+ Constants.CSE_BASENAME; + private String csebaseName = Constants.CSE_BASENAME; + private String cseId = Constants.CSE_ID; + + // AE IP 주소: Notification 수신에 사용됨 + private String ip; + // AE 포트 번호: Notification 수신에 사용됨 + private int port; + + // CSE가 AE에 Notification 요청을 전송할때 사용하는 네트워크 주소, 예:http://10.101.101.111:8080 + // - 서버에 등록되는 AE의 속성 정보임 + private String poa = "http://116.124.171.3:9902"; + + // AE가 구독요청(subscription)을 걸때 Notification 지정하는 Notification 수신 주소 + // - AE의 poa와는 별도로 구독별로 지정할 수 있음 + // # LGU+는 구독별 notificationUri설정을 허용하지 않으며, notificationUri대신에 AE-ID를 셋팅하여 POA로만 Notification을 수신하도록 함 + private String notificationUri = "http://10.101.101.180:9902"; + + + // AE로서 CSE를 연동하는 기능을 제공하는 오브젝트 + private AEController aeController; + + // LGU+ 인증정보 연동 기능을 제공하는 오브젝트 + private LGUAuthController authController; + + // Notification 메시지를 처리하는 핸들러 클래스 + private AppEmulatorNotiHandler notiHandler; + + // HTTP 서버 수신 메시지를 처리하는 핸들러 클래스 + private AppEmulatorHttpListener httpListener; + + // AE 정보 오브젝트 + private AE ae; + + // LGU+ 인증연동을 위한 파라미터 정보 - 미리 제공받아야 함 + private final String mefAddr = "http://106.103.234.198/mef"; + private final String deviceModel = "kidswatch1"; + private final String serviceCode = "0078"; + private final String m2mmType = "20"; + private final String deviceSn = "00000000000000000301"; + private final String mac = ""; + private final String ctn = "0109999999"; + private final String deviceType = "adn"; + private final String iccId = "A244A1"; + + + public AppEmulator(String ip, int port) { + try { + this.poa = "http://"+ip+":"+port; + this.notificationUri = "http://"+ip+":"+port+"/notify"; + + this.ip = ip; + this.port = port; + + logManager.initialize(LoggerFactory.getLogger("IITP-IOT-APP-AE"), null); + + + } catch (Exception e) { + + e.printStackTrace(); + } + + } + + private String getCiNotificationUri() { + + return notificationUri; + + } + + public void start() throws Exception { + + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + + + this.authController = new LGUAuthController(mefAddr, deviceModel, serviceCode, m2mmType, deviceSn, mac, ctn, deviceType, iccId); + + // 임시 테스트용 코드 + // - 인증결과 정보를 미리 입력하면 authController가 인증서버 연동을 수행하지 않고 제공받은 인증정보를 사용함. + // - 인증서버 연동기능이 테스트되지 않았으므로 임시로 제공받은 인증정보를 활용해서 서버 연동 시험 진행해야함 + LGUAuthData authData = new LGUAuthData(); + Http httpAuth = new Http(); + httpAuth.setEnrmtKey("test"); + httpAuth.setEntityId(Constants.AS_ENTITY_ID); + httpAuth.setToken(Constants.AS_AUTH_TOKEN); + authData.setHttp(httpAuth); + + authData.setKeId(Constants.AS_AUTH_KEID); + authData.setDeviceModel(Constants.AS_DEVICE_MODEL); + authData.setNetworkInfo(Constants.AS_NETWORK_INFO); + this.authController.setPreSharedAuthData(authData); + + // 컨트롤러 및 핸들러 객체 생성 + this.aeController = new AEController(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, authController); + notiHandler = new AppEmulatorNotiHandler(aeController); + httpListener = new AppEmulatorHttpListener(ip, port, aeController, notiHandler); + + // Notification 수신을 위한 HTTP 서버 시작 + // + // # 애뮬레이터에 사용된 서버는 애뮬레이터 테스트용으로 제작되었으며 상용서버에서는 별도의 WAS 또는 HTTP 어뎁터를 이용하여 HTTP 서버 기능을 구현해야 함!!!! + httpListener.start(); + + // AE 등록 수행 + // - 이미 등록된 경우는 등록된 정보를 조회함 + this.ae = aeController.doCreateAE(this.csebase, this.aeId, this.aeName, this.appId, this.appName, this.poa, true); + + // ACP 생성 + List oriIds = new ArrayList(); + oriIds.add(ae.getResourceID()); + AccessControlPolicy acp = aeController.doCreateACP(ae.getUri(), this.aeId, "acp-"+ae.getResourceID(), oriIds, 63, oriIds, 63, true); + + List acpIds = new ArrayList(); + acpIds.add(acp.getResourceID()); + + while (true) { + + System.out.println("Enter command!"); + System.out.println("'r:[deviceName]' - device registration"); + System.out.println("'s:[deviceName]' [switch status('ON'/'OFF')] - switch control"); + System.out.println("'u:[PointOfAccess]' - update PointOfAccess"); + System.out.println("'bye': Exit"); + + BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); + String s = bufferRead.readLine(); + + try{ + + if (s.equalsIgnoreCase("BYE")) { + break; + } + + + System.out.println(s); + + if (s.startsWith("r:")) { + // + // 디바이스에 대한 구독(Subscription) 신청 + // - 처음 디바이스가 등록되었을 때 해당 디바이스의 상태를 수신하기 위해서 1회 구독 신청하여야 함 + // - 일반적으로 사용자의 디바이스 등록 또는 프로비저닝 단계에서 실행됨 + // + String deviceName; + deviceName = s.substring(2); + + String aeUri = this.csebase+"/"+deviceName; + //AE ae = aeController.doRetrieveAE(aeUri); + +// aeController.doContainerSubscription(aeUri + "/"+Constants.CNT_SWITCH, this.aeId, this.aeId, NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); +// aeController.doContainerSubscription(aeUri + "/"+Constants.CNT_PHONEBOOK, this.aeId, this.aeId, NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value()); +// aeController.doContainerSubscription(aeUri + "/"+Constants.CNT_TEMPERATURE, this.aeId, this.aeId, NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); +// aeController.doContainerSubscription(aeUri + "/"+Constants.CNT_SWITCH_RES, this.aeId, this.aeId, NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); + + aeController.doCreateSubscription(aeUri + "/"+Constants.CNT_SWITCH, this.aeId, "/sub-"+this.ae.getResourceName().replace("-", "_"), this.getCiNotificationUri(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), acpIds, true); + aeController.doCreateSubscription(aeUri + "/"+Constants.CNT_PHONEBOOK, this.aeId, "/sub-"+this.ae.getResourceName().replace("-", "_"), this.getCiNotificationUri(), NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value(), acpIds, true); + aeController.doCreateSubscription(aeUri + "/"+Constants.CNT_TEMPERATURE, this.aeId, "/sub-"+this.ae.getResourceName().replace("-", "_"), this.getCiNotificationUri(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), acpIds, true); + aeController.doCreateSubscription(aeUri + "/"+Constants.CNT_SWITCH_RES, this.aeId, "/sub-"+this.ae.getResourceName().replace("-", "_"), this.getCiNotificationUri(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), acpIds, true); + + } else if (s.startsWith("s:")) { + // + // 스위치 제어 명령을 전송하는 예제 + // - 스위치 제어 명령 전송을 위해서 정의된 CNT_SWITCH_CMD 컨테이너에 contentInstance를 생성하여 제어명령을 전송함 + // - 디바이스는 제어명령 수신을 위해서 CNT_SWITCH_CMD 컨테이너에 대해서 구독하고 있어야 함 + // - 제어결과는 별도의 컨테이너(CNT_SWITCH_RES)를 통해서 수신하므로 AS는 제어명령을 보내기 전에 결과 수신 컨테이너를 구독하고 있어야 함 + // - 제어전송 및 결과 수신은 별도의 메시지 요청/전송을 통해서 일어나므로 해당 메시지에 대한 매핑은 AS에서 구현하여야 함 + // + String temp = s.substring(2); + String[] tokens = temp.split(" "); + if (tokens.length != 2) { + System.out.println("Invalid command: "+s); + continue; + } + + aeController.doCreateContentInstance(this.csebase+"/"+ tokens[0] +"/"+Constants.CNT_SWITCH_CMD, Constants.CNT_SWITCH_CMD, this.aeId, tokens[1]); + + } else if (s.startsWith("u:")) { + // + // AE poa 정보 업데이트 예 + // - 입력된 poa정보를 IN-CSE에 전송함 + // + String pb = s.substring(2); + aeController.doUpdateAEPoa(this.ae.getUri(), this.aeId, pb); + } else { + System.out.println("Unknown command: "+s); + continue; + } + } + catch(IOException e) + { + System.out.println("Invalid command: "+s); + e.printStackTrace(); + continue; + } + } + + httpListener.stop(); + } + private String getNotificationUri() { + return "http://"+Constants.AS_IP+":"+Constants.AS_PORT+"/notify"; + } + + // 에뮬레이트 실행 함수 + public static void main(String[] args) throws Exception { + new AppEmulator(Constants.AS_IP, Constants.AS_PORT).start(); + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorHttpListener.java b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorHttpListener.java new file mode 100644 index 0000000..ef09abb --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorHttpListener.java @@ -0,0 +1,264 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServer; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.HttpBasicRequest; +import net.herit.iot.onem2m.ae.lib.HttpBasicResponse; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.bind.http.codec.ResponseCodec; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; + +public class AppEmulatorHttpListener implements HttpServerListener { + + private final static HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private HttpServer httpServer; + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(AppEmulatorHttpListener.class); + + private AEController aeController; + private NotiHandlerInterface notiHandler; + + public AppEmulatorHttpListener(String ip, int port, AEController aeController, NotiHandlerInterface notiHandler) { + try { + + httpServer = new HttpServer(this, port); + logManager.initialize(LoggerFactory.getLogger("IITP-IOT-APP-AE"), null); + this.aeController = aeController; + this.notiHandler = notiHandler; + + } catch (Exception e) { + + e.printStackTrace(); + } + + } + + public void start() throws Exception { + + httpServer.runAsync(); + + } + + public void stop() { + + httpServer.stop(); + + } + + + @Override + public void channelDisconnected(ChannelHandlerContext ctx) { + log.debug("channelDisconnected"); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx) { + log.debug("channelConnected"); + + } + + @Override + public void channelRequested(ChannelHandlerContext ctx) { + log.debug("channelRequested"); + + } + + @Override +// public void handleHttpRequest(ChannelHandlerContext ctx,DefaultFullHttpRequest request) { + public void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { + log.debug("handleHttpRequest from " + ctx.channel().remoteAddress().toString()); + OneM2mRequest reqMessage = null; + try { + +// HashMap headerMap = new HashMap(); +// HttpHeaders headers = request.headers(); +// Iterator> it = headers.iterator(); +// while (it.hasNext()) { +// Entry header = it.next(); +// headerMap.put(header.getKey(), header.getValue()); +// } + + String host = ((InetSocketAddress)ctx.channel().remoteAddress()).getHostString(); + String method = request.getMethod().name(); + String uri = request.getUri(); + byte[] content = request.content().isReadable() ? request.content().copy().array() : null; + + HttpBasicRequest basicRequest = new HttpBasicRequest(method, uri, host, content); + + HttpHeaders headers = request.headers(); + Iterator> it = headers.iterator(); + while (it.hasNext()) { + Entry header = it.next(); + basicRequest.addHeader(header.getKey(), header.getValue()); + } + + //reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); + HttpBasicResponse response = this.aeController.doProcessRequest(basicRequest, this.notiHandler); + + DefaultFullHttpResponse dfResponse = null; + if (response.getContent() != null) { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK, + Unpooled.copiedBuffer(response.getContent()), false); + } else { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK); + } + + dfResponse.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + HttpServerHandler.sendHttpMessage(dfResponse, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + + } catch (OneM2MException ex) { + OneM2mResponse resMessage = new OneM2mResponse(ex.getResponseStatusCode(), reqMessage); + resMessage.setContent(new String(ex.getMessage()).getBytes()); + try { + + sendResponse(ctx, ResponseCodec.encode(resMessage, httpVersion)); + + } catch (Exception e) { + e.printStackTrace(); + } + + } catch (Throwable th) { + th.printStackTrace(); + log.error("RequestMessage decode failed.", th); + + sendError(ctx); + } + } + +// protected OneM2mResponse processRequest(OneM2mRequest request) throws UnsupportedEncodingException, Exception { +// +// // AE는 notification request만 처리함 +// +// String content = new String(request.getContent(), "UTF-8"); +// XMLConvertor ContInstXC = (XMLConvertor)ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); +// Notification res = ContInstXC.unmarshal(content); +// +// // process request +// // TBD +// OneM2mResponse response = new OneM2mResponse(RESPONSE_STATUS.NOT_IMPLEMENTED, request); +// +// return response; +// } + + private void sendError(ChannelHandlerContext ctx) { + DefaultFullHttpResponse response = + new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.INTERNAL_SERVER_ERROR); + HttpServerHandler.sendHttpMessage(response, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + } + + private class FilnalEventListener implements ChannelFutureListener { + + private ChannelHandlerContext channelContext = null; + private boolean isClose = false; + + public FilnalEventListener(ChannelHandlerContext channelContext, boolean isClose) { + this.channelContext = channelContext; + this.isClose = isClose; + } + + @Override + public void operationComplete(ChannelFuture arg0) throws Exception { + log.debug("FinalEventListener.operationComplete.."); + } + + } + + protected ChannelFuture sendResponse(ChannelHandlerContext ctx, final FullHttpResponse response) + { + + if (ctx.attr(ATTR_KEY_REQUEST).get() != null) + { + FullHttpRequest request = ctx.attr(ATTR_KEY_REQUEST).get(); + + if (HttpHeaders.isKeepAlive(request)) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + } + } + + if (response.headers().get(HttpHeaders.Names.CONNECTION) == null) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + } + + ChannelFuture future = ctx.writeAndFlush(response); + future.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception + { + if (channelFuture.isDone() && channelFuture.isSuccess()) + { + if (log.isDebugEnabled()) + { + log.debug(""); + log.debug("############################## Send Log ############################"); + log.debug("---------------------------------------------------------------------"); + log.debug("SEND HTTP Response: " + channelFuture.channel()); + for (Map.Entry entry : response.headers()) + { + log.debug("HEADER: " + entry.getKey() + " = " + entry.getValue()); + } + log.debug("VERSION: " + response.getProtocolVersion()); + log.debug("STATUS: " + response.getStatus()); + + log.debug("---------------------------------------------------------------------"); + log.debug(""); + } + } + else + { + if (log.isErrorEnabled()) + { + log.error( + "operationComplete_failure channel=" + channelFuture.channel() + ", isDone=" + channelFuture.isDone() + ", isSuccess=" + channelFuture.isSuccess() + + ", isCancelled=" + channelFuture.isCancelled() + ", isCancellable" + channelFuture.isCancellable() + "\n" + response, + channelFuture.cause()); + } + } + + } + }); + + log.debug("response.headers().get(CONNECTION)=" + response.headers().get(HttpHeaders.Names.CONNECTION)); + if (!response.headers().get(HttpHeaders.Names.CONNECTION).equals(HttpHeaders.Values.KEEP_ALIVE)) + { + log.debug("connection close"); + future.addListener(ChannelFutureListener.CLOSE); + } + + return future; + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorNotiHandler.java b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorNotiHandler.java new file mode 100644 index 0000000..150d6c0 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/AppEmulatorNotiHandler.java @@ -0,0 +1,129 @@ +package net.herit.iot.onem2m.ae.emul; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.handler.codec.http.HttpVersion; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class AppEmulatorNotiHandler implements NotiHandlerInterface { + + private final static HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + private Logger log = LoggerFactory.getLogger(AppEmulatorNotiHandler.class); + + //public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private AEController aeController; + private DeviceEmulator emulator; + + + public AppEmulatorNotiHandler(AEController aeController) { + + this.aeController = aeController; + + } + + + @Override + public RESPONSE_STATUS handleCreateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(String resId, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}, {}", notification.toString(), resId); + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + + + @Override + public RESPONSE_STATUS handleDeleteNoti(Resource resource, Notification notification) throws OneM2MException { + + + log.debug("handleDeleteNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + + } + + + @Override + public RESPONSE_STATUS handleCreateNoti(ContentInstance ci, + Notification notification) throws OneM2MException { + + log.debug("Switch status changed pi:{}, content:{}", ci.getParentID(), ci.getContent()); + return RESPONSE_STATUS.OK; + + } + + + @Override + public RESPONSE_STATUS handleCreateNoti(Container ci, Notification notification) + throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + + + @Override + public RESPONSE_STATUS handleUpdateNoti(AE ae, Notification notification) + throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + + + @Override + public RESPONSE_STATUS handleUpdateNoti(Container container, + Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + + + @Override + public RESPONSE_STATUS handleDeleteNoti(Container container, + Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + + + @Override + public RESPONSE_STATUS handleDeleteNoti(ContentInstance ci, + Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + return RESPONSE_STATUS.OK; + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/Constants.java b/src/main/java/net/herit/iot/onem2m/ae/emul/Constants.java new file mode 100644 index 0000000..16207bf --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/Constants.java @@ -0,0 +1,65 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlList; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import javax.xml.datatype.Duration; + + +public class Constants { + + //Common + public static final String CNT_TEMPERATURE = "cnt-temperature"; + public static final String CNT_PHONEBOOK = "cnt-phonebook"; + public static final String CNT_SWITCH = "cnt-switch"; + public static final String CNT_SWITCH_CMD = "cnt-cmd_switch"; + public static final String CNT_SWITCH_RES = "cnt-res_switch"; + + // cns 개발기 + public static final String CSE_ADDR = "http://106.103.234.117"; + //public static final String CSE_ADDR = "http://106.103.234.118"; + public static final String CSE_BASENAME = "cb-1"; + public static final String CSE_ID = "/IN_CSE-BASE-1"; + + // herit 개발기 +// public static final String CSE_ADDR = "http://10.101.101.195:8080"; +// public static final String CSE_BASENAME = "herit-cse"; +// public static final String CSE_ID = "/herit-in"; + + // 로컬 개발용 +// public static final String CSE_ADDR = "http://localhost:8080"; +// public static final String CSE_BASENAME = "herit-cse"; +// public static final String CSE_ID = "/herit-in"; + + public static final String DEVICE_AUTH_KEID = "B9-i1BBRWbnqZUJ0eAndzw"; + public static final String DEVICE_AUTH_TOKEN = "IFOulS6IeWUUY0L4rKc4iBh2nM2Re3uxrtrY0Z8hwWU"; + public static final String DEVICE_ENTITY_ID = "C_AE-D-49bed3a113-0078"; +// public static final String DEVICE_ENTITY_ID = "C_AE-D-GASLOCK1004"; + public static final String DEVICE_DEVICE_MODEL = "TEST_DEVICE_MODEL"; + public static final String DEVICE_NETWORK_INFO = "20"; + + public static final String DEVICE_AE_NAME = "ae-gaslock10003"; + public static final String DEVICE_APP_ID = "gaslock_emul"; + public static final String DEVICE_APP_NAME ="gaslock_emulator"; + + public static final String DEVICE_IP = "localhost"; + public static final int DEVICE_PORT = 9901; + + public static final String AS_AUTH_KEID = "B9-i1BBRWbnqZUJ0eAndzw"; + public static final String AS_AUTH_TOKEN = "IFOulS6IeWUUY0L4rKc4iBh2nM2Re3uxrtrY0Z8hwWU"; + public static final String AS_ENTITY_ID = "C_AE-D-49bed3a113-0078"; + public static final String AS_DEVICE_MODEL = "TEST_AS_MODEL"; + public static final String AS_NETWORK_INFO = "20"; + + public static final String AS_AE_NAME = "ae-as010"; + public static final String AS_APP_ID = "as_emul"; + public static final String AS_APP_NAME ="as_emulator"; + + public static final String AS_IP = "localhost"; + public static final int AS_PORT = 9902; + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulator.java b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulator.java new file mode 100644 index 0000000..6929e2c --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulator.java @@ -0,0 +1,372 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.HttpBasicRequest; +import net.herit.iot.onem2m.ae.lib.HttpBasicResponse; +import net.herit.iot.onem2m.ae.lib.LGUAuthController; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData.Http; +import net.herit.iot.onem2m.core.convertor.ConvertorFactory; +import net.herit.iot.onem2m.core.convertor.XMLConvertor; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Subscription; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class DeviceEmulator { + + private final static HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + private Logger log = LoggerFactory.getLogger(DeviceEmulator.class); + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + + //private String aeId = Constants.DEVICE_ENTITY_ID; + private String aeId; + private String aeName = Constants.DEVICE_AE_NAME; + private String appId = Constants.DEVICE_APP_ID; + private String appName = Constants.DEVICE_APP_NAME; + + //private String cseAddr = "http://localhost:8080"; + //private String csebase = "/csebase"; + private String cseAddr = Constants.CSE_ADDR; + private String csebase = Constants.CSE_ID +"/"+ Constants.CSE_BASENAME; + private String csebaseName = Constants.CSE_BASENAME; + private String cseId = Constants.CSE_ID; + private String commonAcpId = Constants.CSE_ID +"/"+ Constants.CSE_BASENAME +"/acp-"+Constants.AS_AE_NAME+"-common"; + + private String poa = "http://116.124.171.3:9901"; + + // AE가 구독요청(subscription)을 걸때 Notification 지정하는 Notification 수신 주소 + // - AE의 poa와는 별도로 구독별로 지정할 수 있음 + // # LGU+는 구독별 notificationUri설정을 허용하지 않으며, notificationUri대신에 AE-ID를 셋팅하여 POA로만 Notification을 수신하도록 함 + private String notificationUri = "http://10.101.101.180:9901"; + + private AEController aeController; + private LGUAuthController authController; + private DeviceEmulatorNotiHandler notiHandler; + private DeviceEmulatorHttpListener httpListener; + + private AccessControlPolicy acp; + private AE ae; + private Container switchCnt; + private Container switchCmdCnt; + private Container switchResCnt; + private Container temperatureCnt; + private Container phoneBookCnt; + private Subscription switchCmdCntSubs; + private Subscription phoneBookCntSubs; + + // LGU Auth input + private String mefAddr = "http://106.103.234.198/mef"; + private String deviceModel = "kidswatch1"; + private String serviceCode = "0079"; + private String m2mmType = "LTE-DEVICE"; + private String deviceSn = "00000000000000000302"; + private String mac = ""; + private String ctn = "01012345675"; + private String deviceType = "adn"; + private String iccId = "B244B1"; + + private String ip; + private int port; + + public DeviceEmulator(String ip, int port) { + try { + this.poa = "http://"+ip+":"+port; + + this.ip = ip; + this.port = port; + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private String getCiNotificationUri() { + + return notificationUri; + + } + + public void start2() throws Exception { + + try { + +// log.debug("# start init ContentInstance xml convertor"); +// XMLConvertor xmlCvt4 = ConvertorFactory.getXMLConvertor(ContentInstance.class, null); +// log.debug("# start init Container xml convertor"); +// XMLConvertor xmlCvt2 = ConvertorFactory.getXMLConvertor(Container.class, null); +// log.debug("# start init Notification xml convertor"); +// XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, null); +// log.debug("# start init AE xml convertor"); +// XMLConvertor xmlCvt3 = ConvertorFactory.getXMLConvertor(AE.class, null); +// log.debug("# end init xml convertor"); + + // AE 컨트롤러 생성 + this.aeController = new AEController(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, this.authController, 5); + // Notification Handler 생성 + this.notiHandler = new DeviceEmulatorNotiHandler(this.aeController); + + this.aeController.doInitializeConvertor(CONTENT_TYPE.XML, RESOURCE_TYPE.NOTIFICATION); + this.aeController.doInitializeConvertor(CONTENT_TYPE.XML, RESOURCE_TYPE.AE); + this.aeController.doInitializeConvertor(CONTENT_TYPE.XML, RESOURCE_TYPE.CONTAINER); + this.aeController.doInitializeConvertor(CONTENT_TYPE.XML, RESOURCE_TYPE.CONTENT_INST); + this.aeController.doInitializeConvertor(CONTENT_TYPE.XML, RESOURCE_TYPE.SUBSCRIPTION); + + // + try { + HttpBasicRequest br = new HttpBasicRequest("POST", "/", "/", "test".getBytes()); + br.addHeader("X-M2M-Origin", "local"); + HttpBasicResponse res = this.aeController.doProcessRequest(br, this.notiHandler); + + System.out.println("# Notification test - response:"+res.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + + + + // HTTP 서버 모듈 생성 - 예제에 사용된 HTTP 서버 기능은 예시이며 모듈별로 별도로 구현되거나 타 서버 모듈을 활용해야 함 + this.httpListener = new DeviceEmulatorHttpListener(ip, port, aeController, notiHandler); + httpListener.start(); + + + //====================================================================================== + boolean switchVal = true; + + while (true) { + System.out.println("Enter command!"); + System.out.println("'s': toggle switch"); + System.out.println("'t:[temperature]': change temperature"); + System.out.println("'p:[phonebookcontent]': change phonebook"); + System.out.println("'u:[PointOfAccess]': update PointOfAccess"); + + BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); + String s = bufferRead.readLine(); + + if (s.equalsIgnoreCase("BYE")) { + break; + } + System.out.println(s); + + String temp; + + + if (s.startsWith("bye")) + break; + + String cmd = s.substring(0,1); + switch (cmd) { + case "s": + Container cnt = new Container(); + cnt.setResourceName(""); + cnt.setUri(""); + aeController.doCreateContentInstance(this.switchCnt, this.aeId, switchVal ? "ON" : "OFF", null); + switchVal = !switchVal; + break; + case "t": + temp = s.substring(2); + int iTemp = Integer.parseInt(temp); + aeController.doCreateContentInstance(this.temperatureCnt, this.aeId, temp, null); + break; + case "p": + temp = s.substring(2); + aeController.doCreateContentInstance(this.phoneBookCnt, this.aeId, temp, null); + break; + case "u": + temp = s.substring(2); + aeController.doUpdateAEPoa(this.ae.getUri(), this.aeId, temp); + break; + default: + System.out.println("Unknown command: "+s); + } + continue; + } + + httpListener.stop(); + + } catch (OneM2MException e) { + log.error("OneM2MException occurred!!!"); + RESPONSE_STATUS status = e.getResponseStatusCode(); + log.error("Error code: " + status.Value()); + log.error("Error message: " + status.Name()); + } catch (Exception e) { + log.error("Exception occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + } + + + } + + public void start() throws Exception { + + + try { + + // AE 컨트롤러 생성 + this.aeController = new AEController(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, null); + HttpBasicRequest br = new HttpBasicRequest(aeId, aeId, aeId, null); + + this.aeController.doProcessRequest(br, null); + + // 인증 컨트롤러 생성 + this.authController = new LGUAuthController(mefAddr, deviceModel, serviceCode, m2mmType, deviceSn, mac, ctn, deviceType, iccId); + + + //인증 + //인증후 Http, Coap, Mqtt 의 token, key, entityId 값과 계산된 keId값은 authController의 authData에 저장된다. + //인증정보 가져오기 authController.getAuthData() + authController.doAuth(); + aeId = authController.getAuthData().getHttp().getEntityId(); + + // AE 컨트롤러 생성 + this.aeController = new AEController(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, this.authController); + + // Notification Handler 생성 + this.notiHandler = new DeviceEmulatorNotiHandler(this.aeController); + + // HTTP 서버 모듈 생성 - 예제에 사용된 HTTP 서버 기능은 예시이며 모듈별로 별도로 구현되거나 타 서버 모듈을 활용해야 함 + this.httpListener = new DeviceEmulatorHttpListener(ip, port, aeController, notiHandler); + httpListener.start(); + + // AE 생성 + this.ae = aeController.doCreateAE(this.csebase, this.aeId, this.aeName, this.appId, this.appName, this.poa, true); + + // AccessControlPolicy 생성 - AE가 AE하위에 생성한 리소스에 엑세스 할 수 있는 권한정책리소스를 생성한다. + List oriIds = new ArrayList(); + oriIds.add(ae.getResourceID()); + this.acp = aeController.doCreateACP(ae.getUri(), this.aeId, "acp-"+ae.getResourceID().replace("-", "_"), oriIds, 63, oriIds, 63, true); + + // AE 하위에 생성될 리소스에 설정될 권한정책리소스 ID목록을 생성한다. + // - ID목록에는 AE 자신이 하위 리소스에 CRUD 오퍼레이션을 수행할 수 있는 ACP id와 + // - 공통 엔티티(애플리케이션서버 AE)가 CRUD 오퍼레이션을 수행할 수 있는 ACP id (공통권한정책은 미리 생성되어 있고, 해당 ID가 AE에 셋팅되어 있다고 전제함) + List acpIds = new ArrayList(); + acpIds.add(acp.getResourceID()); + acpIds.add(this.commonAcpId); // 공통권한정책ID를 추가한다. + + // 컨테이너 생성 + Container cntrTemp = new Container(); + cntrTemp.setMaxNrOfInstances(1); + cntrTemp.addLabels("add_label_if_necessary"); + this.temperatureCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_TEMPERATURE, acpIds, cntrTemp, true); + this.phoneBookCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_PHONEBOOK, acpIds, true); + this.switchCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH, acpIds, true); + this.switchCmdCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH_CMD, acpIds, true); + this.switchResCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH_RES, acpIds, true); + + // 컨테이너에 대한 구독 요청 + //aeController.doContainerSubscription(switchCmdCnt.getUri(), this.aeId, getNotificationUri(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); + //aeController.doContainerSubscription(phoneBookCnt.getUri(), this.aeId, getNotificationUri(), NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value()); + this.switchCmdCntSubs = aeController.doCreateSubscription(switchCmdCnt.getUri(), this.aeId, "sub-"+this.ae.getResourceName().replace("-", "_"), this.ae.getResourceID(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), acpIds, true); + this.phoneBookCntSubs = aeController.doCreateSubscription(phoneBookCnt.getUri(), this.aeId, "sub-"+this.ae.getResourceName().replace("-", "_"), this.ae.getResourceID(), NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value(), acpIds, true); + + this.notiHandler.setResource(this.ae, this.switchCmdCnt, this.switchCnt); + + aeController.doCreateContentInstance(this.temperatureCnt, this.ae.getResourceID(), "13", null); + aeController.doCreateContentInstance(this.switchCnt, this.ae.getResourceID(), "Off", null); + + + //====================================================================================== + boolean switchVal = true; + + while (true) { + System.out.println("Enter command!"); + System.out.println("'s': toggle switch"); + System.out.println("'t:[temperature]': change temperature"); + System.out.println("'p:[phonebookcontent]': change phonebook"); + System.out.println("'u:[PointOfAccess]': update PointOfAccess"); + + BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); + String s = bufferRead.readLine(); + + if (s.equalsIgnoreCase("BYE")) { + break; + } + System.out.println(s); + + String temp; + + + if (s.startsWith("bye")) + break; + + String cmd = s.substring(0,1); + switch (cmd) { + case "s": + Container cnt = new Container(); + cnt.setResourceName(""); + cnt.setUri(""); + aeController.doCreateContentInstance(this.switchCnt, this.aeId, switchVal ? "ON" : "OFF", null); + switchVal = !switchVal; + break; + case "t": + temp = s.substring(2); + int iTemp = Integer.parseInt(temp); + aeController.doCreateContentInstance(this.temperatureCnt, this.aeId, temp, null); + break; + case "p": + temp = s.substring(2); + aeController.doCreateContentInstance(this.phoneBookCnt, this.aeId, temp, null); + break; + case "u": + temp = s.substring(2); + aeController.doUpdateAEPoa(this.ae.getUri(), this.aeId, temp); + break; + default: + System.out.println("Unknown command: "+s); + } + continue; + } + + httpListener.stop(); + + } catch (OneM2MException e) { + log.error("OneM2MException occurred!!!"); + RESPONSE_STATUS status = e.getResponseStatusCode(); + log.error("Error code: " + status.Value()); + log.error("Error message: " + status.Name()); + } catch (Exception e) { + log.error("Exception occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + } + + + } + + private String getNotificationUri() { + return "http://"+Constants.DEVICE_IP+":"+Constants.DEVICE_PORT+"/notify"; + } + + public static void main(String[] args) throws Exception { + new DeviceEmulator(Constants.DEVICE_IP, Constants.DEVICE_PORT).start2(); + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorHttpListener.java b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorHttpListener.java new file mode 100644 index 0000000..329251d --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorHttpListener.java @@ -0,0 +1,290 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServer; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.HttpBasicRequest; +import net.herit.iot.onem2m.ae.lib.HttpBasicResponse; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.bind.http.codec.ResponseCodec; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; + +public class DeviceEmulatorHttpListener implements HttpServerListener { + + private final HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private HttpServer httpServer; + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(DeviceEmulatorHttpListener.class); + + private AEController aeController; + private NotiHandlerInterface notiHandler; + + public DeviceEmulatorHttpListener(String ip, int port, AEController aeController, NotiHandlerInterface notiHandler) { + try { + httpServer = new HttpServer(this, port); + logManager.initialize(LoggerFactory.getLogger("IITP-IOT-APP-AE"), null); + this.aeController = aeController; + this.notiHandler = notiHandler; + + } catch (Exception e) { + + e.printStackTrace(); + } + + } + + public void start() throws Exception { + + httpServer.runAsync(); + + } + + public void stop() { + + httpServer.stop(); + + } + + + + @Override + public void channelDisconnected(ChannelHandlerContext ctx) { + log.debug("channelDisconnected"); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx) { + log.debug("channelConnected"); + + } + + @Override + public void channelRequested(ChannelHandlerContext ctx) { + log.debug("channelRequested"); + + } + + @Override + public void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { + log.debug("handleHttpRequest from " + ctx.channel().remoteAddress().toString()); + OneM2mRequest reqMessage = null; + try { + + String host = ((InetSocketAddress)ctx.channel().remoteAddress()).getHostString(); + String method = request.getMethod().name(); + String uri = request.getUri(); + byte[] content = request.content().isReadable() ? request.content().copy().array() : null; + + HttpBasicRequest basicRequest = new HttpBasicRequest(method, uri, host, content); + + HttpHeaders headers = request.headers(); + Iterator> it = headers.iterator(); + while (it.hasNext()) { + Entry header = it.next(); + basicRequest.addHeader(header.getKey(), header.getValue()); + } + + //reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); + HttpBasicResponse response = this.aeController.doProcessRequest(basicRequest, this.notiHandler); + + DefaultFullHttpResponse dfResponse = null; + if (response.getContent() != null) { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK, + Unpooled.copiedBuffer(response.getContent()), false); + } else { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK); + } + + dfResponse.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + dfResponse.headers().set("X-M2M-RSC", response.getHeaders().get("X-M2M-RSC")); + dfResponse.headers().set("X-M2M-RI", response.getHeaders().get("X-M2M-RI")); + HttpServerHandler.sendHttpMessage(dfResponse, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + + } catch (OneM2MException ex) { + OneM2mResponse resMessage = new OneM2mResponse(ex.getResponseStatusCode(), reqMessage); + resMessage.setContent(new String(ex.getMessage()).getBytes()); + try { + + sendResponse(ctx, ResponseCodec.encode(resMessage, httpVersion)); + + } catch (Exception e) { + e.printStackTrace(); + } + + } catch (Throwable th) { + th.printStackTrace(); + log.error("RequestMessage decode failed.", th); + + sendError(ctx); + } + } + /*public void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { + log.debug("handleHttpRequest from " + ctx.channel().remoteAddress().toString()); + OneM2mRequest reqMessage = null; + try { + + HashMap headerMap = new HashMap(); + HttpHeaders headers = request.headers(); + Iterator> it = headers.iterator(); + while (it.hasNext()) { + Entry header = it.next(); + headerMap.put(header.getKey(), header.getValue()); + } + + String host = ((InetSocketAddress)ctx.channel().remoteAddress()).getHostString(); + String method = request.getMethod().name(); + String uri = request.getUri(); + byte[] content = request.content().isReadable() ? request.content().copy().array() : null; + + //reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); + reqMessage = RequestCodec.decode(request, host); + OneM2mResponse resMessage = this.aeController.doProcessRequest(reqMessage, this.notiHandler); + + + DefaultFullHttpResponse response = ResponseCodec.encode(resMessage, httpVersion); + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + HttpServerHandler.sendHttpMessage(response, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + + } catch (OneM2MException ex) { + OneM2mResponse resMessage = new OneM2mResponse(ex.getResponseStatusCode(), reqMessage); + resMessage.setContent(new String(ex.getMessage()).getBytes()); + try { + + sendResponse(ctx, ResponseCodec.encode(resMessage, httpVersion)); + + } catch (Exception e) { + e.printStackTrace(); + } + + } catch (Throwable th) { + th.printStackTrace(); + log.error("RequestMessage decode failed.", th); + + sendError(ctx); + } + }*/ + + private void sendError(ChannelHandlerContext ctx) { + DefaultFullHttpResponse response = + new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.INTERNAL_SERVER_ERROR); + HttpServerHandler.sendHttpMessage(response, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + } + + private class FilnalEventListener implements ChannelFutureListener { + +// private ChannelHandlerContext channelContext = null; +// private boolean isClose = false; + + public FilnalEventListener(ChannelHandlerContext channelContext, boolean isClose) { +// this.channelContext = channelContext; +// this.isClose = isClose; + } + + @Override + public void operationComplete(ChannelFuture arg0) throws Exception { + log.debug("FinalEventListener.operationComplete.."); + } + + } + + protected ChannelFuture sendResponse(ChannelHandlerContext ctx, final FullHttpResponse response) + { + + if (ctx.attr(ATTR_KEY_REQUEST).get() != null) + { + FullHttpRequest request = ctx.attr(ATTR_KEY_REQUEST).get(); + + if (HttpHeaders.isKeepAlive(request)) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + } + } + + if (response.headers().get(HttpHeaders.Names.CONNECTION) == null) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + } + + ChannelFuture future = ctx.writeAndFlush(response); + future.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception + { + if (channelFuture.isDone() && channelFuture.isSuccess()) + { + if (log.isDebugEnabled()) + { + log.debug(""); + log.debug("############################## Send Log ############################"); + log.debug("---------------------------------------------------------------------"); + log.debug("SEND HTTP Response: " + channelFuture.channel()); + for (Map.Entry entry : response.headers()) + { + log.debug("HEADER: " + entry.getKey() + " = " + entry.getValue()); + } + log.debug("VERSION: " + response.getProtocolVersion()); + log.debug("STATUS: " + response.getStatus()); + + log.debug("---------------------------------------------------------------------"); + log.debug(""); + } + } + else + { + if (log.isErrorEnabled()) + { + log.error( + "operationComplete_failure channel=" + channelFuture.channel() + ", isDone=" + channelFuture.isDone() + ", isSuccess=" + channelFuture.isSuccess() + + ", isCancelled=" + channelFuture.isCancelled() + ", isCancellable" + channelFuture.isCancellable() + "\n" + response, + channelFuture.cause()); + } + } + + } + }); + + log.debug("response.headers().get(CONNECTION)=" + response.headers().get(HttpHeaders.Names.CONNECTION)); + if (!response.headers().get(HttpHeaders.Names.CONNECTION).equals(HttpHeaders.Values.KEEP_ALIVE)) + { + log.debug("connection close"); + future.addListener(ChannelFutureListener.CLOSE); + } + + return future; + } + + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorNotiHandler.java b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorNotiHandler.java new file mode 100644 index 0000000..c0506e2 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/DeviceEmulatorNotiHandler.java @@ -0,0 +1,148 @@ +package net.herit.iot.onem2m.ae.emul; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class DeviceEmulatorNotiHandler implements NotiHandlerInterface { + + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(DeviceEmulatorNotiHandler.class); + + //public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private AEController aeController = null; + + private Container switchCmdCntRes = null; + private Container switchCntRes = null; + private AE ae = null; + + public DeviceEmulatorNotiHandler(AEController aeController) { + + this.aeController = aeController; + + this.switchCmdCntRes = null; + this.switchCntRes = null; + this.ae = null; + + } + + public void setResource(AE ae, Container switchCmdCntRes, Container switchCntRes) { + this.switchCmdCntRes = switchCmdCntRes; + this.switchCntRes = switchCntRes; + this.ae = ae; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(ContentInstance ci, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + if (switchCmdCntRes == null || switchCntRes == null || ae == null) return RESPONSE_STATUS.INTERNAL_SERVER_ERROR; + + if (switchCmdCntRes.getResourceID().equals(ci.getParentID())) { + // switch control command + String value = ci.getContent(); + log.debug("Switch control command received!!!!!!"); + log.debug("pi:{}, content:{}", ci.getParentID(), value); + + aeController.doCreateContentInstance(this.switchCntRes, this.ae.getResourceID(), value, null); + } + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleCreateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(String resId, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}, {}", notification.toString(), resId); + + //ContentInstance ci = this.aeController.doRetrieveContentInstance(resId, this.ae.getResourceID()); + //log.debug("CI:"+ci.toString()); + + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(Container ci, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(AE ae, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(Container container, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(Container container, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(ContentInstance ci, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/MobileEmulator.java b/src/main/java/net/herit/iot/onem2m/ae/emul/MobileEmulator.java new file mode 100644 index 0000000..498163c --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/MobileEmulator.java @@ -0,0 +1,237 @@ +package net.herit.iot.onem2m.ae.emul; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.LGUAuthController; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.Subscription; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class MobileEmulator { + + private final static HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + private Logger log = LoggerFactory.getLogger(MobileEmulator.class); + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + + //private String aeId = Constants.DEVICE_ENTITY_ID; + private String aeId; + private String aeName = Constants.DEVICE_AE_NAME; + private String appId = Constants.DEVICE_APP_ID; + private String appName = Constants.DEVICE_APP_NAME; + + //private String cseAddr = "http://localhost:8080"; + //private String csebase = "/csebase"; + private String cseAddr = Constants.CSE_ADDR; + private String csebase = Constants.CSE_ID +"/"+ Constants.CSE_BASENAME; + private String csebaseName = Constants.CSE_BASENAME; + private String cseId = Constants.CSE_ID; + private String commonAcpId = Constants.CSE_ID +"/"+ Constants.CSE_BASENAME +"/acp-"+Constants.AS_AE_NAME+"-common"; + + private String poa = "http://116.124.171.3:9901"; + + // AE가 구독요청(subscription)을 걸때 Notification 지정하는 Notification 수신 주소 + // - AE의 poa와는 별도로 구독별로 지정할 수 있음 + // # LGU+는 구독별 notificationUri설정을 허용하지 않으며, notificationUri대신에 AE-ID를 셋팅하여 POA로만 Notification을 수신하도록 함 + private String notificationUri = "http://10.101.101.180:9901"; + + private AEController aeController; + private LGUAuthController authController; + private DeviceEmulatorNotiHandler notiHandler; + private DeviceEmulatorHttpListener httpListener; + + private AccessControlPolicy acp; + private AE ae; + private Container switchCnt; + private Container switchCmdCnt; + private Container switchResCnt; + private Container temperatureCnt; + private Container phoneBookCnt; + private Subscription switchCmdCntSubs; + private Subscription phoneBookCntSubs; + + // LGU Auth input + private String mefAddr = "http://106.103.234.198/mef"; + private String deviceModel = "kidswatch1"; + private String serviceCode = "0079"; + private String m2mmType = "LTE-DEVICE"; + private String deviceSn = "00000000000000000303"; + private String mac = ""; + private String ctn = "01012345676"; + private String deviceType = "adn"; + private String iccId = "C244C1"; + + private String ip; + private int port; + + public MobileEmulator(String ip, int port) { + try { + this.poa = "http://"+ip+":"+port; + + this.ip = ip; + this.port = port; + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private String getCiNotificationUri() { + + return notificationUri; + + } + + public void start() { + + try { + // 인증 컨트롤러 생성 + this.authController = new LGUAuthController(mefAddr, deviceModel, serviceCode, m2mmType, deviceSn, mac, ctn, deviceType, iccId); + + //인증 + //인증후 Http, Coap, Mqtt 의 token, key, entityId 값과 계산된 keId값은 authController의 authData에 저장된다. + //인증정보 가져오기 authController.getAuthData() + authController.doAuth(); + aeId = authController.getAuthData().getHttp().getEntityId(); + + // AE 컨트롤러 생성 + this.aeController = new AEController(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, this.authController); + + // Notification Handler 생성 + this.notiHandler = new DeviceEmulatorNotiHandler(this.aeController); + + // HTTP 서버 모듈 생성 - 예제에 사용된 HTTP 서버 기능은 예시이며 모듈별로 별도로 구현되거나 타 서버 모듈을 활용해야 함 + this.httpListener = new DeviceEmulatorHttpListener(ip, port, aeController, notiHandler); + httpListener.start(); + + // AE 생성 + this.ae = aeController.doCreateAE(this.csebase, this.aeId, this.aeName, this.appId, this.appName, this.poa, true); + + // AccessControlPolicy 생성 - AE가 AE하위에 생성한 리소스에 엑세스 할 수 있는 권한정책리소스를 생성한다. + List oriIds = new ArrayList(); + oriIds.add(ae.getResourceID()); + this.acp = aeController.doCreateACP(ae.getUri(), this.aeId, "acp-"+ae.getResourceID().replace("-", "_"), oriIds, 63, oriIds, 63, true); + + // AE 하위에 생성될 리소스에 설정될 권한정책리소스 ID목록을 생성한다. + // - ID목록에는 AE 자신이 하위 리소스에 CRUD 오퍼레이션을 수행할 수 있는 ACP id와 + // - 공통 엔티티(애플리케이션서버 AE)가 CRUD 오퍼레이션을 수행할 수 있는 ACP id (공통권한정책은 미리 생성되어 있고, 해당 ID가 AE에 셋팅되어 있다고 전제함) + List acpIds = new ArrayList(); + acpIds.add(acp.getResourceID()); + acpIds.add(this.commonAcpId); // 공통권한정책ID를 추가한다. + + // 컨테이너 생성 + this.temperatureCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_TEMPERATURE, acpIds, true); + this.phoneBookCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_PHONEBOOK, acpIds, true); + this.switchCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH, acpIds, true); + this.switchCmdCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH_CMD, acpIds, true); + this.switchResCnt = aeController.doCreateContainer(ae.getUri(), ae.getAEID(), Constants.CNT_SWITCH_RES, acpIds, true); + + // 컨테이너에 대한 구독 요청 + //aeController.doContainerSubscription(switchCmdCnt.getUri(), this.aeId, getNotificationUri(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); + //aeController.doContainerSubscription(phoneBookCnt.getUri(), this.aeId, getNotificationUri(), NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value()); + this.switchCmdCntSubs = aeController.doCreateSubscription(switchCmdCnt.getUri(), this.aeId, "sub-"+this.ae.getResourceName().replace("-", "_"), this.ae.getResourceID(), NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), acpIds, true); + this.phoneBookCntSubs = aeController.doCreateSubscription(phoneBookCnt.getUri(), this.aeId, "sub-"+this.ae.getResourceName().replace("-", "_"), this.ae.getResourceID(), NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value(), acpIds, true); + + this.notiHandler.setResource(this.ae, this.switchCmdCnt, this.switchCnt); + + aeController.doCreateContentInstance(this.temperatureCnt, this.ae.getResourceID(), "13", null); + aeController.doCreateContentInstance(this.switchCnt, this.ae.getResourceID(), "Off", null); + + + //====================================================================================== + boolean switchVal = true; + + while (true) { + System.out.println("Enter command!"); + System.out.println("'s': toggle switch"); + System.out.println("'t:[temperature]': change temperature"); + System.out.println("'p:[phonebookcontent]': change phonebook"); + System.out.println("'u:[PointOfAccess]': update PointOfAccess"); + + BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); + String s = bufferRead.readLine(); + + if (s.equalsIgnoreCase("BYE")) { + break; + } + System.out.println(s); + + String temp; + + + if (s.startsWith("bye")) + break; + + String cmd = s.substring(0,1); + switch (cmd) { + case "s": + aeController.doCreateContentInstance(this.switchCnt, this.aeId, switchVal ? "ON" : "OFF", null); + switchVal = !switchVal; + break; + case "t": + temp = s.substring(2); + int iTemp = Integer.parseInt(temp); + aeController.doCreateContentInstance(this.temperatureCnt, this.aeId, temp, null); + break; + case "p": + temp = s.substring(2); + aeController.doCreateContentInstance(this.phoneBookCnt, this.aeId, temp, null); + break; + case "u": + temp = s.substring(2); + aeController.doUpdateAEPoa(this.ae.getUri(), this.aeId, temp); + break; + default: + System.out.println("Unknown command: "+s); + } + continue; + } + + httpListener.stop(); + + } catch (OneM2MException e) { + log.error("OneM2MException occurred!!!"); + RESPONSE_STATUS status = e.getResponseStatusCode(); + log.error("Error code: " + status.Value()); + log.error("Error message: " + status.Name()); + } catch (Exception e) { + log.error("Exception occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + } + + + } + + private String getNotificationUri() { + return "http://"+Constants.DEVICE_IP+":"+Constants.DEVICE_PORT+"/notify"; + } + + public static void main(String[] args) throws Exception { + new MobileEmulator(Constants.DEVICE_IP, Constants.DEVICE_PORT).start(); + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/emul/MqttAeEmulator.java b/src/main/java/net/herit/iot/onem2m/ae/emul/MqttAeEmulator.java new file mode 100644 index 0000000..b27d51f --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/emul/MqttAeEmulator.java @@ -0,0 +1,102 @@ +package net.herit.iot.onem2m.ae.emul; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; +import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.bind.mqtt.api.MqttClientListener; +import net.herit.iot.onem2m.bind.mqtt.client.MqttClientHandler; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.PrimitiveContent; + +public class MqttAeEmulator implements MqttClientListener { + + MqttClientHandler mqttClient; + + String brokerURL = "tcp://iot.eclipse.org:1883"; + String AE_ID = "/herit-in/ae_0001"; + String CSE_ID = "/herit-in"; + + public static void main(String[] args) { + // TODO Auto-generated method stub + MqttAeEmulator s = new MqttAeEmulator(); + s.init(); + + try { + s.sendRequest(); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public void init() { + try { + mqttClient = MqttClientHandler.getInstance(AE_ID); + mqttClient.connect(brokerURL); + mqttClient.setListener(this); + } catch(Exception e) { + e.printStackTrace(System.out); + } + } + + public void sendRequest() throws Exception { + + OneM2mRequest req = new OneM2mRequest(); + req.setRequestIdentifier("req_222222"); + req.setFrom("ae_0001"); + req.setTo("/herit-cse"); + req.setContentType(CONTENT_TYPE.JSON); + req.setOperation(OPERATION.CREATE); + req.setResourceType(RESOURCE_TYPE.AE); + + AE ae = new AE(); + ae.addLabels("home"); + ae.setExpirationTime("20151231T235555"); + ae.setAppName("TEST"); + ae.setAppID("testApp"); + + PrimitiveContent pCont = new PrimitiveContent(); + pCont.addAny(ae); + + req.setPrimitiveContent(pCont); + + mqttClient.sendReqMessage(CSE_ID, req); + } + + + @Override + public void receiveMqttMessage(OneM2mRequest request) { + // TODO Auto-generated method stub + + System.out.println(request); + + } + + @Override + public void receiveMqttMessage(OneM2mResponse response) { + // TODO Auto-generated method stub + + System.out.println(response); + System.out.println(((AE)response.getPrimitiveContent().getAny().get(0)).toString()); + + } + + @Override + public void completedMqttDelivery(int messageID) { + // TODO Auto-generated method stub + System.out.println("deliveryComplete : " + messageID); + } + + @Override + public boolean sendMqttMessage(OneM2mRequest reqMessage) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean sendMqttMessage(OneM2mResponse resMessage) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpEventListener.java b/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpEventListener.java new file mode 100644 index 0000000..3004a5d --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpEventListener.java @@ -0,0 +1,29 @@ +package net.herit.iot.onem2m.ae.http.api; + +import io.netty.channel.ChannelHandlerContext; + +public interface HttpEventListener { + /** + * Channel 연결이 해제되면 Invoke된다. + * + * @param ctx + * the ChannelHandlerContext + * @param e + * the ChannelStateEvent + */ + public void channelDisconnected(ChannelHandlerContext ctx); + + /** + * Channel 연결이 완료되면 Invoke된다. + * + * @param ctx + */ + public void channelConnected(ChannelHandlerContext ctx); + + /** + * 요청메시지 전송이 완료되면 Invoke된다. + * + * @param ctx + */ + public void channelRequested(ChannelHandlerContext ctx); +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpServerListener.java b/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpServerListener.java new file mode 100644 index 0000000..c944d6a --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/http/api/HttpServerListener.java @@ -0,0 +1,17 @@ +package net.herit.iot.onem2m.ae.http.api; + +import net.herit.iot.onem2m.bind.http.api.HttpEventListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.FullHttpRequest; + +public interface HttpServerListener extends HttpEventListener { + /** + * HTTP Request가 들어오면 Invoke된다. + * + * @param ctx + * the ChannelHandlerContext + * @param request + * the HttpRequest + */ + public void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request); +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServer.java b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServer.java new file mode 100644 index 0000000..93d5efb --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServer.java @@ -0,0 +1,130 @@ +package net.herit.iot.onem2m.ae.http.server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServer; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import net.herit.iot.onem2m.ae.http.server.HttpServerInitializer; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; +//import io.netty.handler.ssl.SslContext; +//import io.netty.handler.ssl.SslContextBuilder; +//import io.netty.handler.ssl.util.SelfSignedCertificate; + +/** + * + */ +public final class HttpServer { + + static final boolean SSL = System.getProperty("ssl") != null; + //static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080")); + static int PORT = 8080; + + private Logger log = LoggerFactory.getLogger(HttpServer.class); + + private HttpServerListener listener = null; + + // member for runAsync + private Channel bindChannel = null; + EventLoopGroup bossGroup = null; + EventLoopGroup workerGroup = null; + + public HttpServer(HttpServerListener listener, int port) { + this.listener = listener; + this.PORT = port; + } + + + public void run() throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new HttpServerInitializer(this.listener)); + + b.option(ChannelOption.SO_REUSEADDR, true); + Channel ch = b.bind(PORT).sync().channel(); + + log.debug("Open your web browser and navigate to {}://127.0.0.1:{}/", (SSL? "https" : "http"), PORT); + + ch.closeFuture().sync(); + } finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + } + + public void runAsync() throws Exception { + bossGroup = new NioEventLoopGroup(1); + workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new HttpServerInitializer(this.listener)); + + b.option(ChannelOption.SO_REUSEADDR, true); + bindChannel = b.bind(PORT).sync().channel(); + + log.debug("Open your web browser and navigate to {}://127.0.0.1:{}/", (SSL? "https" : "http"), PORT); + + //ch.closeFuture().sync(); + } finally { + //bossGroup.shutdownGracefully(); + //workerGroup.shutdownGracefully(); + } + } + + public void stop() { + try { + bindChannel.close(); + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + bindChannel.closeFuture().sync(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + + } + } + + public ChannelFuture sendHttpResponse(ChannelHandlerContext ctx, DefaultFullHttpResponse response) { + + return HttpServerHandler.sendHttpMessage(response, ctx.channel()); + } + + public static void main(String[] args) throws Exception { + + HttpServer server = new HttpServer(null, 8080); + server.run(); + + // Configure SSL. +// final SslContext sslCtx; +// if (SSL) { +// SelfSignedCertificate ssc = new SelfSignedCertificate(); +// sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); +// } else { +// sslCtx = null; +// } + + // Configure the server. + + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerHandler.java b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerHandler.java new file mode 100644 index 0000000..6f75a2f --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerHandler.java @@ -0,0 +1,327 @@ +package net.herit.iot.onem2m.ae.http.server; + +import java.net.URI; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.TooLongFrameException; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.util.CharsetUtil; +import io.netty.util.ReferenceCountUtil; + +public class HttpServerHandler extends ChannelInboundHandlerAdapter { + + private HttpVersion httpVersion = HttpVersion.HTTP_1_1; + private boolean isReadBytes = false; + private HttpServerListener requestListener; + + private static Logger log = LoggerFactory.getLogger(HttpServerHandler.class); + + public HttpServerHandler(HttpServerListener listener) { + this.requestListener = listener; + } + + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + Channel channel = ctx.channel(); + log.debug("channelActive={}", channel); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + Channel channel = ctx.channel(); + log.debug("channelInactive={}", channel); + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + Channel channel = ctx.channel(); + log.debug("channelUnregistered={}", channel); + + /* + * else { InetSocketAddress address = (InetSocketAddress) channel.remoteAddress(); String addr = + * address.getHostName(); + * + * if (logger.isErrorEnabled()) { if (addr.equalsIgnoreCase("10.101.101.98") == false) + * logger.error("channelUnregistered=ctx.attr(LISTENER_ATTR_KEY) Not Found." ); } } + */ + + if (requestListener != null) { + requestListener.channelDisconnected(ctx); + } + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + FullHttpRequest httpRequest = null; + try + { + Channel channel = ctx.channel(); + log.debug("channelRead=", channel); + + /* timer 해제 */ + isReadBytes = true; + + /* HTTP 요청 메시지만 처리 */ + if (message instanceof FullHttpRequest) { + httpRequest = (FullHttpRequest) message; + + StringBuilder strBld = new StringBuilder(); + strBld.append("\n"); + strBld.append("######################## Server Log ################################\n"); + strBld.append("---------------------------------------------------------------------\n"); + strBld.append(">> RECV HTTP REQUEST: ").append(ctx.channel()).append("\n"); + strBld.append("VERSION: ").append(httpRequest.getProtocolVersion()).append("\n"); + strBld.append("METHOD: ").append(httpRequest.getMethod()).append("\n"); + strBld.append("URI: ").append(httpRequest.getUri()).append("\n"); + + for (Entry entry : httpRequest.headers()) { + strBld.append("HEADER: ").append(entry.getKey()).append(" = ").append(entry.getValue()).append("\n"); + } + + if (httpRequest.content().isReadable()) { + String contentType = httpRequest.headers().get(HttpHeaders.Names.CONTENT_TYPE); + + ByteBuf copyBuf = httpRequest.content().copy(); + String content = null; + content = "CONTENTS: \n" + new String(copyBuf.array(), CharsetUtil.UTF_8); + + strBld.append(content).append("\n"); + copyBuf.release(); + strBld.append("---------------------------------------------------------------------\n"); + } + log.debug(strBld.toString()); + + /* WARNNING - URL 기본규칙을 사용하지 않음 */ + /* + * URI uri = new URI(URLDecoder.decode(httpRequest.getUri(), ServerProperty.getInst().getEncodeChar())); + */ + URI uri = null; + try { + uri = new URI(httpRequest.getUri()); + } catch (Exception e) { + log.error("channelRead_error=", e); + + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.BAD_REQUEST), + ctx.channel()).addListener(ChannelFutureListener.CLOSE); + + return; + } + + /** + * Resource 위치가 명시되지 않으면 에러 응답. + */ + if (httpRequest.getUri() == null || uri.getPath() == null) { + log.error("channelRead_failure=Resource Not Found from URI(URI is Not Exist)"); + + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.NOT_FOUND), + ctx.channel()).addListener(ChannelFutureListener.CLOSE); + + return; + } + + if (httpRequest.getUri().equalsIgnoreCase("/bad-request")) { + log.error("channelRead_failure=Resource Not Found from URI(URI is Unavailable)"); + + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.BAD_REQUEST), + ctx.channel()).addListener(ChannelFutureListener.CLOSE); + + return; + } + + if (uri.getPath().equalsIgnoreCase("/monitor.do")) { + String hello = "Hello"; + ByteBuf buff = ctx.alloc().directBuffer().writeBytes(hello.getBytes(CharsetUtil.UTF_8)); + DefaultFullHttpResponse httpMessage = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK, buff); + httpMessage.headers().add(HttpHeaders.Names.CONTENT_LENGTH, buff.readableBytes()); + sendHttpMessage(httpMessage, ctx.channel()); + } else { + StringBuilder strBld2 = new StringBuilder(); + strBld2.append("\n"); + strBld2.append("######################## Trigger Log ###########################\n"); + strBld2.append("---------------------------------------------------------------------\n"); + strBld2.append("URL : ").append(uri.getPath()).append("\n"); + strBld2.append("TRIGGER TARGET: ").append(requestListener).append("\n"); + strBld2.append("---------------------------------------------------------------------\n"); + log.debug(strBld2.toString()); + + if (requestListener != null) { +// ctx.attr(HttpServerImpl.LISTENER_ATTR_KEY).set(triggerResource); + requestListener.handleHttpRequest(ctx, (FullHttpRequest) message); + } else { + log.error("channelRead_failure=Not Found Listener"); + + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.NOT_FOUND), + ctx.channel()).addListener(ChannelFutureListener.CLOSE); + } + + } + + } else { + log.error("channelRead_failure=It's Not Supported Message Type. : " + message); + + ctx.close(); + } + } catch (Exception exception) { + log.error("channelRead_error=" + exception.toString()); + + if (httpRequest != null) { + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.INTERNAL_SERVER_ERROR), + ctx.channel()).addListener( ChannelFutureListener.CLOSE); + } else { + ctx.close(); + } + } finally { + /* ByteBuf 해제 */ + ReferenceCountUtil.release(message); + } + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + + Channel channel = ctx.channel(); + log.error("userEventTriggered={}, object={}", channel, evt); + + if (!(evt instanceof IdleStateEvent)) { return; } + + if (evt instanceof IdleStateEvent) { + IdleStateEvent e = (IdleStateEvent) evt; + + if (e.state() == IdleState.READER_IDLE) { + log.debug("userEventTriggered(readIdle)={}", ctx.channel()); + + if (isReadBytes == false) ctx.close(); + } else if (e.state() == IdleState.WRITER_IDLE) { + log.debug("userEventTriggered(writeIdle)={}", ctx.channel()); + + if (isReadBytes == false) ctx.close(); + } else { + log.debug("userEventTriggered(allIdle)={}", ctx.channel()); + + if (isReadBytes == false) ctx.close(); + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + Channel channel = ctx.channel(); + log.error("exceptionCaught={}, cause={}", channel, cause); + + /* Content Length의 크기가 너무 큰 경우 */ + if (cause instanceof TooLongFrameException) { + sendHttpMessage(new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE), ctx.channel()) + .addListener(ChannelFutureListener.CLOSE); + } else { + ctx.close(); + } + + } + + /** + * Http message를 전송한다. + * + * @param response + * the http message + * @param channel + * the channel + * @return the channel future + */ + public static ChannelFuture sendHttpMessage(final DefaultFullHttpResponse response, Channel channel) { + + try { + if (channel != null && channel.isActive() && channel.isWritable()) { + String contentString = null; + + if (response.content() != null) { + if (response.content().isReadable()) { + String contentType = response.headers().get(HttpHeaders.Names.CONTENT_TYPE); + + contentString = "CONTENTS: \n" + response.content().toString(CharsetUtil.UTF_8); + + } + } + + /* SENDING */ + ChannelFuture future = channel.writeAndFlush(response); + + final String contents = contentString; + future.addListener(new ChannelFutureListener() { + + /** + * SENT + */ + @Override + public void operationComplete(ChannelFuture future) throws Exception { + try { + if (future.isDone() && future.isSuccess()) { + + StringBuilder strBld = new StringBuilder(); + strBld.append("\n"); + strBld.append("######################## Server Log ################################\n"); + strBld.append("---------------------------------------------------------------------\n"); + strBld.append("<< SEND HTTP Response: ").append(future.channel()).append("\n"); + for (Entry entry : response.headers()) { + strBld.append("HEADER: ").append(entry.getKey()).append(" = ").append(entry.getValue()).append("\n"); + } + strBld.append("VERSION: ").append(response.getProtocolVersion()).append("\n"); + strBld.append("STATUS: ").append(response.getStatus()).append("\n"); + + + if (contents != null) strBld.append(contents).append("\n"); + strBld.append("---------------------------------------------------------------------\n"); + strBld.append("\n"); + log.debug(strBld.toString()); + } else { + log.error("operationComplete_failure channel=" + future.channel() + "\n" + response + ", " + future.cause()); + } + } catch (Exception e) { + log.error("operationComplete_error=", e); + + throw e; + } finally { + + /* ByteBuf 해제 */ + try { + ReferenceCountUtil.release(response); + } + catch (Exception e) {} + } + } + }); + + return future; + } else { + log.error("sendHttpMessage_failure=Channel not connected, channel={}", channel); + } + } catch (Exception exception) { + log.error("sendHTTPMessage_error=", exception); + exception.printStackTrace(); + + response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR); + channel.writeAndFlush(response); + channel.close(); + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerInitializer.java b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerInitializer.java new file mode 100644 index 0000000..8ef357e --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/http/server/HttpServerInitializer.java @@ -0,0 +1,45 @@ +package net.herit.iot.onem2m.ae.http.server; + +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.http.HttpContentCompressor; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpServerCodec; +//import io.netty.handler.ssl.SslContext; +import io.netty.handler.stream.ChunkedWriteHandler; + +public class HttpServerInitializer extends ChannelInitializer { + + HttpServerListener listener = null; +// private final SslContext sslCtx; + + public HttpServerInitializer(HttpServerListener listener) { +// this.sslCtx = sslCtx; + this.listener = listener; + } + + @Override + public void initChannel(SocketChannel ch) { + ChannelPipeline pipeline = ch.pipeline(); +// if (sslCtx != null) { +// p.addLast(sslCtx.newHandler(ch.alloc())); +// } + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + // Uncomment the following line if you don't want to handle HttpChunks. + //pipeline.addLast("chunkedWriter", new ChunkedWriteHandler()); + //p.addLast(new HttpObjectAggregator(1048576)); + // Remove the following line if you don't want automatic content compression. + //pipeline.addLast(new HttpContentCompressor()); + + // Uncomment the following line if you don't want to handle HttpContents. + pipeline.addLast(new HttpObjectAggregator(65536)); + + pipeline.addLast("handler", new HttpServerHandler(listener)); + } +} \ No newline at end of file diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEController.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEController.java new file mode 100644 index 0000000..e42d7ea --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEController.java @@ -0,0 +1,1349 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import io.netty.handler.codec.http.HttpVersion; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.persistence.oxm.XMLRoot; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; +import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; +import net.herit.iot.message.onem2m.OneM2mRequest.RESULT_CONT; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.ae.lib.AuthControllerInterface; +import net.herit.iot.onem2m.ae.lib.HttpBasicRequest; +import net.herit.iot.onem2m.ae.lib.HttpBasicResponse; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.bind.http.client.HttpClient; +import net.herit.iot.onem2m.bind.http.codec.RequestCodec; +import net.herit.iot.onem2m.bind.http.codec.ResponseCodec; +import net.herit.iot.onem2m.core.convertor.ConvertorFactory; +import net.herit.iot.onem2m.core.convertor.JSONConvertor; +import net.herit.iot.onem2m.core.convertor.XMLConvertor; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.core.util.Utils; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.AccessControlRule; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.EventNotificationCriteria; +import net.herit.iot.onem2m.resource.Naming; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; +import net.herit.iot.onem2m.resource.SetOfAcrs; +import net.herit.iot.onem2m.resource.Subscription; +import net.herit.iot.onem2m.resource.UriContent; +import net.herit.iot.onem2m.resource.UriListContent; +import net.herit.iot.onem2m.resource.Notification.NotificationEvent; +import net.herit.iot.onem2m.resource.Notification.NotificationEvent.OperationMonitor; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONEVENT_TYPE; + +/** + * AE가 IN-CSE와 연동하기 위한 함수를 제공하는 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class AEController { + + /** + * AE 컨트롤러 생성자 + * + * @param cseAddr - INCSE 주소 (INCSE 고정값) + * @param cseId - INCSE의 cse id (INCSE 고정값) + * @param csebaseName - INCSE의 csebase 리소스의 이름 (INCSE 고정값) + * @param contentType - 서버 연동에 사용할 Content-Type (XML:CONTENT_TYPE.XML, JSON:CONTENT_TYPE.JSON) + * @param authController - 인증 수행 클래스, 입력된 클래스는 AE 등록시 인증을 수행하고, 인증정보를 REQUEST메시지에 주입한다. + * + */ + public AEController(String cseAddr, String cseId, String csebaseName, + CONTENT_TYPE contentType, AuthControllerInterface authController) { + + this.cseAddr = cseAddr; + this.contentType = contentType; + this.csebaseUri = cseId +"/"+ csebaseName; + this.cseId = cseId; + this.authController = authController; + + } + + /** + * AccessControlPolicy를 등록한다. + * * + * @param parentUri - AccessControlPolicy 리소스를 생성할 부모 리소스 URI(structured id). + * @param from - AE의 ID. + * @param originIds - 권한을 허용할 AE 또는 CSE의 ID 목록. + * @param operation - 허용할 오퍼레이션, CREATE:1, RETRIEVE:2, UPDATE:4, DELETE:8, DISCOVERY:16, NOTIFY:32 (허용할 오퍼레이션의 합) + * @param retrieveBeforeCreate - create하기전에 retrieve하여 성공할 경우 retrieve된 값 반환 + * @return 서버에 생성된 AccessControlPolicy 정보, 이미 생성되어 추가 생성되지 못한 경우에는 null 반환 + * @throws OneM2MException + */ + public AccessControlPolicy doCreateACP(String parentUri, String from, String acpName, + List originIds, int operation, + List spOriginIds, int spOperation, + boolean retrieveBeforeCreate) throws OneM2MException { + + // 이미 등록된 경우 AE정보 retrieve + if (retrieveBeforeCreate) { + try { + AccessControlPolicy acp = (AccessControlPolicy)this.retrieveACP(parentUri +"/"+acpName, from); + return acp; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + SetOfAcrs soa = new SetOfAcrs(); + AccessControlRule acr = new AccessControlRule(originIds, operation); + soa.addAccessControlRule(acr); + + SetOfAcrs spSoa = new SetOfAcrs(); + AccessControlRule spAcr = new AccessControlRule(spOriginIds, spOperation); + spSoa.addAccessControlRule(spAcr); + + AccessControlPolicy acp = new AccessControlPolicy(); + acp.setPrivileges(soa); + acp.setSelfPrivileges(spSoa); + + AccessControlPolicy rAcp = createACP(parentUri, from, acp, acpName); + + return rAcp; + + } + + + /** + * AccessControlPolicy를 조회한다. + * * + * @param acpUri - 조회할 AccessControlPolicy 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 AccessControlPolicy 정보 + * @throws OneM2MException + */ + public AccessControlPolicy doRetrieveACP(String acpUri, String from) throws OneM2MException { + + return retrieveACP(acpUri, from); + + } + + /** + * AE를 IN-CSE에 등록한다. + * 모든 AE는 최소 1회이상 실행해야 하며, + * 이미 실행해서 INCSE에 등록되어 있을 경우 등록된 정보를 조회하여 반환한다. + * + * @param csebaseUri - IN-CSE의 csebase(root) 리소스 uri. + * @param aeId - AE의 ID. + * @param aeName - AE 이름 (예: ae-gaslock-001, LGU+ INCSE연동시 "ae-"로 시작하여야함) + * @param appId - AE의 애플리케이션 ID (AE는 애플리케이션의 하나의 instance) + * @param appName - AE의 애플리케이션 Name (AE는 애플리케이션의 하나의 instance) + * @param poa - IN-CSE에 AE로 REQUEST보낼 접속 주소, 예: http://onem2m.herit.net:8080 + * @return 서버에 저장된 AE 정보 + */ + public AE doCreateAE(String csebaseUri, String aeId, String aeName, String appId, String appName, + String poa, boolean retrieveBeforeCreate) throws OneM2MException { + + if (authController != null && authController.isAuthorized() == false) { + authController.doAuth(); + if (authController.getEntityId() != null) { + aeId = authController.getEntityId(); + } + } + + // 이미 등록된 경우 AE정보 retrieve + if (retrieveBeforeCreate) { + try { + this.ae = (AE)this.retrieveAE(csebaseUri +"/"+aeName, aeId); + return this.ae; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + + AE ae1 = new AE(); + //ae1.setAEID(aeId); + ae1.setAppID(appId); + ae1.setAppName(appName); + ae1.addPointOfAccess(poa); + ae1.setRequestReachability(true); + + this.ae = createAE(csebaseUri, aeId, ae1, aeName); + + return this.ae; + + } + + /** + * AE를 IN-CSE에 등록한다. + * 모든 AE는 최소 1회이상 실행해야 하며, + * 이미 실행해서 INCSE에 등록되어 있을 경우 등록된 정보를 조회하여 반환한다. + * + * @param csebaseUri - IN-CSE의 csebase(root) 리소스 uri. + * @param aeId - AE의 ID. + * @param aeName - AE 이름 (예: ae-gaslock-001, LGU+ INCSE연동시 "ae-"로 시작하여야함) + * @param ae - 등록될 AE정보를 포함한 AE오브젝트 (appId, appName, poa, reachability 필수) + * @return 서버에 저장된 AE 정보 + */ + public AE doCreateAE(String csebaseUri, String aeId, String aeName, AE ae, boolean retrieveBeforeCreate) throws OneM2MException { + + if (authController != null && authController.isAuthorized() == false) { + authController.doAuth(); + if (authController.getEntityId() != null) { + aeId = authController.getEntityId(); + } + } + + // 이미 등록된 경우 AE정보 retrieve + if (retrieveBeforeCreate) { + try { + this.ae = (AE)this.retrieveAE(csebaseUri +"/"+aeName, aeId); + return this.ae; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + +// AE ae1 = new AE(); +// ae1.setAppID(appId); +// ae1.setAppName(appName); +// ae1.addPointOfAccess(poa); +// ae1.setRequestReachability(true); + + this.ae = createAE(csebaseUri, aeId, ae, aeName); + + return this.ae; + + } + + /** + * AE정보를 조회한다. + * + * @param csebaseUri - IN-CSE의 csebase(root) 리소스 uri. + * @param aeName - AE 이름 (예: ae-gaslock-001, LGU+ INCSE연동시 "ae-"로 시작하여야함) + * @param from - AE의 ID. + * @return 서버에 저장된 AE 정보 + * @throws OneM2MException + */ + public AE doRetrieveAE(String csebaseUri, String aeName, String from) throws OneM2MException { + + return retrieveAE(csebaseUri +"/"+ aeName, from); + + } + + /** + * AE정보를 조회한다. + * + * @param aeUri - 조회할 AE 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 AE 정보 + * @throws OneM2MException + */ + public AE doRetrieveAE(String aeUri, String from) throws OneM2MException { + + return retrieveAE(aeUri, from); + + } + + + /** + * AE의 POA를 수정한다. + * AE의 POA가 변경되었을 경우 호출해야 한다. + * + * @param aeUri - AE의 Uri. + * @param from - AE의 ID. + * @param poa - 수정될 POA + * @return 수정된 AE 정보 오브젝트 + */ + public AE doUpdateAEPoa(String aeUri, String from, String poa) throws OneM2MException { + + AE ae1 = new AE(); + ae1.addPointOfAccess(poa); + + this.update(aeUri, from, ae1); + + if (this.ae == null) { + return ae1; + } else { + if (this.ae.getPointOfAccess() != null) { + this.ae.getPointOfAccess().clear(); + } + this.ae.addPointOfAccess(poa); + + return this.ae; + } + + } + + /** + * Container를 생성한다. + * + * @param aeUri - AE의 Uri. + * @param from - AE의 ID. + * @param containerName - 생성될 container이름 + * @param acpIds - 접근권한을 지정한 AccessControlPolicy ID 리스트 + * @param acpIds + * @return 생성된 container정보 오브젝트 + */ + public Container doCreateContainer(String aeUri, String from, String containerName, List acpIds, + boolean retrieveBeforeCreate) throws Exception { + + // 이미 등록된 경우 Container정보 retrieve + if (retrieveBeforeCreate) { + try { + Container cntr = (Container)this.retrieveContainer(aeUri +"/"+containerName, from); + return cntr; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + Container cnt1 = new Container(); + cnt1.addLabels(containerName); + + if (acpIds != null) { + Iterator it = acpIds.iterator(); + while (it.hasNext()) { + cnt1.addAccessControlPolicyIDs(it.next()); + } + } + + return createContainer(aeUri, from, cnt1, containerName); + + } + + /** + * Container정보를 조회한다. + * + * @param containerUri - 조회할 Container 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 Container 정보 + * @throws OneM2MException + */ + public Container doRetrieveContainer(String containerUri, String from) throws OneM2MException { + + return retrieveContainer(containerUri, from); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param cntUri - Container의 Uri. + * @param containerName - container이름 + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param name - 생성될 contentInstance의 이름 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(String cntUri, String containerName, String from, String value, String ciName) throws Exception { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + ci.addLabels(containerName); + + return createContentInstance(cntUri, from, ci, ciName); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param container - 업데이트될 container정보, uri와 resourceName이 반드시 셋팅되어 있어야 함. + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param ciName - 생성될 contentInstance 이름. null로 설정할 경우 서버에서 자동 생성 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(Container container, String from, String value, String ciName) throws OneM2MException { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + ci.addLabels(container.getResourceName()); + + return createContentInstance(container.getUri(), from, ci, ciName); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param containerUri - 업데이트될 container의 uri + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param ciName - 생성될 contentInstance 이름. null로 설정할 경우 서버에서 자동 생성 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(String containerUri, String from, String value, String ciName) throws OneM2MException { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + + return createContentInstance(containerUri, from, ci, ciName); + + } + + + /** + * ContentInstance 정보를 조회한다. + * + * @param ciUri - 조회할 contentInstance 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 ContentInstance 정보 + * @throws OneM2MException + */ + public ContentInstance doRetrieveContentInstance(String ciUri, String from) throws OneM2MException { + + return retrieveContentInstance(ciUri, from); + + } + + /** + * Container의 최종 정보(contentInstnace)를 조회한다. + * + * @param cntUri - 업데이트될 container의 uri + * @param from - AE의 ID. + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doGetLatestContent(String cntUri, String from) throws OneM2MException { + return (ContentInstance)this.retrieveContentInstance(cntUri+"/"+Naming.LATEST_SN, from); + } + + // contentType: 1-resource, 2-modified attribute, 3-resourceId(uri) + + /** + * 리소스에 대한 구독을 신청한다. + * 지정한 리소스의 하위에 subscription리소스를 생성함 + * + * @param targetUri - 구독 신청할 리소스 uri + * @param from - AE의 ID. + * @param notificationUri - 컨테이너 리소스 수정, 하위 리소스 생성, 삭제에 대한 통지(notification)을 받을 URI, LGU+서버의 경우 통지를 받을 ae의 resourceID입력 + * @param notiContentType - 통지되는 정보의 종류 1:리소스 오브젝트, 2:수정된 속성을 포함한 리소스 오브젝트, 3:리소스 ID정보(이 경우 통지가 오면 해당 리소스 조회를 통해서 정보를 파악함) + * @param acpIds - 권한을 지정한 AccessControlPolicy + * @return 생성된 subscription 정보 오브젝트 + */ + public Subscription doCreateSubscription(String targetUri, String from, String subsName, String notificationUri, + int notiContentType, List acpIds, boolean retrieveBeforeCreate) throws Exception { + + // 이미 등록된 경우 Container정보 retrieve + if (retrieveBeforeCreate) { + try { + Subscription subs = (Subscription)this.retrieveSubscription(targetUri +"/"+subsName, from); + return subs; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + Subscription subs = new Subscription(); + subs.addNotificationURI(notificationUri); + EventNotificationCriteria cri = new EventNotificationCriteria(); + cri.addNotificationEventType(NOTIFICATIONEVENT_TYPE.CREATE_OF_CHILD_RESOURCE.Value()); + + subs.setEventNotificationCriteria(cri); + subs.setNotificationContentType(notiContentType == 3 ? NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value() : + NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); + + + if (acpIds != null) { + Iterator it = acpIds.iterator(); + while (it.hasNext()) { + subs.addAccessControlPolicyIDs(it.next()); + } + } + + return createSubscription(targetUri, from, subsName, subs); + + } + + /** + * Subscription 리소스를 조회한다. + * + * @param subsUri - 조회할 Subscription 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 Subscription 정보 + * @throws OneM2MException + */ + public Subscription doRetrieveSubscription(String subsUri, String from) throws OneM2MException { + + return retrieveSubscription(subsUri, from); + + } + + /** + * NOT TESTED!!!! + * AE에 대한 구독을 신청한다. + * AE가 생성될 경우 notification을 받을 수 있도록 csebase하위에 subscription리소스를 생성함 + * + * @param deviceAppName - 구독 신청할 AE의 애플리케이션명, 해당 애플리케이션에 속한 AE의 생성 삭제에 대해서만 통지됨 + * @param from - AE의 ID. + * @param notificationUri - AE 생성 삭제에 대한 통지(notification)을 받을 URI, LGU+서버의 경우 통지를 받을 ae의 resourceID입력 + * @return 생성된 subscription 정보 오브젝트 + */ +// public Subscription doAESubscription(String deviceAppName, String from, String notificationUri) throws Exception { +// +// Subscription subs = new Subscription(); +// subs.addNotificationURI(notificationUri); +// EventNotificationCriteria cri = new EventNotificationCriteria(); +// cri.addNotificationEventType(NOTIFICATIONEVENT_TYPE.CREATE_OF_CHILD_RESOURCE.Value()); +// cri.addAttribute(new Attribute(Naming.RESOURCETYPE_SN, RESOURCE_TYPE.AE.Value())); +// cri.addAttribute(new Attribute(Naming.APPNAME_SN, deviceAppName)); +// +// subs.setEventNotificationCriteria(cri); +// subs.setNotificationContentType(NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); +// +// return createSubscription(csebaseUri, from, subs); +// +// } + + + /** + * NOT TESTED!!!! + * AE에 정보를 검색한다. + * + * @param deviceAppName - 검색할 AE의 애플리케이션명, 해당 애플리케이션만 검색됨 + * @param createdSince - 생성시간조건, 지정된 시간 이후에 생성된 AE만 검색됨 + * @return 검색된 AE 목록 + */ +// public List doDiscoverDeviceAE(String deviceAppName, String createdSince) throws Exception { +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.DISCOVERY); +// request.setTo(this.csebaseUri); +// request.setFrom(ae.getResourceID()); +// request.setRequestId(Utils.createRequestId()); +// +// FilterCriteria fc = new FilterCriteria(); +// fc.setCreatedAfter(createdSince); +// fc.setFilterUsage(FILTER_USAGE.DISCOVERY.Value()); +// request.setFilterCriteria(fc); +// +// if (this.authController != null) this.authController.setAuthData(request); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); +// +// if (res.getResStatusCode() == RESPONSE_STATUS.OK) { +// +// UriListContent ulc = (UriListContent)convertToUriList(new String(res.getContent(), "UTF-8")); +// +// List aeList = new ArrayList(); +// List aeUriList = ulc.getUriList(); +// Iterator it = aeUriList.iterator(); +// +// while (it.hasNext()) { +// String uri = it.next(); +// AE ae = (AE)this.retrieveAE(uri, this.ae.getResourceID()); +// } +// +// return aeList; +// +// } else { +// log.debug("registration failed. {}", res.toString()); +// return null; +// } +// +// } + + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param method - 수신 메시지의 HTTP Method + * @param uri - 수신 메시지의 요청 URI + * @param headerMap - 수신 메시지의 HTTP 헤더맵 + * @param host - 수신 메시지의 호스트명 + * @param content - 수신 메시지의 Body 내용 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ +// public OneM2mResponse doProcessRequest(String method, String uri, HashMap headerMap, String host, byte[] content, +// NotiHandlerInterface notiHandler) throws Exception { +// +// OneM2mRequest reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); +// +// return doProcessRequest(reqMessage, notiHandler); +// } + + + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param reqMessage - 파싱된 OneM2M HTTP 요청 메시지 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ + public HttpBasicResponse doProcessRequest(HttpBasicRequest request, NotiHandlerInterface notiHandler) throws Exception { + + OneM2mRequest reqMessage = RequestCodec.decode(request.getMethod(), request.getUri(), request.getHeaders(), + request.getHost(), request.getContent()); + + OneM2mResponse resMessage = doProcessRequest(reqMessage, notiHandler); + + HttpBasicResponse response = ResponseCodec.encodeToBasic(resMessage, HttpVersion.HTTP_1_1); + + return response; + + } + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param reqMessage - 파싱된 OneM2M HTTP 요청 메시지 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ + public OneM2mResponse doProcessRequest(OneM2mRequest reqMessage, NotiHandlerInterface notiHandler) throws Exception { + + Notification noti = null; + try { + noti = convertToNotification(new String(reqMessage.getContent(), "UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Fail to convert to notification obejct:"+e.getMessage()); + } + + + if (noti.isVerificationRequest() != null && noti.isVerificationRequest()) { + return new OneM2mResponse(RESPONSE_STATUS.OK, reqMessage); + } + + NotificationEvent ne = noti.getNotificationEvent(); + if (ne == null) { + OneM2mResponse res = new OneM2mResponse(RESPONSE_STATUS.BAD_REQUEST, reqMessage); + res.setContent(new String("NotificationEvent should be provided!").getBytes()); + return res; + } + + OperationMonitor om = ne.getOperationMonitor(); + + RESPONSE_STATUS status = null; + Resource resource = null; + String resId = null; + + OPERATION op = OPERATION.CREATE; + if (om != null) { + op = OPERATION.get(om.getOperation()); + } + + Object rep = ne.getRepresentation().getResource(); + + try { + if (rep instanceof UriListContent) { + resId = ((UriListContent)rep).getUriList().get(0); + //OneM2mResponse response = this.retrieve(resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof String) { + resId = (String)rep; + //OneM2mResponse response = this.retrieve(this.cseId+"/"+resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof UriContent) { + resId = ((UriContent)rep).getUri(); + //OneM2mResponse response = this.retrieve(((UriContent)rep).getUri(), this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof Resource) { + resource = (Resource)rep; + } else if (rep instanceof XMLRoot) { + XMLRoot root = (XMLRoot)rep; + resId = (String)root.getObject(); + //OneM2mResponse response = this.retrieve(this.cseId+"/"+resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else { + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Unexpected representation:"+ (rep != null ? rep.getClass().getName() : "null")); + } + } catch (OneM2MException e) { + throw e; + } catch (Exception e) { + + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Unexpected representation:"+e.getMessage()); + + } + + if (resource == null && resId != null) { + status = notiHandler.handleCreateNoti(resId, noti); + } else { + + switch (op) { + case CREATE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case CONTENT_INST: + status = notiHandler.handleCreateNoti((ContentInstance)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleCreateNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleCreateNoti(resource, noti); + break; + } + case UPDATE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case AE: + status = notiHandler.handleUpdateNoti((AE)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleUpdateNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleUpdateNoti(resource, noti); + break; + } + case DELETE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case CONTENT_INST: + status = notiHandler.handleDeleteNoti((ContentInstance)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleDeleteNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleDeleteNoti(resource, noti); + break; + } + case RETRIEVE: + case NOTIFY: + default: + break; + } + } + + return new OneM2mResponse(status, reqMessage); + } + + + + + + + + + + + + private Logger log = LoggerFactory.getLogger(AEController.class); + + protected String cseAddr; + protected CONTENT_TYPE contentType; + + protected AE ae = null; + protected String csebaseUri; + protected String cseId; + + protected AuthControllerInterface authController = null; + + + protected Resource convertToResource(RESOURCE_TYPE resType, OneM2mResponse res) throws OneM2MException { + + try { + Resource resource = convertToResource(resType, new String(res.getContent(), "UTF-8")); + resource.setUri(res.getContentLocation()); + return resource; + } catch (Exception e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Error during content utf8 encoding:"+e.getMessage()); + } + + } + + protected Resource convertToResource(OneM2mResponse res) throws OneM2MException { + + try { + String pc = new String(res.getContent(), "UTF-8"); + Resource resource = convertToResource(Utils.getResTypeWithContentString(pc, res.getContentType()), pc); + resource.setUri(res.getContentLocation()); + return resource; + } catch (Exception e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Error during content utf8 encoding:"+e.getMessage()); + } + + } + + protected Resource convertToResource(RESOURCE_TYPE resType, String content) throws OneM2MException { + try { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = null; + switch (resType) { + case AE: + xmlCvt = ConvertorFactory.getXMLConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + xmlCvt = ConvertorFactory.getXMLConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + xmlCvt = ConvertorFactory.getXMLConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + break; + case SUBSCRIPTION: + xmlCvt = ConvertorFactory.getXMLConvertor(Subscription.class, Subscription.SCHEMA_LOCATION); + break; + case NOTIFICATION: + xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + case ACCESS_CTRL_POLICY: + xmlCvt = ConvertorFactory.getXMLConvertor(AccessControlPolicy.class, AccessControlPolicy.SCHEMA_LOCATION); + break; + } + + if (xmlCvt == null) return null; + else + return (Resource)xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = null; + switch (resType) { + case AE: + jsonCvt = ConvertorFactory.getJSONConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + jsonCvt = ConvertorFactory.getJSONConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + jsonCvt = ConvertorFactory.getJSONConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + break; + case SUBSCRIPTION: + jsonCvt = ConvertorFactory.getJSONConvertor(Subscription.class, Subscription.SCHEMA_LOCATION); + break; + case NOTIFICATION: + jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + } + + if (jsonCvt == null) return null; + else return (Resource)jsonCvt.unmarshal(content); + + } + + } catch (Exception e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during contentToResource:"+ e.getMessage()); + } + } + + + protected Notification convertToNotification(String content) throws Exception { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + if (xmlCvt == null) return null; + else return (Notification) xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, Notification.SCHEMA_LOCATION); + if (jsonCvt == null) return null; + else return (Notification)jsonCvt.unmarshal(content); + + } + + } + + + protected UriListContent convertToUriList(String content) throws Exception { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(UriListContent.class, UriListContent.SCHEMA_LOCATION); + if (xmlCvt == null) return null; + else return (UriListContent) xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = ConvertorFactory.getJSONConvertor(UriListContent.class, UriListContent.SCHEMA_LOCATION); + if (jsonCvt == null) return null; + else return (UriListContent)jsonCvt.unmarshal(content); + + } + + } + + protected AE retrieveAE(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AE ae = (AE)convertToResource(RESOURCE_TYPE.AE, res); + if (ae.getUri() == null) { + ae.setUri(resUri); + } + return ae; + } + + protected AE updateAE(String resUri, AE ae, String from) throws OneM2MException { + + OneM2mResponse res = update(resUri, from, ae); + return (AE)convertToResource(RESOURCE_TYPE.AE, res); + + } + + protected AccessControlPolicy retrieveACP(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AccessControlPolicy acp = (AccessControlPolicy)convertToResource(RESOURCE_TYPE.ACCESS_CTRL_POLICY, res); + if (acp.getUri() == null) { + acp.setUri(resUri); + } + return acp; + + } + + protected Container retrieveContainer(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + Container container = (Container)convertToResource(RESOURCE_TYPE.CONTAINER, res); + if (container.getUri() == null) { + container.setUri(resUri); + } + return container; + } + + protected Subscription retrieveSubscription(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + Subscription subs = (Subscription)convertToResource(RESOURCE_TYPE.SUBSCRIPTION, res); + if (subs.getUri() == null) { + subs.setUri(resUri); + } + return subs; + } + + protected ContentInstance retrieveContentInstance(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + ContentInstance ci = (ContentInstance)convertToResource(RESOURCE_TYPE.CONTENT_INST, res); + if (ci.getUri() == null) { + ci.setUri(resUri); + } + return ci; + } + + +// private Resource retrieveResource(String resUri, String from) throws OneM2MException { +// +// OneM2mResponse res = retrieve(resUri, from); +// return convertToResource(res); +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.RETRIEVE); +// request.setTo(resUri); // "/casebase/SAE_1" +// request.setFrom(from); // "/SAE_1" +// request.setRequestId(OneM2mUtil.createRequestId()); +// request.setContentType(CONTENT_TYPE.RES_XML); +// request.setResultContent(RESULT_CONT.ATTRIBUTE); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); // "http://localhost:8080" +// +// if (res == null) { +// log.error("retrieveResource failed."); +// throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Faile to retrieveResource RES:null"); +// } +// +// if (res.getResStatusCode() == RESPONSE_STATUS.OK) { +// return convertToResource(RESOURCE_TYPE.AE, res); +// } else { +// log.error("retrieveResource failed. {}", res.toString()); +// throw new OneM2MException(res.getResStatusCode(), "Faile to retrieveResource RES:"+res.toString()); +// } +// +// } + + protected OneM2mResponse update(String resUri, String from, Resource resource) throws OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.UPDATE); + request.setTo(resUri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(resource); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); // "http://localhost:8080" + + + if (res == null) { + log.error("update failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CHANGED) { + return res; + } else { + log.error("update failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to uprdate resource, response:"+res.toString()); + } + + } + + protected OneM2mResponse retrieve(String resUri, String from) throws OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.RETRIEVE); + request.setTo(resUri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); // "http://localhost:8080" + + + if (res == null) { + log.error("retrieve failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK) { + return res; + } else { + log.error("retrieve failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to retrieve RES:"+res.toString()); + } + + } + + protected Subscription createSubscription(String targetUri, String from, String subsName, Subscription subs) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(targetUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.SUBSCRIPTION); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(subs); + if (subsName == null || subsName.length() == 0) { + subsName = "sub-"+ae.getResourceName().replace("-", "_"); // uplus 서버 제약사항 (resourcename에 '-' 사용 불가) + } + request.setName(subsName); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createSubscription failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Subscription subs1 = (Subscription)convertToResource(RESOURCE_TYPE.SUBSCRIPTION, res); + subs1.setUri(targetUri +"/"+ subs1.getResourceName()); + return subs1; + } else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + Subscription subs1 = this.retrieveSubscription(targetUri +"/"+subsName, from); + subs1.setUri(targetUri +"/"+ subs1.getResourceName()); + return subs1; + } else { + log.error("createSubscription failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createSubscription RES:null"); + } + + } + + protected AE createAE(String parentUri, String from, AE ae, String name) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.AE); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(ae); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createAE failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + AE ae1 = (AE)convertToResource(RESOURCE_TYPE.AE, res); + ae1.setUri(parentUri +"/" + ae1.getResourceName()); + return ae1; + } else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + // 이미 등록된 경우 AE정보 retrieve + AE ae1 = (AE)this.retrieveAE(parentUri +"/"+name, from); + ae1.setUri(parentUri +"/"+name); + + // poa가 변경된 경우 AE update + String curPoa = ae1.getPointOfAccess() != null && ae1.getPointOfAccess().size() > 0 ? ae1.getPointOfAccess().get(0) : null; + String newPoa = ae.getPointOfAccess() != null && ae.getPointOfAccess().size() > 0 ? ae.getPointOfAccess().get(0) : null; + if (curPoa != newPoa) { + AE aeU = new AE(); + aeU.setUri(parentUri +"/" + ae1.getResourceName()); + aeU.addPointOfAccess(newPoa); + this.updateAE(aeU.getUri(), aeU, from); + + if (ae1.getPointOfAccess() != null) { + ae1.getPointOfAccess().clear(); + } + ae1.addPointOfAccess(newPoa); + } + + return ae1; + } else { + log.debug("createAE failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Fail to createAE RES:"+res.toString()); + } + + } + + + protected AccessControlPolicy createACP(String parentUri, String from, AccessControlPolicy acp, String name) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.ACCESS_CTRL_POLICY); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(acp); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createAE failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + AccessControlPolicy acpRes = (AccessControlPolicy)convertToResource(RESOURCE_TYPE.ACCESS_CTRL_POLICY, res); + acpRes.setUri(parentUri +"/" + acpRes.getResourceName()); + return acpRes; + } else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + return null; + } else { + log.debug("createACP failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Fail to createACP RES:"+res.toString()); + } + + } +// private AE retrieveAE(String resUri, String from) throws Exception { +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.RETRIEVE); +// request.setTo(resUri); // "/casebase/SAE_1" +// request.setFrom(from); // "/SAE_1" +// request.setRequestId(OneM2mUtil.createRequestId()); +// request.setContentType(CONTENT_TYPE.RES_XML); +// request.setResultContent(RESULT_CONT.ATTRIBUTE); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); // "http://localhost:8080" +// +// if (res == null) { +// log.debug("retrieveAE failed."); +// return null; +// } +// +// if (res != null && res.getResStatusCode() == RESPONSE_STATUS.OK) { +// return (AE)convertToResource(RESOURCE_TYPE.AE, new String(res.getContent(), "UTF-8")); +// } else { +// log.debug("retrieveAE failed. {}", res.toString()); +// return null; +// } +// +// } + + protected Container createContainer(String parentUri, String from, Container container, String name) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.CONTAINER); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(container); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Container cntr = (Container)convertToResource(RESOURCE_TYPE.CONTAINER, res); + cntr.setUri(parentUri +"/" + cntr.getResourceName()); + return cntr; + } else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + // 이미 등록된 경우 AE정보 retrieve + Container cntr = (Container)this.retrieveContainer(parentUri +"/"+name, from); + cntr.setUri(parentUri +"/" + cntr.getResourceName()); + return cntr; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:"+res.toString()); + } + + } + + protected ContentInstance createContentInstance(String parentUri, String from, ContentInstance ci, String ciName) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.CONTENT_INST); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(ci); + if (ciName != null) { + request.setName(ciName); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + ContentInstance ci1 = (ContentInstance)convertToResource(RESOURCE_TYPE.CONTENT_INST, res); + ci1.setUri(parentUri +"/"+ ci1.getResourceName()); + return ci1; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:null"+res.toString()); + } + + } + + protected boolean deleteResource(String uri, String from) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.RETRIEVE); + request.setTo(uri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("deleteResource failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK) { + return true; + } else { + log.error("deleteResource failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to deleteResource RES:"+res.toString()); + } + + } +// public Resource parseContentResource(AbsMessage message, ManagerInterface manager) throws OneM2MException { +// +// try { +// Resource res; +// String str = new String(message.getContent(), "UTF-8"); +// XMLConvertor xmlCvt; +// JSONConvertor jsonCvt; +// switch (message.getContentType()) { +// case RES_XML: +// xmlCvt = manager.getXMLConveter(); +// res = (Resource)xmlCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// case RES_JSON: +// jsonCvt = manager.getJSONConveter(); +// res = (Resource)jsonCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// case XML: // cannot sure if content is resource or not, so just return null in case exception +// try { +// xmlCvt = manager.getXMLConveter(); +// res = (Resource)xmlCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// } catch(Exception e) { +// e.printStackTrace(); +// return null; +// } +// case JSON: // cannot sure if content is resource or not, so just return null in case exception +// try { +// jsonCvt = manager.getJSONConveter(); +// res = (Resource)jsonCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// } catch(Exception e) { +// e.printStackTrace(); +// return null; +// } +// +// default: +// return null; +// } +// } catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// +// throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); +// } +// +// } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEControllerEx.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEControllerEx.java new file mode 100644 index 0000000..5dbb95c --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/AEControllerEx.java @@ -0,0 +1,233 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.message.onem2m.format.Enums.FILTER_USAGE; +import net.herit.iot.onem2m.ae.lib.AuthControllerInterface; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.bind.http.client.HttpClient; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.core.util.Utils; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.FilterCriteria; +import net.herit.iot.onem2m.resource.UriListContent; + +/** + * AE가 IN-CSE와 연동하기 위한 함수를 제공하는 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class AEControllerEx extends AEController { + + private Logger log = LoggerFactory.getLogger(AEControllerEx.class); + + private HubissEmulatorHttpListener httpListener; + private NotiHandlerInterface notiHandler; + + // 제어 요청과 결과를 저장한 클래스 + static class Command { + Command(ContentInstance ciCommand) { + this.ciCommand = ciCommand; + } + public ContentInstance ciCommand; + public ContentInstance ciResult; + public ContentInstance getCiCommand() { return ciCommand; } + public ContentInstance getCiResult() { return ciResult; } + public void setCiCommand(ContentInstance ci) { this.ciCommand = ci; } + public void setCiResult(ContentInstance ci) { this.ciResult = ci; } + } + // CommandResult를 저장한 해시맵 + private ConcurrentHashMap commandMap = new ConcurrentHashMap(); + + protected void putNWaitCommand(String name, Command cmd, long timeout) throws InterruptedException { + commandMap.put(name, cmd); + synchronized (cmd) { + cmd.wait(timeout); + } + } + protected Command setResultNNotifyCommand(ContentInstance ci) { + + Command cmd = commandMap.get(ci.getResourceName()); + if (cmd != null) { + log.debug("Set command result and notify!!!!"); + cmd.setCiResult(ci); + synchronized (cmd) { + cmd.notifyAll(); + } + } + return cmd; + } + protected void removeCommand(Command cmd) throws InterruptedException { + commandMap.remove(cmd.getCiCommand().getResourceName()); + } + protected ConcurrentHashMap getCommandMap() { + return commandMap; + } + + /** + * AE 컨트롤러 생성자 + * + * @param cseAddr - INCSE 주소 (INCSE 고정값) + * @param cseId - INCSE의 cse id (INCSE 고정값) + * @param csebaseName - INCSE의 csebase 리소스의 이름 (INCSE 고정값) + * @param contentType - 서버 연동에 사용할 Content-Type (XML:CONTENT_TYPE.XML, JSON:CONTENT_TYPE.JSON) + * @param authController - 인증 수행 클래스, 입력된 클래스는 AE 등록시 인증을 수행하고, 인증정보를 REQUEST메시지에 주입한다. + * + */ + public AEControllerEx(String cseAddr, String cseId, String csebaseName, + CONTENT_TYPE contentType, AuthControllerInterface authController) { + + super(cseAddr, cseId, csebaseName, contentType, authController); + } + + + /** + * HTTP 서버를 시작한다. + * * + * @param ip - HTTP 서버 IP + * @param port - HTTP 서버 포트 + * @param notiHandler - Notification 처리 클래스 인스턴스 + * @return 검색결과 데이터 (Content) + * @throws OneM2MException + */ + public void doHttpServerStart(String ip, int port, NotiHandlerInterface notiHandler) throws Exception { + + this.notiHandler = notiHandler; + this.httpListener = new HubissEmulatorHttpListener(ip, port, this, notiHandler); + this.httpListener.start(); + + } + + /** + * HTTP 서버를 종료한다. + * * + * @throws Exception + */ + public void doHttpServerStop() throws Exception { + this.httpListener.stop(); + } + + + /** + * 제어를 수행한다. + * + * # 컨테이너 구조 + * - gas_0001: 제어 대상 디바이스 AE + * |- switch: 제어 대상 항목 + * |- Execute: 제어 요청 전송용 container (디바이스가 subscribe 해야 함) + * |- Result: 제어 결과 전송용 container (서비스 애플리케이션이 subscribe 해야 함) + * + * # 메시지 규칙 + * - request: command식별자를 이름으로 contentInstance 생성 + * - response: request와 동일한 이름으로 contentInstance 생성 + * + * * + * @param resUri - 제어대상 container id (structured id). + * @param from - AE의 ID. + * @param ci - 제어를 위해 전송될 데이터를 포함한 contentInstance + * @return 검색결과 데이터 (Content) + * @throws OneM2MException + */ + public ContentInstance doControlCommand(String resUri, String from, ContentInstance ci, long timeout) throws OneM2MException { + + String ciName = Utils.createRequestId(); + ContentInstance ciCommand = this.createContentInstance(resUri +"/Execute", from, ci, ciName); + + log.debug("Command sent (Sent RN:"+ciName+", Recv RN:"+ciCommand.getResourceName()+", Recv Uri:"+ciCommand.getUri()+")"); + + Command cmd = new Command(ciCommand); + try { + this.putNWaitCommand(ciCommand.getResourceName(), cmd, timeout); + ContentInstance ciResult = cmd.getCiResult(); + if (ciResult == null) { + log.debug("Timeout:"+ciName); + try { + ciResult = this.retrieveContentInstance(resUri+"/Result/"+ciCommand.getResourceName(), from); + if (ciResult != null) { + return ciResult; + } + } catch (OneM2MException ex) { + System.out.println("doControlCommand - exception on retrieveContentInstance("+resUri+"/Result/"+ + ciCommand.getResourceName()+"):"+ex.getMessage()); + throw new OneM2MException(RESPONSE_STATUS.COMMAND_TIMEOUT, "Command timeout"); + } + + } else { + log.debug("Recv command result:"+ciName); + this.removeCommand(cmd); + return ciResult; + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + + } + + return null; + + } + + + /** + * 등록된 리소스를 전달된 FilterCriteria를 조건으로 검색한다. + * * + * @param resUri - 리소스를 검색할 리소스 URI(structured id). + * @param from - AE의 ID. + * @param fc - 검색 조건 + * @return 검색된 리소스 id 목록 + * @throws OneM2MException + */ + public List doDiscovery(String resUri, String from, FilterCriteria fc) throws OneM2MException { + + UriListContent ulc = this.discovery(resUri, from, fc); + return ulc.getUriList(); + + } + + + protected UriListContent discovery(String resUri, String from, FilterCriteria fc) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.DISCOVERY); + request.setTo(resUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setContentType(CONTENT_TYPE.RES_JSON); + //request.setResultContent(RESULT_CONT.ATTRIBUTE); + fc.setFilterUsage(FILTER_USAGE.DISCOVERY.Value()); + request.setFilterCriteria(fc); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("retrieve failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK) { + + try { + return (UriListContent)convertToUriList(new String(res.getContent(), "UTF-8")); + } catch (Exception e) { + throw new OneM2MException(RESPONSE_STATUS.BAD_RESPONSE, "Fail to parse RES:"+e.getMessage()); + } + + + } else { + log.error("Discovery failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to retrieve RES:"+res.toString()); + } + + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissAuthController.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissAuthController.java new file mode 100644 index 0000000..d87c384 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissAuthController.java @@ -0,0 +1,63 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.onem2m.ae.lib.AuthControllerInterface; +import net.herit.iot.onem2m.core.util.OneM2MException; + +/** + * LGU+ OneM2M MES서버 연동 기능을 구현한 클래스 + * + * @version : 1.0 + * @author : Lee inseuk + */ +public class HubissAuthController implements AuthControllerInterface { + + private Logger log = LoggerFactory.getLogger(HubissAuthController.class); + + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public void setAuthData(OneM2mRequest request) throws OneM2MException { + + log.debug("setAuthData called but nothing to do."); + + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public boolean isAuthorized() { + + return true; + + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public String getEntityId() { + + return null; + + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public void doAuth() throws OneM2MException { + + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulator.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulator.java new file mode 100644 index 0000000..5c146e5 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulator.java @@ -0,0 +1,233 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.LGUAuthController; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData.Http; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.FilterCriteria; +import net.herit.iot.onem2m.resource.Subscription; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class HubissEmulator { + + private final static HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + private Logger log = LoggerFactory.getLogger(HubissEmulator.class); + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + + + public HubissEmulator() { + + } + + public void start() throws Exception { + + String aeId = "CAE_HUBISS_ADMIN"; + String aeName = "hubiss_admin"; + String appId = "HUBISS"; + String appName = "HUBISS_ADMIN"; + + String cseAddr = "http://10.101.101.195:8090"; + //String csebase = "/herit-in/herit-cse"; + //String csebaseName = "herit-cse"; + String csebase = "/mobius-yt"; + String csebaseName = ""; + String cseId = "mobius-yt"; + + String ip = "10.101.101.180"; + int port = 9902; + String poa = "http://10.101.101.180:9901"; + + AEControllerEx aeController; + HubissEmulatorNotiHandler notiHandler; + + + try { + + // AE 컨트롤러 생성 + aeController = new AEControllerEx(cseAddr, cseId, csebaseName, CONTENT_TYPE.RES_XML, null); + + // Notification Handler 생성 + notiHandler = new HubissEmulatorNotiHandler(aeController); + aeController.doHttpServerStart(ip, port, notiHandler); + + // AE 생성 + AE ae = new AE(); + ae.setAppID(appId); + ae.setAppName(appName); + ae.addPointOfAccess(poa); + ae.setRequestReachability(true); + ae.addLabels("hubiss"); + ae.addLabels("admin"); + ae = aeController.doCreateAE(csebase, aeId, aeName, ae, true); + + + } catch (OneM2MException e) { + + RESPONSE_STATUS status = e.getResponseStatusCode(); + log.debug("Status:" + status.toString()); + + log.error("OneM2MException occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + return; + + } catch (Exception e) { + + log.error("Exception occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + return; + + } + + try{ + // 디바이스 등록 + String deviceUri = null, valveUri = null, tempUri = null, co2Uri = null, humidUri = null; + + BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); + while (true) { + System.out.println("Enter command!"); + System.out.println("'d:[deviceId]': discover & subscribe device."); + System.out.println("'r': retrieve status (valve, humidity, temperature, co2)"); + System.out.println("'v:[ON/OFF]': control valve"); + System.out.println("'bye': stop program"); + + String s = bufferRead.readLine(); + + if (s.equalsIgnoreCase("BYE")) { + break; + } + System.out.println(s); + + String param; + + try { + if (s.startsWith("bye")) + break; + + String cmd = s.substring(0,1); + switch (cmd) { + case "d": + param = s.substring(2); + FilterCriteria fc = new FilterCriteria(); + fc.setResourceType(RESOURCE_TYPE.AE.Value()); + fc.addLabels(param); + fc.setResourceType(2); + List devIds = aeController.doDiscovery(csebase, aeId, fc); + + if (devIds.size() == 0) { + System.out.println("No device discovered. Retry with another deviceId!"); + continue; + } + + int i = 1; + String deviceList = "[Device IDs]\r\n"; + Iterator it = devIds.iterator(); + while (it.hasNext()) { + deviceList += Integer.toString(i)+":"+it.next()+"\r\n"; + } + System.out.println(deviceList); + System.out.println("Input device number:"); + + s = bufferRead.readLine(); + int selected = Integer.parseInt(s); + deviceUri = devIds.get(selected-1); + + valveUri = deviceUri + "/VALVE"; + tempUri = deviceUri + "/TEMPERATURE"; + co2Uri = deviceUri + "/CO2"; + humidUri = deviceUri + "/HUMIDITY"; + + AE aeDevice = aeController.doRetrieveAE(deviceUri, aeId); + Subscription valveExecuteSubs = aeController.doCreateSubscription(valveUri+"/Result", aeId, "sub-"+aeId, poa /*aeId notificationUri*/, NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value(), null, true); + + break; + + case "r": + if (deviceUri == null) { + System.out.println("No device selected. please do discover first."); + continue; + } + // 상태 조회 + ContentInstance ci; + ci = aeController.doGetLatestContent(valveUri, aeId); + log.debug("valve:"+ci.getContent()); + ci = aeController.doGetLatestContent(tempUri, aeId); + log.debug("temperature:"+ci.getContent()); + ci = aeController.doGetLatestContent(co2Uri, aeId); + log.debug("co2:"+ci.getContent()); + ci = aeController.doGetLatestContent(humidUri, aeId); + log.debug("humidity:"+ci.getContent()); + break; + + case "v": + param = s.substring(2); + ContentInstance ciCommand = new ContentInstance(); + ciCommand.setContentInfo("text/plain:0"); + ciCommand.setContent(param); + ci = aeController.doControlCommand(valveUri, aeId, ciCommand, 20000 /*timeout*/); + log.debug("Control result:"+ci.getContent()); + break; + + default: + System.out.println("Unknown command: "+s); + + } + continue; + } catch (OneM2MException e) { + + log.error("OneM2MException occurred!!!"); + log.error(e.toString()); + e.printStackTrace(); + + } catch (Exception e) { + + System.out.println("Unknown command or exception: "+s +"\r\n"+e.getMessage()); + continue; + + } + } + + aeController.doHttpServerStop(); + + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + + public static void main(String[] args) throws Exception { + new HubissEmulator().start(); + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorHttpListener.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorHttpListener.java new file mode 100644 index 0000000..0b80f25 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorHttpListener.java @@ -0,0 +1,251 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AttributeKey; +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.onem2m.ae.http.api.HttpServerListener; +import net.herit.iot.onem2m.ae.http.server.HttpServer; +import net.herit.iot.onem2m.ae.http.server.HttpServerHandler; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.HttpBasicRequest; +import net.herit.iot.onem2m.ae.lib.HttpBasicResponse; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.bind.http.codec.ResponseCodec; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; + +public class HubissEmulatorHttpListener implements HttpServerListener { + + private final HttpVersion httpVersion = HttpVersion.HTTP_1_1; + + public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private HttpServer httpServer; + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(HubissEmulatorHttpListener.class); + + private AEControllerEx aeController; + private NotiHandlerInterface notiHandler; + + public HubissEmulatorHttpListener(String ip, int port, AEControllerEx aeController, NotiHandlerInterface notiHandler) { + try { + + httpServer = new HttpServer(this, port); + logManager.initialize(LoggerFactory.getLogger("IITP-IOT-APP-AE"), null); + this.notiHandler = notiHandler; + this.aeController = aeController; + + } catch (Exception e) { + + e.printStackTrace(); + + } + + } + + public void start() throws Exception { + + httpServer.runAsync(); + + } + + public void stop() { + + httpServer.stop(); + + } + + + + @Override + public void channelDisconnected(ChannelHandlerContext ctx) { + log.debug("channelDisconnected"); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx) { + log.debug("channelConnected"); + + } + + @Override + public void channelRequested(ChannelHandlerContext ctx) { + log.debug("channelRequested"); + + } + + @Override + public void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { + log.debug("handleHttpRequest from " + ctx.channel().remoteAddress().toString()); + OneM2mRequest reqMessage = null; + try { + +// HashMap headerMap = new HashMap(); +// HttpHeaders headers = request.headers(); +// Iterator> it = headers.iterator(); +// while (it.hasNext()) { +// Entry header = it.next(); +// headerMap.put(header.getKey(), header.getValue()); +// } + + String host = ((InetSocketAddress)ctx.channel().remoteAddress()).getHostString(); + String method = request.getMethod().name(); + String uri = request.getUri(); + byte[] content = request.content().isReadable() ? request.content().copy().array() : null; + + HttpBasicRequest basicRequest = new HttpBasicRequest(method, uri, host, content); + + HttpHeaders headers = request.headers(); + Iterator> it = headers.iterator(); + while (it.hasNext()) { + Entry header = it.next(); + basicRequest.addHeader(header.getKey(), header.getValue()); + } + + //reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); + HttpBasicResponse response = this.aeController.doProcessRequest(basicRequest, this.notiHandler); + + DefaultFullHttpResponse dfResponse = null; + if (response.getContent() != null) { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK, + Unpooled.copiedBuffer(response.getContent()), false); + } else { + dfResponse = new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.OK); + } + + dfResponse.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + HttpServerHandler.sendHttpMessage(dfResponse, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + + } catch (OneM2MException ex) { + OneM2mResponse resMessage = new OneM2mResponse(ex.getResponseStatusCode(), reqMessage); + resMessage.setContent(new String(ex.getMessage()).getBytes()); + try { + + sendResponse(ctx, ResponseCodec.encode(resMessage, httpVersion)); + + } catch (Exception e) { + e.printStackTrace(); + } + + } catch (Throwable th) { + th.printStackTrace(); + log.error("RequestMessage decode failed.", th); + + sendError(ctx); + } + } + + private void sendError(ChannelHandlerContext ctx) { + DefaultFullHttpResponse response = + new DefaultFullHttpResponse(httpVersion, HttpResponseStatus.INTERNAL_SERVER_ERROR); + HttpServerHandler.sendHttpMessage(response, ctx.channel()). + addListener(ChannelFutureListener.CLOSE). + addListener(new FilnalEventListener(ctx, true)); + } + + private class FilnalEventListener implements ChannelFutureListener { + + private ChannelHandlerContext channelContext = null; + private boolean isClose = false; + + public FilnalEventListener(ChannelHandlerContext channelContext, boolean isClose) { + this.channelContext = channelContext; + this.isClose = isClose; + } + + @Override + public void operationComplete(ChannelFuture arg0) throws Exception { + log.debug("FinalEventListener.operationComplete.."); + } + + } + + protected ChannelFuture sendResponse(ChannelHandlerContext ctx, final FullHttpResponse response) + { + + if (ctx.attr(ATTR_KEY_REQUEST).get() != null) + { + FullHttpRequest request = ctx.attr(ATTR_KEY_REQUEST).get(); + + if (HttpHeaders.isKeepAlive(request)) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + } + } + + if (response.headers().get(HttpHeaders.Names.CONNECTION) == null) + { + response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + } + + ChannelFuture future = ctx.writeAndFlush(response); + future.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception + { + if (channelFuture.isDone() && channelFuture.isSuccess()) + { + if (log.isDebugEnabled()) + { + log.debug(""); + log.debug("############################## Send Log ############################"); + log.debug("---------------------------------------------------------------------"); + log.debug("SEND HTTP Response: " + channelFuture.channel()); + for (Map.Entry entry : response.headers()) + { + log.debug("HEADER: " + entry.getKey() + " = " + entry.getValue()); + } + log.debug("VERSION: " + response.getProtocolVersion()); + log.debug("STATUS: " + response.getStatus()); + + log.debug("---------------------------------------------------------------------"); + log.debug(""); + } + } + else + { + if (log.isErrorEnabled()) + { + log.error( + "operationComplete_failure channel=" + channelFuture.channel() + ", isDone=" + channelFuture.isDone() + ", isSuccess=" + channelFuture.isSuccess() + + ", isCancelled=" + channelFuture.isCancelled() + ", isCancellable" + channelFuture.isCancellable() + "\n" + response, + channelFuture.cause()); + } + } + + } + }); + + log.debug("response.headers().get(CONNECTION)=" + response.headers().get(HttpHeaders.Names.CONNECTION)); + if (!response.headers().get(HttpHeaders.Names.CONNECTION).equals(HttpHeaders.Values.KEEP_ALIVE)) + { + log.debug("connection close"); + future.addListener(ChannelFutureListener.CLOSE); + } + + return future; + } + + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorNotiHandler.java b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorNotiHandler.java new file mode 100644 index 0000000..aa4c0f1 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/hubiss/HubissEmulatorNotiHandler.java @@ -0,0 +1,147 @@ +package net.herit.iot.onem2m.ae.hubiss; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.onem2m.ae.hubiss.AEControllerEx.Command; +import net.herit.iot.onem2m.ae.lib.AEController; +import net.herit.iot.onem2m.ae.lib.NotiHandlerInterface; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; + +/** + * AE컨트롤러 클래스를 이용하여 디바이스 애뮬레이터를 구현한 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +public class HubissEmulatorNotiHandler implements NotiHandlerInterface { + + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(HubissEmulatorNotiHandler.class); + + //public static AttributeKey ATTR_KEY_REQUEST = AttributeKey.valueOf("httpRequest"); + + private AEControllerEx aeController = null; + + private Container switchCmdCntRes = null; + private Container switchCntRes = null; + private AE ae = null; + + public HubissEmulatorNotiHandler(AEControllerEx aeController) { + + this.aeController = aeController; + + this.switchCmdCntRes = null; + this.switchCntRes = null; + this.ae = null; + + } + + public void setResource(AE ae, Container switchCmdCntRes, Container switchCntRes) { + this.switchCmdCntRes = switchCmdCntRes; + this.switchCntRes = switchCntRes; + this.ae = ae; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(ContentInstance ci, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + String resName = ci.getResourceName(); + String resUri = ci.getUri(); + + log.debug("handleCreateNoti called"); + log.debug(" resourceName:"+resName); + log.debug(" resourceUri:"+resUri); + + Command cmd = this.aeController.setResultNNotifyCommand(ci); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleCreateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(String resId, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}, {}", notification.toString(), resId); + + ContentInstance ci = this.aeController.doRetrieveContentInstance(resId, this.ae.getResourceID()); + log.debug("CI:"+ci.toString()); + + return RESPONSE_STATUS.OK; + + } + + @Override + public RESPONSE_STATUS handleCreateNoti(Container ci, Notification notification) throws OneM2MException { + + log.debug("handleCreateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(AE ae, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(Container container, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleUpdateNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleUpdateNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(Container container, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(ContentInstance ci, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + } + + @Override + public RESPONSE_STATUS handleDeleteNoti(Resource resource, Notification notification) throws OneM2MException { + + log.debug("handleDeleteNoti:{}", notification.toString()); + + return RESPONSE_STATUS.OK; + + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/AEController.java b/src/main/java/net/herit/iot/onem2m/ae/lib/AEController.java new file mode 100644 index 0000000..e7f0979 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/AEController.java @@ -0,0 +1,1619 @@ +package net.herit.iot.onem2m.ae.lib; + +import io.netty.handler.codec.http.HttpVersion; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.persistence.oxm.XMLRoot; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse; +import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; +import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; +import net.herit.iot.message.onem2m.OneM2mRequest.RESULT_CONT; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; +import net.herit.iot.onem2m.bind.http.client.HttpClient; +import net.herit.iot.onem2m.bind.http.codec.RequestCodec; +import net.herit.iot.onem2m.bind.http.codec.ResponseCodec; +import net.herit.iot.onem2m.core.convertor.ConvertorFactory; +import net.herit.iot.onem2m.core.convertor.JSONConvertor; +import net.herit.iot.onem2m.core.convertor.XMLConvertor; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.core.util.Utils; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.AEAnnc; +import net.herit.iot.onem2m.resource.AccessControlPolicy; +import net.herit.iot.onem2m.resource.AccessControlRule; +import net.herit.iot.onem2m.resource.AggregatedResponse; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContainerAnnc; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.ContentInstanceAnnc; +import net.herit.iot.onem2m.resource.EventNotificationCriteria; +import net.herit.iot.onem2m.resource.Group; +import net.herit.iot.onem2m.resource.Naming; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; +import net.herit.iot.onem2m.resource.SetOfAcrs; +import net.herit.iot.onem2m.resource.Subscription; +import net.herit.iot.onem2m.resource.UriContent; +import net.herit.iot.onem2m.resource.UriListContent; +import net.herit.iot.onem2m.resource.Notification.NotificationEvent; +import net.herit.iot.onem2m.resource.Notification.NotificationEvent.OperationMonitor; +import net.herit.iot.onem2m.resource.Request; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONCONTENT_TYPE; +import net.herit.iot.onem2m.resource.Subscription.NOTIFICATIONEVENT_TYPE; + +/** + * AE가 IN-CSE와 연동하기 위한 함수를 제공하는 클래스 + * @version : 1.0 + * @author : Lee inseuk + */ +/** + * @author eastflag + * + */ +public class AEController { + + /** + * AE 컨트롤러 생성자 + * + * @param cseAddr - INCSE 주소 (INCSE 고정값) + * @param cseId - INCSE의 cse id (INCSE 고정값) + * @param csebaseName - INCSE의 csebase 리소스의 이름 (INCSE 고정값) + * @param contentType - 서버 연동에 사용할 Content-Type (XML:CONTENT_TYPE.XML, JSON:CONTENT_TYPE.JSON) + * @param authController - 인증 수행 클래스, 입력된 클래스는 AE 등록시 인증을 수행하고, 인증정보를 REQUEST메시지에 주입한다. + * @param maxCvtCnt - Convertor 풀내에 관리될 최대 Convertor 수 + * @throws OneM2MException + * + */ + public AEController(String cseAddr, String cseId, String csebaseName, + CONTENT_TYPE contentType, AuthControllerInterface authController, int maxCvtCnt) throws OneM2MException { + + this.cseAddr = cseAddr; + this.contentType = contentType; + this.csebaseUri = cseId +"/"+ csebaseName; + this.cseId = cseId; + this.authController = authController; + + ConvertorFactory.initialize(maxCvtCnt); + + } + + /** + * AE 컨트롤러 생성자 + * + * @param cseAddr - INCSE 주소 (INCSE 고정값) + * @param cseId - INCSE의 cse id (INCSE 고정값) + * @param csebaseName - INCSE의 csebase 리소스의 이름 (INCSE 고정값) + * @param contentType - 서버 연동에 사용할 Content-Type (XML:CONTENT_TYPE.XML, JSON:CONTENT_TYPE.JSON) + * @param authController - 인증 수행 클래스, 입력된 클래스는 AE 등록시 인증을 수행하고, 인증정보를 REQUEST메시지에 주입한다. + * + */ + public AEController(String cseAddr, String cseId, String csebaseName, + CONTENT_TYPE contentType, AuthControllerInterface authController) { + + this.cseAddr = cseAddr; + this.contentType = contentType; + this.csebaseUri = cseId +"/"+ csebaseName; + this.cseId = cseId; + this.authController = authController; + + } + + /** + * AccessControlPolicy를 등록한다. + * * + * @param parentUri - AccessControlPolicy 리소스를 생성할 부모 리소스 URI(structured id). + * @param from - AE의 ID. + * @param originIds - 권한을 허용할 AE 또는 CSE의 ID 목록. + * @param operation - 허용할 오퍼레이션, CREATE:1, RETRIEVE:2, UPDATE:4, DELETE:8, DISCOVERY:16, NOTIFY:32 (허용할 오퍼레이션의 합) + * @param retrieveBeforeCreate - create하기전에 retrieve하여 성공할 경우 retrieve된 값 반환 + * @return 서버에 생성된 AccessControlPolicy 정보, 이미 생성되어 추가 생성되지 못한 경우에는 null 반환 + * @throws OneM2MException + */ + public AccessControlPolicy doCreateACP(String parentUri, String from, String acpName, + List originIds, int operation, + List spOriginIds, int spOperation, + boolean retrieveBeforeCreate) throws OneM2MException { + + // 이미 등록된 경우 AE정보 retrieve + if (retrieveBeforeCreate) { + try { + AccessControlPolicy acp = (AccessControlPolicy)this.retrieveACP(parentUri +"/"+acpName, from); + return acp; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + SetOfAcrs soa = new SetOfAcrs(); + AccessControlRule acr = new AccessControlRule(originIds, operation); + soa.addAccessControlRule(acr); + + SetOfAcrs spSoa = new SetOfAcrs(); + AccessControlRule spAcr = new AccessControlRule(spOriginIds, spOperation); + spSoa.addAccessControlRule(spAcr); + + AccessControlPolicy acp = new AccessControlPolicy(); + acp.setPrivileges(soa); + acp.setSelfPrivileges(spSoa); + + AccessControlPolicy rAcp = createACP(parentUri, from, acp, acpName); + + return rAcp; + + } + + + /** + * AccessControlPolicy를 조회한다. + * * + * @param acpUri - 조회할 AccessControlPolicy 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 AccessControlPolicy 정보 + * @throws OneM2MException + */ + public AccessControlPolicy doRetrieveACP(String acpUri, String from) throws OneM2MException { + + return retrieveACP(acpUri, from); + + } + + /** + * AE를 IN-CSE에 등록한다. + * 모든 AE는 최소 1회이상 실행해야 하며, + * 이미 실행해서 INCSE에 등록되어 있을 경우 등록된 정보를 조회하여 반환한다. + * + * @param csebaseUri - IN-CSE의 csebase(root) 리소스 uri. + * @param aeId - AE의 ID. + * @param aeName - AE 이름 (예: ae-gaslock-001, LGU+ INCSE연동시 "ae-"로 시작하여야함) + * @param appId - AE의 애플리케이션 ID (AE는 애플리케이션의 하나의 instance) + * @param appName - AE의 애플리케이션 Name (AE는 애플리케이션의 하나의 instance) + * @param poa - IN-CSE에 AE로 REQUEST보낼 접속 주소, 예: http://onem2m.herit.net:8080 + * @return 서버에 저장된 AE 정보 + */ + public AE doCreateAE(String csebaseUri, String aeId, String aeName, String appId, String appName, + String poa, boolean retrieveBeforeCreate) throws OneM2MException { + + if (authController != null && authController.isAuthorized() == false) { + authController.doAuth(); + if (authController.getEntityId() != null) { + aeId = authController.getEntityId(); + } + } + + // 이미 등록된 경우 AE정보 retrieve + if (retrieveBeforeCreate) { + try { + this.ae = (AE)this.retrieveAE(csebaseUri +"/"+aeName, aeId); + return this.ae; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + + AE ae1 = new AE(); + //ae1.setAEID(aeId); + ae1.setAppID(appId); + ae1.setAppName(appName); + ae1.addPointOfAccess(poa); + ae1.setRequestReachability(true); + + this.ae = createAE(csebaseUri, aeId, ae1, aeName); + + return this.ae; + + } + + + /** + * AE정보를 조회한다. + * + * @param csebaseUri - IN-CSE의 csebase(root) 리소스 uri. + * @param aeName - AE 이름 (예: ae-gaslock-001, LGU+ INCSE연동시 "ae-"로 시작하여야함) + * @param from - AE의 ID. + * @return 서버에 저장된 AE 정보 + * @throws OneM2MException + */ + public AE doRetrieveAE(String csebaseUri, String aeName, String from) throws OneM2MException { + + return retrieveAE(csebaseUri +"/"+ aeName, from); + + } + + /** + * AE정보를 조회한다. + * + * @param aeUri - 조회할 AE 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 AE 정보 + * @throws OneM2MException + */ + public AE doRetrieveAE(String aeUri, String from) throws OneM2MException { + + return retrieveAE(aeUri, from); + + } + + + /** + * AE의 POA를 수정한다. + * AE의 POA가 변경되었을 경우 호출해야 한다. + * + * @param aeUri - AE의 Uri. + * @param from - AE의 ID. + * @param poa - 수정될 POA + * @return 수정된 AE 정보 오브젝트 + */ + public AE doUpdateAEPoa(String aeUri, String from, String poa) throws OneM2MException { + + AE ae1 = new AE(); + ae1.addPointOfAccess(poa); + + this.update(aeUri, from, ae1); + + if (this.ae == null) { + return ae1; + } else { + if (this.ae.getPointOfAccess() != null) { + this.ae.getPointOfAccess().clear(); + } + this.ae.addPointOfAccess(poa); + + return this.ae; + } + + } + + /** + * Notification XML Convertor를 초기화 한다. + * + * @param contentType - 초기화될 Convertor의 contentType, CONTENT_TYPE.XML 또는 CONTENT_TPYE.JSON 입력. + * @param resType - 초기화될 Convertor의 ResourceType + */ + public void doInitializeConvertor(CONTENT_TYPE contentType, RESOURCE_TYPE resType) throws Exception { + + + if (contentType == CONTENT_TYPE.XML) { + XMLConvertor xmlCvt; + switch (resType) { + case NOTIFICATION: + xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + case ACCESS_CTRL_POLICY: + xmlCvt = ConvertorFactory.getXMLConvertor(AccessControlPolicy.class, AccessControlPolicy.SCHEMA_LOCATION); + break; + case AE: + xmlCvt = ConvertorFactory.getXMLConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + xmlCvt = ConvertorFactory.getXMLConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + xmlCvt = ConvertorFactory.getXMLConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + break; + default: + throw new OneM2MException(RESPONSE_STATUS.INVALID_ARGUMENTS, "Not supported resource type:"+resType.Name()); + } + } else if (contentType == CONTENT_TYPE.JSON){ + JSONConvertor jsonCvt; // NOPMD by inseu_000 on 16. 1. 19 오후 4:37 + switch (resType) { + case NOTIFICATION: + jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + case ACCESS_CTRL_POLICY: + jsonCvt = ConvertorFactory.getJSONConvertor(AccessControlPolicy.class, AccessControlPolicy.SCHEMA_LOCATION); + break; + case AE: + jsonCvt = ConvertorFactory.getJSONConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + jsonCvt = ConvertorFactory.getJSONConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + jsonCvt = ConvertorFactory.getJSONConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + break; + default: + throw new OneM2MException(RESPONSE_STATUS.INVALID_ARGUMENTS, "Not supported resource type:"+resType.Name()); + } + + } else { + throw new OneM2MException(RESPONSE_STATUS.INVALID_ARGUMENTS, "Not supported content type:"+contentType.Name()); + } + } + + /** + * Container를 생성한다. + * + * @param aeUri - AE의 Uri. + * @param from - AE의 ID. + * @param containerName - 생성될 container이름 + * @param acpIds - 접근권한을 지정한 AccessControlPolicy ID 리스트 + * @param cntr - 생성될 container 정보 + * @param acpIds + * @return 생성된 container정보 오브젝트 + */ + public Container doCreateContainer(String aeUri, String from, String containerName, List acpIds, Container cntr, + boolean retrieveBeforeCreate) throws Exception { + + // 이미 등록된 경우 Container정보 retrieve + if (retrieveBeforeCreate) { + try { + Container cntr1 = (Container)this.retrieveContainer(aeUri +"/"+containerName, from); + return cntr1; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + //Container cnt1 = new Container(); + //cnt1.addLabels(containerName); + + if (acpIds != null) { + Iterator it = acpIds.iterator(); + while (it.hasNext()) { + cntr.addAccessControlPolicyIDs(it.next()); + } + } + + return createContainer(aeUri, from, cntr, containerName); + + } + + /** + * Container를 생성한다. + * + * @param aeUri - AE의 Uri. + * @param from - AE의 ID. + * @param containerName - 생성될 container이름 + * @param acpIds - 접근권한을 지정한 AccessControlPolicy ID 리스트 + * @param acpIds + * @return 생성된 container정보 오브젝트 + */ + public Container doCreateContainer(String aeUri, String from, String containerName, List acpIds, + boolean retrieveBeforeCreate) throws Exception { + + // 이미 등록된 경우 Container정보 retrieve + if (retrieveBeforeCreate) { + try { + Container cntr = (Container)this.retrieveContainer(aeUri +"/"+containerName, from); + return cntr; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + Container cnt1 = new Container(); + cnt1.addLabels(containerName); + + if (acpIds != null) { + Iterator it = acpIds.iterator(); + while (it.hasNext()) { + cnt1.addAccessControlPolicyIDs(it.next()); + } + } + + return createContainer(aeUri, from, cnt1, containerName); + + } + + /** + * Container정보를 조회한다. + * + * @param containerUri - 조회할 Container 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 Container 정보 + * @throws OneM2MException + */ + public Container doRetrieveContainer(String containerUri, String from) throws OneM2MException { + + return retrieveContainer(containerUri, from); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param cntUri - Container의 Uri. + * @param containerName - container이름 + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param name - 생성될 contentInstance의 이름 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(String cntUri, String containerName, String from, String value, String ciName) throws Exception { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + ci.addLabels(containerName); + + return createContentInstance(cntUri, from, ci, ciName); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param container - 업데이트될 container정보, uri와 resourceName이 반드시 셋팅되어 있어야 함. + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param ciName - 생성될 contentInstance 이름. null로 설정할 경우 서버에서 자동 생성 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(Container container, String from, String value, String ciName) throws OneM2MException { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + ci.addLabels(container.getResourceName()); + + return createContentInstance(container.getUri(), from, ci, ciName); + + } + + /** + * Container의 content를 업데이트한다. + * Container하위에 contentInstance를 생성을 통해서 최종 상태값을 업데이트함. + * 최종 생성된 값은 [container uri]/la 를 통해서 조회(retrieve) 가능함 + * + * @param containerUri - 업데이트될 container의 uri + * @param from - AE의 ID. + * @param value - 문자열로 된 Container의 정보 값, 값의 형식은 container별로 정의해서 사용해야 함 + * @param ciName - 생성될 contentInstance 이름. null로 설정할 경우 서버에서 자동 생성 + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doCreateContentInstance(String containerUri, String from, String value, String ciName) throws OneM2MException { + + ContentInstance ci = new ContentInstance(); + ci.setContentInfo("text/plain:0"); + ci.setContent(value); + + return createContentInstance(containerUri, from, ci, ciName); + + } + + + /** + * ContentInstance 정보를 조회한다. + * + * @param ciUri - 조회할 contentInstance 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 ContentInstance 정보 + * @throws OneM2MException + */ + public ContentInstance doRetrieveContentInstance(String ciUri, String from) throws OneM2MException { + + return retrieveContentInstance(ciUri, from); + + } + + /** + * Container의 최종 정보(contentInstnace)를 조회한다. + * + * @param cntUri - 업데이트될 container의 uri + * @param from - AE의 ID. + * @return 생성된 contentInstance 정보 오브젝트 + */ + public ContentInstance doGetLatestContent(String cntUri, String from) throws OneM2MException { + return (ContentInstance)this.retrieveContentInstance(cntUri+"/"+Naming.LATEST_SN, from); + } + + // contentType: 1-resource, 2-modified attribute, 3-resourceId(uri) + + /** + * 리소스에 대한 구독을 신청한다. + * 지정한 리소스의 하위에 subscription리소스를 생성함 + * + * @param targetUri - 구독 신청할 리소스 uri + * @param from - AE의 ID. + * @param notificationUri - 컨테이너 리소스 수정, 하위 리소스 생성, 삭제에 대한 통지(notification)을 받을 URI, LGU+서버의 경우 통지를 받을 ae의 resourceID입력 + * @param notiContentType - 통지되는 정보의 종류 1:리소스 오브젝트, 2:수정된 속성을 포함한 리소스 오브젝트, 3:리소스 ID정보(이 경우 통지가 오면 해당 리소스 조회를 통해서 정보를 파악함) + * @param acpIds - 권한을 지정한 AccessControlPolicy + * @return 생성된 subscription 정보 오브젝트 + */ + public Subscription doCreateSubscription(String targetUri, String from, String subsName, String notificationUri, + int notiContentType, List acpIds, boolean retrieveBeforeCreate) throws Exception { + + // 이미 등록된 경우 Container정보 retrieve + if (retrieveBeforeCreate) { + try { + Subscription subs = (Subscription)this.retrieveSubscription(targetUri +"/"+subsName, from); + return subs; + } catch (OneM2MException e) { + if (e.getResponseStatusCode() != RESPONSE_STATUS.NOT_FOUND) { + throw e; + } + } + } + + Subscription subs = new Subscription(); + subs.addNotificationURI(notificationUri); + EventNotificationCriteria cri = new EventNotificationCriteria(); + cri.addNotificationEventType(NOTIFICATIONEVENT_TYPE.CREATE_OF_CHILD_RESOURCE.Value()); + + subs.setEventNotificationCriteria(cri); + subs.setNotificationContentType(notiContentType == 3 ? NOTIFICATIONCONTENT_TYPE.RESOURCE_ID.Value() : + NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); + + + if (acpIds != null) { + Iterator it = acpIds.iterator(); + while (it.hasNext()) { + subs.addAccessControlPolicyIDs(it.next()); + } + } + + return createSubscription(targetUri, from, subsName, subs); + + } + + /** + * Subscription 리소스를 조회한다. + * + * @param subsUri - 조회할 Subscription 리소스 URI(structured id). + * @param from - AE의 ID. + * @return 서버에 저장된 Subscription 정보 + * @throws OneM2MException + */ + public Subscription doRetrieveSubscription(String subsUri, String from) throws OneM2MException { + + return retrieveSubscription(subsUri, from); + + } + + /** + * NOT TESTED!!!! + * AE에 대한 구독을 신청한다. + * AE가 생성될 경우 notification을 받을 수 있도록 csebase하위에 subscription리소스를 생성함 + * + * @param deviceAppName - 구독 신청할 AE의 애플리케이션명, 해당 애플리케이션에 속한 AE의 생성 삭제에 대해서만 통지됨 + * @param from - AE의 ID. + * @param notificationUri - AE 생성 삭제에 대한 통지(notification)을 받을 URI, LGU+서버의 경우 통지를 받을 ae의 resourceID입력 + * @return 생성된 subscription 정보 오브젝트 + */ +// public Subscription doAESubscription(String deviceAppName, String from, String notificationUri) throws Exception { +// +// Subscription subs = new Subscription(); +// subs.addNotificationURI(notificationUri); +// EventNotificationCriteria cri = new EventNotificationCriteria(); +// cri.addNotificationEventType(NOTIFICATIONEVENT_TYPE.CREATE_OF_CHILD_RESOURCE.Value()); +// cri.addAttribute(new Attribute(Naming.RESOURCETYPE_SN, RESOURCE_TYPE.AE.Value())); +// cri.addAttribute(new Attribute(Naming.APPNAME_SN, deviceAppName)); +// +// subs.setEventNotificationCriteria(cri); +// subs.setNotificationContentType(NOTIFICATIONCONTENT_TYPE.ALL_ATRRIBUTES.Value()); +// +// return createSubscription(csebaseUri, from, subs); +// +// } + + + /** + * NOT TESTED!!!! + * AE에 정보를 검색한다. + * + * @param deviceAppName - 검색할 AE의 애플리케이션명, 해당 애플리케이션만 검색됨 + * @param createdSince - 생성시간조건, 지정된 시간 이후에 생성된 AE만 검색됨 + * @return 검색된 AE 목록 + */ +// public List doDiscoverDeviceAE(String deviceAppName, String createdSince) throws Exception { +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.DISCOVERY); +// request.setTo(this.csebaseUri); +// request.setFrom(ae.getResourceID()); +// request.setRequestId(Utils.createRequestId()); +// +// FilterCriteria fc = new FilterCriteria(); +// fc.setCreatedAfter(createdSince); +// fc.setFilterUsage(FILTER_USAGE.DISCOVERY.Value()); +// request.setFilterCriteria(fc); +// +// if (this.authController != null) this.authController.setAuthData(request); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); +// +// if (res.getResStatusCode() == RESPONSE_STATUS.OK) { +// +// UriListContent ulc = (UriListContent)convertToUriList(new String(res.getContent(), "UTF-8")); +// +// List aeList = new ArrayList(); +// List aeUriList = ulc.getUriList(); +// Iterator it = aeUriList.iterator(); +// +// while (it.hasNext()) { +// String uri = it.next(); +// AE ae = (AE)this.retrieveAE(uri, this.ae.getResourceID()); +// } +// +// return aeList; +// +// } else { +// log.debug("registration failed. {}", res.toString()); +// return null; +// } +// +// } + + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param method - 수신 메시지의 HTTP Method + * @param uri - 수신 메시지의 요청 URI + * @param headerMap - 수신 메시지의 HTTP 헤더맵 + * @param host - 수신 메시지의 호스트명 + * @param content - 수신 메시지의 Body 내용 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ +// public OneM2mResponse doProcessRequest(String method, String uri, HashMap headerMap, String host, byte[] content, +// NotiHandlerInterface notiHandler) throws Exception { +// +// OneM2mRequest reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); +// +// return doProcessRequest(reqMessage, notiHandler); +// } + + + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param reqMessage - 파싱된 OneM2M HTTP 요청 메시지 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ + public HttpBasicResponse doProcessRequest(HttpBasicRequest request, NotiHandlerInterface notiHandler) throws Exception { + + OneM2mRequest reqMessage = RequestCodec.decode(request.getMethod(), request.getUri(), request.getHeaders(), + request.getHost(), request.getContent()); + + OneM2mResponse resMessage = doProcessRequest(reqMessage, notiHandler); + + HttpBasicResponse response = ResponseCodec.encodeToBasic(resMessage, HttpVersion.HTTP_1_1); + + return response; + + } + + /** + * 수신한 OneM2m Http Request에서 Notification메시지를 추출하여 notiHandler로 전달한다. + * Notification 메시지만 처리한다. + * Notification에 의한 서비스 로직은 notiHandler에서 구현해야 함. + * + * @param reqMessage - 파싱된 OneM2M HTTP 요청 메시지 + * @param notiHandler - 수신한 notification 메시지를 처리할 클래스 + * @return 처리 결과 응답 메시지 + * @throws Exception + */ + public OneM2mResponse doProcessRequest(OneM2mRequest reqMessage, NotiHandlerInterface notiHandler) throws Exception { + + Notification noti = null; + try { + noti = convertToNotification(new String(reqMessage.getContent(), "UTF-8")); + } catch (Exception e) { + log.debug("Handled exception", e); + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Fail to convert to notification obejct:"+e.getMessage()); + } + + + if (noti.isVerificationRequest() != null && noti.isVerificationRequest()) { + return new OneM2mResponse(RESPONSE_STATUS.OK, reqMessage); + } + + NotificationEvent ne = noti.getNotificationEvent(); + if (ne == null) { + OneM2mResponse res = new OneM2mResponse(RESPONSE_STATUS.BAD_REQUEST, reqMessage); + res.setContent(new String("NotificationEvent should be provided!").getBytes()); // NOPMD by inseu_000 on 16. 1. 19 오후 4:35 + return res; + } + + OperationMonitor om = ne.getOperationMonitor(); + + Resource resource = null; + String resId = null; + + OPERATION op = OPERATION.CREATE; + if (om != null) { + op = OPERATION.get(om.getOperation()); + } + + Object rep = ne.getRepresentation().getResource(); + + try { + if (rep instanceof UriListContent) { + resId = ((UriListContent)rep).getUriList().get(0); + //OneM2mResponse response = this.retrieve(resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof String) { + resId = (String)rep; + //OneM2mResponse response = this.retrieve(this.cseId+"/"+resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof UriContent) { + resId = ((UriContent)rep).getUri(); + //OneM2mResponse response = this.retrieve(((UriContent)rep).getUri(), this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else if (rep instanceof Resource) { + resource = (Resource)rep; + } else if (rep instanceof XMLRoot) { + XMLRoot root = (XMLRoot)rep; + resId = (String)root.getObject(); + //OneM2mResponse response = this.retrieve(this.cseId+"/"+resId, this.ae.getResourceID()); + //resource = this.convertToResource(response); + } else { + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Unexpected representation:"+ (rep != null ? rep.getClass().getName() : "null")); + } + } catch (OneM2MException e) { + throw e; + } catch (Exception e) { + + log.debug("Handled exception", e); + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Unexpected representation:"+e.getMessage()); + + } + + RESPONSE_STATUS status = null; + if (resource == null && resId != null) { + status = notiHandler.handleCreateNoti(resId, noti); + } else { + + switch (op) { + case CREATE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case CONTENT_INST: + status = notiHandler.handleCreateNoti((ContentInstance)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleCreateNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleCreateNoti(resource, noti); + break; + } + break; + case UPDATE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case AE: + status = notiHandler.handleUpdateNoti((AE)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleUpdateNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleUpdateNoti(resource, noti); + break; + } + break; + case DELETE: + switch (RESOURCE_TYPE.get(resource.getResourceType())) { + case CONTENT_INST: + status = notiHandler.handleDeleteNoti((ContentInstance)resource, noti); + break; + case CONTAINER: + status = notiHandler.handleDeleteNoti((Container)resource, noti); + break; + default: + status = notiHandler.handleDeleteNoti(resource, noti); + break; + } + break; + case RETRIEVE: + break; + case NOTIFY: + break; + default: + break; + } + } + + return new OneM2mResponse(status, reqMessage); + } + + + + + + + + + + + + private Logger log = LoggerFactory.getLogger(AEController.class); + + private String cseAddr; + private CONTENT_TYPE contentType; + + private AE ae = null; + private String csebaseUri; + private String cseId; + + private AuthControllerInterface authController = null; + + + private Resource convertToResource(RESOURCE_TYPE resType, OneM2mResponse res) throws OneM2MException { + + try { + Resource resource = convertToResource(resType, new String(res.getContent(), "UTF-8")); + resource.setUri(res.getContentLocation()); + return resource; + } catch (Exception e) { + log.debug("Handled exception", e); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Error during content utf8 encoding:"+e.getMessage()); + } + + } + + private Resource convertToResource(OneM2mResponse res) throws OneM2MException { + + try { + String pc = new String(res.getContent(), "UTF-8"); + Resource resource = convertToResource(Utils.getResTypeWithContentString(pc, res.getContentType()), pc); + resource.setUri(res.getContentLocation()); + return resource; + } catch (Exception e) { + log.debug("Handled exception", e); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Error during content utf8 encoding:"+e.getMessage()); + } + + } + + private Resource convertToResource(RESOURCE_TYPE resType, String content) throws OneM2MException { + try { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = null; + switch (resType) { + case AE: + xmlCvt = ConvertorFactory.getXMLConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + xmlCvt = ConvertorFactory.getXMLConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + //xmlCvt = ConvertorFactory.getXMLConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + xmlCvt = ConvertorFactory.getXMLConvertorCI(); + break; + case SUBSCRIPTION: + xmlCvt = ConvertorFactory.getXMLConvertor(Subscription.class, Subscription.SCHEMA_LOCATION); + break; + case NOTIFICATION: + xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + case ACCESS_CTRL_POLICY: + xmlCvt = ConvertorFactory.getXMLConvertor(AccessControlPolicy.class, AccessControlPolicy.SCHEMA_LOCATION); + break; + case GROUP: + xmlCvt = ConvertorFactory.getXMLConvertor(Group.class, Group.SCHEMA_LOCATION); + break; + case AE_ANNC: + xmlCvt = ConvertorFactory.getXMLConvertor(AEAnnc.class, AEAnnc.SCHEMA_LOCATION); + break; + case CONTAINER_ANNC: + xmlCvt = ConvertorFactory.getXMLConvertor(ContainerAnnc.class, ContainerAnnc.SCHEMA_LOCATION); + break; + case CONTENT_INST_ANNC: + xmlCvt = ConvertorFactory.getXMLConvertor(ContentInstanceAnnc.class, ContentInstanceAnnc.SCHEMA_LOCATION); + break; + } + + if (xmlCvt == null) return null; + else + return (Resource)xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = null; + switch (resType) { + case AE: + jsonCvt = ConvertorFactory.getJSONConvertor(AE.class, AE.SCHEMA_LOCATION); + break; + case CONTAINER: + jsonCvt = ConvertorFactory.getJSONConvertor(Container.class, Container.SCHEMA_LOCATION); + break; + case CONTENT_INST: + jsonCvt = ConvertorFactory.getJSONConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION); + break; + case SUBSCRIPTION: + jsonCvt = ConvertorFactory.getJSONConvertor(Subscription.class, Subscription.SCHEMA_LOCATION); + break; + case NOTIFICATION: + jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, Notification.SCHEMA_LOCATION); + break; + } + + if (jsonCvt == null) return null; + else return (Resource)jsonCvt.unmarshal(content); + + } + + } catch (Exception e) { + log.debug("Handled exception", e); + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during contentToResource:"+ e.getMessage()); + } + } + + private AggregatedResponse convertToAggregatedResponse(String content) throws Exception { + if (contentType == CONTENT_TYPE.RES_XML) { + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(AggregatedResponse.class, AggregatedResponse.SCHEMA_LOCATION); + if (xmlCvt == null) { + return null; + } else { + return (AggregatedResponse) xmlCvt.unmarshal(content); + } + }else { + JSONConvertor jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, AggregatedResponse.SCHEMA_LOCATION); + if (jsonCvt == null) { + return null; + } else { + return (AggregatedResponse)jsonCvt.unmarshal(content); + } + } + } + + private Notification convertToNotification(String content) throws Exception { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(Notification.class, Notification.SCHEMA_LOCATION); + if (xmlCvt == null) return null; + else return (Notification) xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = ConvertorFactory.getJSONConvertor(Notification.class, Notification.SCHEMA_LOCATION); + if (jsonCvt == null) return null; + else return (Notification)jsonCvt.unmarshal(content); + + } + + } + + + private UriListContent convertToUriList(String content) throws Exception { + if (contentType == CONTENT_TYPE.RES_XML) { + + XMLConvertor xmlCvt = ConvertorFactory.getXMLConvertor(UriListContent.class, UriListContent.SCHEMA_LOCATION); + if (xmlCvt == null) return null; + else return (UriListContent) xmlCvt.unmarshal(content); + + } else { + + JSONConvertor jsonCvt = ConvertorFactory.getJSONConvertor(UriListContent.class, UriListContent.SCHEMA_LOCATION); + if (jsonCvt == null) return null; + else return (UriListContent)jsonCvt.unmarshal(content); + + } + + } + + public AE retrieveAE(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AE ae = (AE)convertToResource(RESOURCE_TYPE.AE, res); + if (ae.getUri() == null) { + ae.setUri(resUri); + } + return ae; + } + + public AEAnnc retrieveAEAnnc(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AEAnnc ae = (AEAnnc)convertToResource(RESOURCE_TYPE.AE_ANNC, res); + if (ae.getUri() == null) { + ae.setUri(resUri); + } + return ae; + } + + private AE updateAE(String resUri, AE ae, String from) throws OneM2MException { + + OneM2mResponse res = update(resUri, from, ae); + return (AE)convertToResource(RESOURCE_TYPE.AE, res); + + } + + public AccessControlPolicy retrieveACP(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AccessControlPolicy acp = (AccessControlPolicy)convertToResource(RESOURCE_TYPE.ACCESS_CTRL_POLICY, res); + if (acp.getUri() == null) { + acp.setUri(resUri); + } + return acp; + + } + + public Container retrieveContainer(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + Container container = (Container)convertToResource(RESOURCE_TYPE.CONTAINER, res); + if (container.getUri() == null) { + container.setUri(resUri); + } + return container; + } + + public ContainerAnnc retrieveContainerAnnc(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + ContainerAnnc containerA = (ContainerAnnc)convertToResource(RESOURCE_TYPE.CONTAINER_ANNC, res); + if (containerA.getUri() == null) { + containerA.setUri(resUri); + } + return containerA; + } + + public AggregatedResponse retrieveFanoutContainer(String resUri, String from) throws Exception, OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + AggregatedResponse agr = convertToAggregatedResponse(new String(res.getContent(), "UTF-8")); +// if (container.getUri() == null) { +// container.setUri(resUri); +// } + return agr; + } + + public Subscription retrieveSubscription(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + Subscription subs = (Subscription)convertToResource(RESOURCE_TYPE.SUBSCRIPTION, res); + if (subs.getUri() == null) { + subs.setUri(resUri); + } + return subs; + } + + public ContentInstance retrieveContentInstance(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + ContentInstance ci = (ContentInstance)convertToResource(RESOURCE_TYPE.CONTENT_INST, res); + if (ci.getUri() == null) { + ci.setUri(resUri); + } + return ci; + } + + public ContentInstanceAnnc retrieveContentInstanceAnnc(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + ContentInstanceAnnc ciA = (ContentInstanceAnnc)convertToResource(RESOURCE_TYPE.CONTENT_INST_ANNC, res); + if (ciA.getUri() == null) { + ciA.setUri(resUri); + } + return ciA; + } + + public Group retrieveGroup(String resUri, String from) throws OneM2MException { + + OneM2mResponse res = retrieve(resUri, from); + Group group = (Group)convertToResource(RESOURCE_TYPE.GROUP, res); + if (group.getUri() == null) { + group.setUri(resUri); + } + return group; + } + + +// private Resource retrieveResource(String resUri, String from) throws OneM2MException { +// +// OneM2mResponse res = retrieve(resUri, from); +// return convertToResource(res); +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.RETRIEVE); +// request.setTo(resUri); // "/casebase/SAE_1" +// request.setFrom(from); // "/SAE_1" +// request.setRequestId(OneM2mUtil.createRequestId()); +// request.setContentType(CONTENT_TYPE.RES_XML); +// request.setResultContent(RESULT_CONT.ATTRIBUTE); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); // "http://localhost:8080" +// +// if (res == null) { +// log.error("retrieveResource failed."); +// throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Faile to retrieveResource RES:null"); +// } +// +// if (res.getResStatusCode() == RESPONSE_STATUS.OK) { +// return convertToResource(RESOURCE_TYPE.AE, res); +// } else { +// log.error("retrieveResource failed. {}", res.toString()); +// throw new OneM2MException(res.getResStatusCode(), "Faile to retrieveResource RES:"+res.toString()); +// } +// +// } + + public OneM2mResponse update(String resUri, String from, Resource resource) throws OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.UPDATE); + request.setTo(resUri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(resource); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); // "http://localhost:8080" + + + if (res == null) { + log.error("update failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CHANGED) { + return res; + } else { + log.error("update failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to uprdate resource, response:"+res.toString()); + } + + } + + + private OneM2mResponse retrieve(String resUri, String from) throws OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.RETRIEVE); + request.setTo(resUri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); // "http://localhost:8080" + + + if (res == null) { + log.error("retrieve failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.OK) { + return res; + } else { + log.error("retrieve failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to retrieve RES:"+res.toString()); + } + + } + + public Subscription createSubscription(String targetUri, String from, String subsName, Subscription subs) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(targetUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.SUBSCRIPTION); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(subs); + if (subsName == null || subsName.length() == 0) { + subsName = "sub-"+ae.getResourceName().replace("-", "_"); // uplus 서버 제약사항 (resourcename에 '-' 사용 불가) + } + request.setName(subsName); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createSubscription failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Subscription subs1 = (Subscription)convertToResource(RESOURCE_TYPE.SUBSCRIPTION, res); + subs1.setUri(targetUri +"/"+ subs1.getResourceName()); + return subs1; + } /*else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + Subscription subs1 = this.retrieveSubscription(targetUri +"/"+subsName, from); + subs1.setUri(targetUri +"/"+ subs1.getResourceName()); + return subs1; + }*/ else { + log.error("createSubscription failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createSubscription RES:null"); + } + + } + + public AE createAE(String parentUri, String from, AE ae, String name) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.AE); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(ae); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createAE failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + AE ae1 = (AE)convertToResource(RESOURCE_TYPE.AE, res); + ae1.setUri(parentUri +"/" + ae1.getResourceName()); + return ae1; + } /*else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + // 이미 등록된 경우 AE정보 retrieve + AE ae1 = (AE)this.retrieveAE(parentUri +"/"+name, from); + ae1.setUri(parentUri +"/"+name); + + // poa가 변경된 경우 AE update + String curPoa = ae1.getPointOfAccess() != null && ae1.getPointOfAccess().size() > 0 ? ae1.getPointOfAccess().get(0) : null; + String newPoa = ae.getPointOfAccess() != null && ae.getPointOfAccess().size() > 0 ? ae.getPointOfAccess().get(0) : null; + if (curPoa != newPoa) { + AE aeU = new AE(); + aeU.setUri(parentUri +"/" + ae1.getResourceName()); + aeU.addPointOfAccess(newPoa); + this.updateAE(aeU.getUri(), aeU, from); + + if (ae1.getPointOfAccess() != null) { + ae1.getPointOfAccess().clear(); + } + ae1.addPointOfAccess(newPoa); + } + + return ae1; + } */else { + log.debug("createAE failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Fail to createAE RES:"+res.toString()); + } + } + + public AccessControlPolicy createACP(String parentUri, String from, AccessControlPolicy acp, String name) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.ACCESS_CTRL_POLICY); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(acp); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createAE failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + AccessControlPolicy acpRes = (AccessControlPolicy)convertToResource(RESOURCE_TYPE.ACCESS_CTRL_POLICY, res); + acpRes.setUri(parentUri +"/" + acpRes.getResourceName()); + return acpRes; + } else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + return null; + } else { + log.debug("createACP failed. {}", res.toString()); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Fail to createACP RES:"+res.toString()); + } + + } +// private AE retrieveAE(String resUri, String from) throws Exception { +// +// OneM2mRequest request = new OneM2mRequest(); +// request.setOperation(OPERATION.RETRIEVE); +// request.setTo(resUri); // "/casebase/SAE_1" +// request.setFrom(from); // "/SAE_1" +// request.setRequestId(OneM2mUtil.createRequestId()); +// request.setContentType(CONTENT_TYPE.RES_XML); +// request.setResultContent(RESULT_CONT.ATTRIBUTE); +// +// OneM2mResponse res = new HttpClient().processRequest(cseAddr, request); // "http://localhost:8080" +// +// if (res == null) { +// log.debug("retrieveAE failed."); +// return null; +// } +// +// if (res != null && res.getResStatusCode() == RESPONSE_STATUS.OK) { +// return (AE)convertToResource(RESOURCE_TYPE.AE, new String(res.getContent(), "UTF-8")); +// } else { +// log.debug("retrieveAE failed. {}", res.toString()); +// return null; +// } +// +// } + + public Container createContainer(String parentUri, String from, Container container, String name) throws OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.CONTAINER); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(container); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Container cntr = (Container)convertToResource(RESOURCE_TYPE.CONTAINER, res); + cntr.setUri(parentUri +"/" + cntr.getResourceName()); + return cntr; + } /*else if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CONFLICT || res.getResponseStatusCodeEnum() == RESPONSE_STATUS.ALREADY_EXISTS) { + // 이미 등록된 경우 AE정보 retrieve + Container cntr = (Container)this.retrieveContainer(parentUri +"/"+name, from); + cntr.setUri(parentUri +"/" + cntr.getResourceName()); + return cntr; + }*/ else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:"+res.toString()); + } + } + + public AggregatedResponse createFanoutContainer(String parentUri, String from, Container container, String name) throws Exception, OneM2MException { + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.CONTAINER); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(container); + if (name != null) { + request.setName(name); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + AggregatedResponse agr = convertToAggregatedResponse(new String(res.getContent(), "UTF-8")); + return agr; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:"+res.toString()); + } + } + + public ContentInstance createContentInstance(String parentUri, String from, ContentInstance ci, String ciName) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.CONTENT_INST); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(ci); + if (ciName != null) { + request.setName(ciName); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + ContentInstance ci1 = (ContentInstance)convertToResource(RESOURCE_TYPE.CONTENT_INST, res); + ci1.setUri(parentUri +"/"+ ci1.getResourceName()); + return ci1; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:null"+res.toString()); + } + + } + + public Group createGroup(String parentUri, String from, Group group, String groupName) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.GROUP); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(group); + if (groupName != null) { + request.setName(groupName); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Group g = (Group)convertToResource(RESOURCE_TYPE.GROUP, res); + g.setUri(parentUri +"/"+ g.getResourceName()); + return g; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:null"+res.toString()); + } + + } + + public Request createRequest(String parentUri, String from, Request reqVO, String reqVOName) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.CREATE); + request.setTo(parentUri); + request.setFrom(from); + request.setRequestIdentifier(Utils.createRequestId()); + request.setResourceType(RESOURCE_TYPE.REQUEST); + request.setContentType(CONTENT_TYPE.RES_XML); + request.setResultContent(RESULT_CONT.ATTRIBUTE); + request.setContentObject(reqVO); + if (reqVOName != null) { + request.setName(reqVOName); + } + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("createContainer failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.CREATED) { + Request req = (Request)convertToResource(RESOURCE_TYPE.REQUEST, res); + req.setUri(parentUri +"/"+ req.getResourceName()); + return req; + } else { + log.error("createContainer failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to createContainer RES:null"+res.toString()); + } + + } + + public OneM2mResponse deleteResource(String uri, String from) throws OneM2MException { + + OneM2mRequest request = new OneM2mRequest(); + request.setOperation(OPERATION.DELETE); + request.setTo(uri); // "/casebase/SAE_1" + request.setFrom(from); // "/SAE_1" + request.setRequestIdentifier(Utils.createRequestId()); + + if (this.authController != null) this.authController.setAuthData(request); + + OneM2mResponse res = new HttpClient().process(cseAddr, request); + + if (res == null) { + log.error("deleteResource failed."); + throw new OneM2MException(RESPONSE_STATUS.NETWORK_FAILURE, "network failure"); + } + + if (res.getResponseStatusCodeEnum() == RESPONSE_STATUS.DELETED) { + log.debug(res.getResponseStatusCodeEnum().toString()); + log.debug(res.toString()); + return res; + } else { + log.error("deleteResource failed."); + throw new OneM2MException(res.getResponseStatusCodeEnum(), "Faile to deleteResource RES:"+res.toString()); + } + + } +// public Resource parseContentResource(AbsMessage message, ManagerInterface manager) throws OneM2MException { +// +// try { +// Resource res; +// String str = new String(message.getContent(), "UTF-8"); +// XMLConvertor xmlCvt; +// JSONConvertor jsonCvt; +// switch (message.getContentType()) { +// case RES_XML: +// xmlCvt = manager.getXMLConveter(); +// res = (Resource)xmlCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// case RES_JSON: +// jsonCvt = manager.getJSONConveter(); +// res = (Resource)jsonCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// case XML: // cannot sure if content is resource or not, so just return null in case exception +// try { +// xmlCvt = manager.getXMLConveter(); +// res = (Resource)xmlCvt.unmarshal(str); +// System.out.println("resourceName: " + res.getResourceName()); +// return res; +// } catch(Exception e) { +// log.debug("Handled exception", e); +// return null; +// } +// case JSON: // cannot sure if content is resource or not, so just return null in case exception +// try { +// jsonCvt = manager.getJSONConveter(); +// res = (Resource)jsonCvt.unmarshal(str); +// log.debug("resourceName: " + res.getResourceName()); +// return res; +// } catch(Exception e) { +// log.debug("Handled exception", e); +// return null; +// } +// +// default: +// return null; +// } +// } catch (Exception e) { +// log.debug("Handled exception", e); +// +// throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); +// } +// +// } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/AuthControllerInterface.java b/src/main/java/net/herit/iot/onem2m/ae/lib/AuthControllerInterface.java new file mode 100644 index 0000000..f3c70f4 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/AuthControllerInterface.java @@ -0,0 +1,43 @@ +package net.herit.iot.onem2m.ae.lib; + +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.onem2m.core.util.OneM2MException; + +/** + * 인증 컨트롤러 클래스 인터페이스 + * + * @version : 1.0 + * @author : Lee inseuk + */ +public interface AuthControllerInterface { + + /** + * 인증을 수행한다. 인증 수행 방법 및 절차는 각 구현에 따른다. + * + */ + public void doAuth() throws OneM2MException; + + /** + * 인증 성공여부를 반환환다. + * 인증을 수행하지 않고 미리 제공된 인증 정보가 있을 경우에도 true를 반환한다. + * @return 인증 성공 여부 + * + */ + public boolean isAuthorized() throws OneM2MException; + + /** + * OneM2MRequest에 인증정보를 셋팅한다. + * + * @param request - CSE로 전송될 REQUEST 정보 오브젝트 + */ + public void setAuthData(OneM2mRequest request) throws OneM2MException; + + + /** + * 인증 과정을 통해서 인증서버로(MES)부터 획득한 Entity ID(AE ID)를 반환한다. + * + * @return Entity ID(AE ID) + */ + public String getEntityId() throws OneM2MException; + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicRequest.java b/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicRequest.java new file mode 100644 index 0000000..7716ec9 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicRequest.java @@ -0,0 +1,84 @@ +package net.herit.iot.onem2m.ae.lib; + +import java.util.HashMap; + +public class HttpBasicRequest { + + private String method; + private String uri; + private String host; + private byte[] content; + private HashMap headers; + + public HttpBasicRequest(String method, String uri, String host, byte[] content2) { + this.method = method; + this.uri = uri; + this.host = host; + this.content = content2; + } + + //reqMessage = RequestCodec.decode(method, uri, headerMap, host, content); + /** + * @return the method + */ + public String getMethod() { + return method; + } + /** + * @param method the method to set + */ + public void setMethod(String method) { + this.method = method; + } + /** + * @return the uri + */ + public String getUri() { + return uri; + } + /** + * @param uri the uri to set + */ + public void setUri(String uri) { + this.uri = uri; + } + /** + * @return the host + */ + public String getHost() { + return host; + } + /** + * @param host the host to set + */ + public void setHost(String host) { + this.host = host; + } + /** + * @return the content + */ + public byte[] getContent() { + return content; + } + /** + * @param content the content to set + */ + public void setContent(byte[] content) { + this.content = content; + } + /** + * @return the headers + */ + public HashMap getHeaders() { + return headers; + } + /** + * @param headers the headers to set + */ + public void addHeader(String key, String value) { + if (this.headers == null) { + this.headers = new HashMap(); + } + this.headers.put(key, value); + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicResponse.java b/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicResponse.java new file mode 100644 index 0000000..4672c27 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/HttpBasicResponse.java @@ -0,0 +1,107 @@ +package net.herit.iot.onem2m.ae.lib; + +import java.util.HashMap; + +public class HttpBasicResponse { + + private String version; + private String statusCode; + private String statusMessage; + private byte content[]; + private HashMap headers; + + public HttpBasicResponse(String version, String statusCode, String statusMessage, byte[] content) { + this.version = version; + this.statusCode = statusCode; + this.statusMessage = statusMessage; + this.content = content; + } + + /** + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * @param version the version to set + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * @return the statusCode + */ + public String getStatusCode() { + return statusCode; + } + + /** + * @param statusCode the statusCode to set + */ + public void setStatusCode(String statusCode) { + this.statusCode = statusCode; + } + + /** + * @return the statusMessage + */ + public String getStatusMessage() { + return statusMessage; + } + + /** + * @param statusMessage the statusMessage to set + */ + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + /** + * @return the content + */ + public byte[] getContent() { + return content; + } + + /** + * @param content the content to set + */ + public void setContent(byte[] content) { + this.content = content; + } + + /** + * @param headers the headers to set + */ + public void setHeaders(HashMap headers) { + this.headers = headers; + } + + /** + * @return the headers + */ + public HashMap getHeaders() { + return headers; + } + /** + * @param headers the headers to set + */ + public void addHeader(String key, String value) { + if (this.headers == null) { + this.headers = new HashMap(); + } + this.headers.put(key, value); + } + /** + * @param headers the headers to set + */ + public void addHeader(String key, int value) { + if (this.headers == null) { + this.headers = new HashMap(); + } + this.headers.put(key, Integer.toString(value)); + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/LGUAuthController.java b/src/main/java/net/herit/iot/onem2m/ae/lib/LGUAuthController.java new file mode 100644 index 0000000..001f4b5 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/LGUAuthController.java @@ -0,0 +1,332 @@ +package net.herit.iot.onem2m.ae.lib; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpVersion; +import net.herit.iot.message.onem2m.OneM2mRequest; +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.onem2m.ae.lib.dto.AuthReqDTO; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData; +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData.Http; +import net.herit.iot.onem2m.ae.lib.dto.ServerAuthReqDTO; +import net.herit.iot.onem2m.bind.http.client.HttpClientBasic; +import net.herit.iot.onem2m.core.util.LogManager; +import net.herit.iot.onem2m.core.util.OneM2MException; + +/** + * LGU+ OneM2M MES서버 연동 기능을 구현한 클래스 + * + * @version : 1.0 + * @author : Lee inseuk + */ +public class LGUAuthController implements AuthControllerInterface { + + private LogManager logManager = LogManager.getInstacne(); + private Logger log = LoggerFactory.getLogger(LGUAuthController.class); + + private String deviceModel; + private String serviceCode; + private String m2mmType; + private String deviceSerialNo; + private String mac; + private String ctn; + private String deviceType; + private String iccId; + + private String mefAddr; + private int keySize = 128; + + private String mSvcServerCdSeq; + private String mSvcCdSeq; + private String mSvcCdNum; + + private LGUAuthData authData; + + private final String AUTH_HEADER_EKI = "X-MEF-EKI"; + private final String AUTH_HEADER_TK = "X-MEF-TK"; + private final String AUTH_HEADER_DM = "X-LGU-DM"; + private final String AUTH_HEADER_NI = "X-LGU-NI"; + + public LGUAuthController(String mefAddr, String svcServerCdSeq, String svcCdSeq, String svcCdNum) { + this.mefAddr = mefAddr; + mSvcServerCdSeq = svcServerCdSeq; + mSvcCdSeq = svcCdSeq; + mSvcCdNum = svcCdNum; + } + + /** + * LGU+ 인증서버 연동을 위한 컨트롤러 생성자. 입력값은 미리 제공받아야 한다. + * + * @param mefAddr - 인증서버 주소 (예: http://106.103.234.198/mef) + * @param deviceModel - 디바이스 모델 명 + * @param serviceCode - 서비스 코드 + * @param m2mmType - AE의 타입 (예: LTE-DEVICE) + * @param deviceSn - 디바이스 시리얼 번호 + * @param ctn - 디바이스 CTN, 디바이스가 아니거나 CTN이 없는 디바이스일 경우 null 입력 + * @param deviceType - 디바이스 타입 (AE의 경우 "AE"를 입력해야 함) + */ + public LGUAuthController(String mefAddr, String deviceModel, String serviceCode, String m2mmType, + String deviceSn, String mac, String ctn, String deviceType, String iccId) { + try { + + this.mefAddr = mefAddr; + this.deviceModel = deviceModel; + this.serviceCode = serviceCode; + this.m2mmType = m2mmType; + this.deviceSerialNo = deviceSn; + this.mac = mac; + this.ctn = ctn; + this.deviceType = deviceType; + this.iccId = iccId; + + this.authData = null; + + } catch (Exception e) { + + e.printStackTrace(); + } + } + + /** + * MEF 인증을 사용하지 않는 경우의 생성자 + */ + public LGUAuthController() { + this.authData = new LGUAuthData(); + authData.setHttp(new Http()); + } + + /** + * LGU+ 미리 공유된 인증정보를 셋팅한다. + * 미리 공유된 인증정보가 셋팅되면 인증서버를 통한 인증을 수행하지 않고 주어진 인증정보를 활용하여 oneM2M 서버와 통신을 수행한다. + * + * @param authData - 인증 정보, 상세정보는 LGUAuthData 클래스 참조 + */ + public void setPreSharedAuthData(LGUAuthData authData) throws OneM2MException { + + this.authData = authData; + + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public void setAuthData(OneM2mRequest request) throws OneM2MException { + + request.addUserDefinedHeaders(AUTH_HEADER_EKI, this.authData.getKeId()); + request.addUserDefinedHeaders(AUTH_HEADER_TK, this.authData.getHttp().getToken()); + //request.addUserDefinedHeaders(AUTH_HEADER_DM, this.authData.getDeviceModel()); + //request.addUserDefinedHeaders(AUTH_HEADER_NI, this.authData.getNetworkInfo()); + + } + + public LGUAuthData getAuthData() { + return this.authData; + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public boolean isAuthorized() { + return this.authData != null; + } + + @Override + /** + * 라이브러리 내부에서 사용함 + * + */ + public String getEntityId() { + try { + return this.authData.getHttp().getEntityId().length() > 0 ? this.authData.getHttp().getEntityId() : null; + } catch (NullPointerException e) { + return null; + } + } + + @Override + /** + * 디바이스 인증 or 서비스 서버 인증 + * + */ + public void doAuth() throws OneM2MException { + try { + LGUAuthData authData = requestAccessPermission(); + + //log.debug(authData.toString()); + + SecretKey skey = decodeBase64ToAESKey(authData.getHttp().getEnrmtKey()); + String keId = encryptKey(skey, getShortUuid(authData.getHttp().getEntityId())); + log.debug("keId: " + keId); + + if (keId == null) throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Fail to create KeId"); + + authData.setKeId(keId); + this.authData = authData; + + } catch (InvalidKeyException | IllegalBlockSizeException + | BadPaddingException | NoSuchAlgorithmException | IllegalArgumentException e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Fail to authrization"); + } + } + + private String getShortUuid(String entity_id) { + String [] data = entity_id.split("-"); + return data[2]; + } + + public SecretKey decodeBase64ToAESKey(String encodedKey ) throws IllegalArgumentException, NoSuchAlgorithmException { + try { + byte[] keyData = Base64.decodeBase64(encodedKey); + int keysize = keyData.length * Byte.SIZE; + + switch ( keysize ) { + case 128: + case 192: + case 256: + break; + default: + throw new IllegalArgumentException(); + } + + if ( Cipher.getMaxAllowedKeyLength( "AES" ) < keysize ) { + throw new IllegalArgumentException(); + } + + SecretKeySpec aesKey = new SecretKeySpec( keyData, "AES" ); + return aesKey; + } catch ( NoSuchAlgorithmException e ) { + throw new NoSuchAlgorithmException(); + } + } + + private String encryptKey(SecretKey secureKey, String shortUuid) throws InvalidKeyException, + IllegalBlockSizeException, + BadPaddingException { + String encryptStr = null; + try { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, secureKey); + byte[] encryptedData = cipher.doFinal(shortUuid.getBytes()); + encryptStr = Base64.encodeBase64URLSafeString(encryptedData); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + + } + return encryptStr; + } + + + // KeID : xuSjIzEoisV2EWvArbgN36lgjuau-GV5fDL_J7vffLhu1XqxBYPxSrOHN5q1Q_Cd + // token : 7b39ed3bc721401ba0e69e4bada2c7e4 + // CSE ID : MN_CSE-D-48b5886a084c3942baa86d587d9ebf9f-0078 + private LGUAuthData requestAccessPermission() throws OneM2MException { + String body; + + if(mSvcServerCdSeq == null) { + AuthReqDTO authDTO = new AuthReqDTO(); + authDTO.setDeviceModel(this.deviceModel); + authDTO.setDeviceSerialNo(this.deviceSerialNo); + authDTO.setServiceCode(this.serviceCode); + authDTO.setDeviceType(this.deviceType); + authDTO.setCtn(this.ctn); + authDTO.setMac(this.mac); + authDTO.setIccId(this.iccId); + + XMLConv reqConvertor = new XMLConv(AuthReqDTO.class); + body = reqConvertor.marshal(authDTO); + } else { + ServerAuthReqDTO authDTO = new ServerAuthReqDTO(); + authDTO.setSvcServerCdSeq(mSvcServerCdSeq); + authDTO.setSvcCdSeq(mSvcCdSeq); + authDTO.setSvcCdNum(mSvcCdNum); + + XMLConv reqConvertor = new XMLConv(ServerAuthReqDTO.class); + body = reqConvertor.marshal(authDTO); + log.debug(body); + } + + HttpClientBasic httpClient = new HttpClientBasic(); + + DefaultFullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, + HttpMethod.POST, + mefAddr, + Unpooled.copiedBuffer(body.getBytes())); + httpRequest.headers().add("Content-Type", "application/xml"); + httpRequest.headers().add("Content-Length", body.length()); + httpRequest.headers().add("Host", "106.103.234.198"); + FullHttpResponse httpResponse = httpClient.process(mefAddr, httpRequest); + + try { + int code = httpResponse.getStatus().code(); + log.debug("status code: " + code); + + if ( code >=200 && code <300) { + if(httpResponse.content().isReadable()) { + String xml = new String(httpResponse.content().copy().array(), "UTF-8"); + + + XMLConv XC2 = new XMLConv(LGUAuthData.class); + LGUAuthData auth = (LGUAuthData)XC2.unmarshal(xml); + return auth; + } + } else { + switch (code) { + case 400: + throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, RESPONSE_STATUS.BAD_REQUEST.Name()); + case 401: + throw new OneM2MException(RESPONSE_STATUS.UNAUTHORIZED, RESPONSE_STATUS.UNAUTHORIZED.Name()); + case 403: + throw new OneM2MException(RESPONSE_STATUS.ACCESS_DENIED, RESPONSE_STATUS.ACCESS_DENIED.Name()); + case 404: + throw new OneM2MException(RESPONSE_STATUS.NOT_FOUND, RESPONSE_STATUS.NOT_FOUND.Name()); + case 409: + throw new OneM2MException(RESPONSE_STATUS.GROUP_REQ_ID_EXISTS, RESPONSE_STATUS.GROUP_REQ_ID_EXISTS.Name()); + case 500: + throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, RESPONSE_STATUS.INTERNAL_SERVER_ERROR.Name()); + case 501: + throw new OneM2MException(RESPONSE_STATUS.NOT_IMPLEMENTED, RESPONSE_STATUS.NOT_IMPLEMENTED.Name()); + } + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Fail to encode response, "+e.getMessage()); + } catch (OneM2MException e) { + log.debug("OneM2MException code: "); + throw new OneM2MException(e.getResponseStatusCode(), e.getResponseStatusCode().Name()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new OneM2MException(RESPONSE_STATUS.UNDEFINED, "Exception in xml parsing, "+e.getMessage()); + } + + return null; + + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/NotiHandlerInterface.java b/src/main/java/net/herit/iot/onem2m/ae/lib/NotiHandlerInterface.java new file mode 100644 index 0000000..a941f39 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/NotiHandlerInterface.java @@ -0,0 +1,136 @@ +package net.herit.iot.onem2m.ae.lib; + +import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; +import net.herit.iot.onem2m.core.util.OneM2MException; +import net.herit.iot.onem2m.resource.AE; +import net.herit.iot.onem2m.resource.Container; +import net.herit.iot.onem2m.resource.ContentInstance; +import net.herit.iot.onem2m.resource.Notification; +import net.herit.iot.onem2m.resource.Resource; + +/** + * Notification 처리 클래스 인터페이스 + * + * @version : 1.0 + * @author : Lee inseuk + */ +public interface NotiHandlerInterface { + + /** + * ContentInstance 리소스 생성 Notification을 처리한다. + * Container에 subscription을 생성하면 contentInstance가 생성되었을때 이 함수가 호출된다. + * @param ci - 생성된 리소스 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleCreateNoti(ContentInstance ci, Notification notification) throws OneM2MException; + + /** + * Container 리소스 생성 Notification을 처리한다. + * AE에 subscription을 생성하면 container가 생성되었을때 이 함수가 호출된다. + * @param container - 생성된 리소스 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleCreateNoti(Container container, Notification notification) throws OneM2MException; + + + /** + * 리소스 생성 Notification을 처리한다. + * AE에 subscription을 생성하면 container가 생성되었을때 이 함수가 호출된다. + * @param resource - 생성된 리소스 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleCreateNoti(Resource resource, Notification notification) throws OneM2MException; + + + /** + * 리소스 생성 Notification을 처리한다. + * Noti를 통해서 전달되는 데이터가 Resource가 아니고 resourceId인 경우 이 함수가 호출된다. + * @param resId - 생성된 리소스 ID + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleCreateNoti(String resId, Notification noti) throws OneM2MException; + + /** + * !!!! NOT TESTED + * AE 변경 Notification을 처리한다. + * AE에 subscription을 생성하면 AE의 정보가 변경되었을 때 이 함수가 호출된다. + * @param ae - 수정된 AE 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleUpdateNoti(AE ae, Notification notification) throws OneM2MException; + + + /** + * !!!! NOT TESTED + * Container 변경 Notification을 처리한다. + * Container에 subscription을 생성하면 Container의 정보가 변경되었을 때 이 함수가 호출된다. + * @param container - 수정된 컨테이너 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleUpdateNoti(Container container, Notification notification) throws OneM2MException; + + + /** + * !!!! NOT TESTED + * 리소스 변경 Notification을 처리한다. + * @param resource - 수정된 리소스 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleUpdateNoti(Resource resource, Notification notification) throws OneM2MException; + + /** + * !!!! NOT TESTED + * Container 삭제 Notification을 처리한다. + * AE에 subscription을 생성하면 하위 Container가 삭제되었을때 이 함수가 호출된다. + * @param container - 삭제된 컨테이너 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleDeleteNoti(Container container, Notification notification) throws OneM2MException; + + /** + * !!!! NOT TESTED + * ContentInstance 삭제 Notification을 처리한다. + * Container에 subscription을 생성하면 하위 CnotentInstance가 삭제되었을때 이 함수가 호출된다. + * @param ci - 삭제된 ContentInstance 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleDeleteNoti(ContentInstance ci, Notification notification) throws OneM2MException; + + /** + * !!!! NOT TESTED + * 리소스 삭제 Notification을 처리한다. + * @param resource - 삭제된 리소스 정보 + * @param notification - Notification 메시지 정보 + * @return 처리 결과 상태 코드, 지정된 상태 코드로 Notification 메시지에 대한 응답을 보낸다. + * @throws OneM2MException + * + */ + public RESPONSE_STATUS handleDeleteNoti(Resource resource, Notification notification) throws OneM2MException; +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/XMLConv.java b/src/main/java/net/herit/iot/onem2m/ae/lib/XMLConv.java new file mode 100644 index 0000000..25d710e --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/XMLConv.java @@ -0,0 +1,115 @@ +package net.herit.iot.onem2m.ae.lib; + +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.xml.sax.InputSource; + +import net.herit.iot.onem2m.ae.lib.dto.LGUAuthData; + +public class XMLConv { + + private final Class t; + private JAXBContext context; + private Unmarshaller um; + private Marshaller m; + +// private final static String XML_HEADER = "\n"; + + public XMLConv(Class type) { + this.t = type; + + try { + context = JAXBContext.newInstance(t); + if(context == null) { + throw new Exception("JAXBContext newInstance failed"); + } + um = context.createUnmarshaller(); + + m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + } catch (Exception e) { + System.out.println(e); + } + + } + + @SuppressWarnings("unchecked") + public T unmarshal(String xml) throws Exception { + + InputSource ins = new InputSource(new StringReader(xml)); + + T obj = null; + + if(um == null) System.out.println("um is null"); + + obj = (T)um.unmarshal(ins); + + return obj; + } + + public String marshal(T obj) { + + String xml = null; + Writer writer = new StringWriter(); + + if(m == null) System.out.println("m is null"); + + try { + m.marshal(obj, writer); + xml = writer.toString(); + } catch (JAXBException e) { + e.printStackTrace(); + } + + return xml; + } + + public static void main(String[] args) { + + String xml = "\n" + + "\n" + + " \n" + + " entityId\n" + + " key\n" + + " abcd-efa-teafdvadasdf\n" + + " \n" + + " \n" + + " entityId\n" + + " key\n" + + " abcd-efa-teafdvadasdf\n" + + " tls_psk_aes_128_ccm_8\n" + + " \n" + + " \n" + + " entityId\n" + + " key\n" + + " abcd-efa-teafdvadasdf\n" + + " http://xxx.xxx.xxx./mef/cert/xxxxxxxx\n" + + " \n" + + ""; + + + try { + //----------------------------------------------------------------------------------------- + + XMLConv XC2 = new XMLConv(LGUAuthData.class); + LGUAuthData resource = (LGUAuthData)XC2.unmarshal(xml); + + System.out.println(resource); + + + + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/dto/AuthReqDTO.java b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/AuthReqDTO.java new file mode 100644 index 0000000..81cba4a --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/AuthReqDTO.java @@ -0,0 +1,86 @@ +package net.herit.iot.onem2m.ae.lib.dto; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * LGU+ OneM2M MEF 연동을 위한 인증 요청 정보 클래스 + * @author eastflag + * + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "auth") +public class AuthReqDTO { + @XmlElement(name = "deviceModel") + private String deviceModel; + + @XmlElement(name = "deviceSerialNo") + private String deviceSerialNo; + + @XmlElement(name = "serviceCode") + private String serviceCode; + + @XmlElement(name = "deviceType") + private String deviceType; + + @XmlElement(name = "ctn") + private String ctn; + + @XmlElement(name = "mac") + private String mac; + + @XmlElement(name = "iccId") + private String iccId; + + public String getDeviceModel() { + return deviceModel; + } + public void setDeviceModel(String deviceModel) { + this.deviceModel = deviceModel; + } + + public String getDeviceSerialNo() { + return deviceSerialNo; + } + public void setDeviceSerialNo(String deviceSerialNo) { + this.deviceSerialNo = deviceSerialNo; + } + + public String getServiceCode() { + return serviceCode; + } + public void setServiceCode(String serviceCode) { + this.serviceCode = serviceCode; + } + + public String getDeviceType() { + return deviceType; + } + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getCtn() { + return ctn; + } + public void setCtn(String ctn) { + this.ctn = ctn; + } + + public String getMac() { + return mac; + } + public void setMac(String mac) { + this.mac = mac; + } + + public String getIccId() { + return iccId; + } + public void setIccId(String iccId) { + this.iccId = iccId; + } +} diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/dto/LGUAuthData.java b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/LGUAuthData.java new file mode 100644 index 0000000..069d2d1 --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/LGUAuthData.java @@ -0,0 +1,223 @@ +package net.herit.iot.onem2m.ae.lib.dto; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * LGU+ OneM2M MES서버 연동을 위한 인증정보 클래스 + * 수신 메시지에 포함된 XML과 매핑됨 + * + * @version : 1.0 + * @author : Lee inseuk + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "authdata") +public class LGUAuthData { + private static final String NL = "\r\n"; + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlRootElement(name = "http") + public static class Http { + @XmlElement(name = "entityId") + private String entityId; + + @XmlElement(name = "enrmtKey") + private String enrmtKey; + + @XmlElement(name = "token") + private String token; + + public String toString() { + StringBuilder sbd = new StringBuilder(); + sbd.append("http] entityId=").append(entityId).append(NL); + sbd.append("\tenrmtKey=").append(enrmtKey).append(NL); + sbd.append("\ttoken=").append(token).append(NL); + + return sbd.toString(); + } + + public String getEntityId() { + return entityId; + } + public void setEntityId(String entityId) { + this.entityId = entityId; + } + public String getEnrmtKey() { + return enrmtKey; + } + public void setEnrmtKey(String enrmtKey) { + this.enrmtKey = enrmtKey; + } + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + + } + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlRootElement(name = "coap") + public static class Coap { + @XmlElement(name = "entityId") + private String entityId; + + @XmlElement(name = "enrmtKey") + private String enrmtKey; + + @XmlElement(name = "token") + private String token; + + @XmlElement(name = "encryptionMethod") + private String encryptionMethod; + + public String toString() { + StringBuilder sbd = new StringBuilder(); + sbd.append("coap] entityId=").append(entityId).append(NL); + sbd.append("\tenrmtKey=").append(enrmtKey).append(NL); + sbd.append("\ttoken=").append(token).append(NL); + sbd.append("\tencryptionMethod=").append(encryptionMethod).append(NL); + + return sbd.toString(); + } + + public String getEntityId() { + return entityId; + } + public void setEntityId(String entityId) { + this.entityId = entityId; + } + public String getEnrmtKey() { + return enrmtKey; + } + public void setEnrmtKey(String enrmtKey) { + this.enrmtKey = enrmtKey; + } + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + public String getEncryptionMethod() { + return encryptionMethod; + } + public void setEncryptionMethod(String encryptionMethod) { + this.encryptionMethod = encryptionMethod; + } + + } + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlRootElement(name = "mqtt") + public static class Mqtt { + @XmlElement(name = "entityId") + private String entityId; + + @XmlElement(name = "enrmtKey") + private String enrmtKey; + + @XmlElement(name = "token") + private String token; + + @XmlElement(name = "certUrl") + private String certUrl; + + public String toString() { + StringBuilder sbd = new StringBuilder(); + sbd.append("mqtt] entityId=").append(entityId).append(NL); + sbd.append("\tenrmtKey=").append(enrmtKey).append(NL); + sbd.append("\ttoken=").append(token).append(NL); + sbd.append("\tcertUrl=").append(certUrl).append(NL); + + return sbd.toString(); + } + + public String getEntityId() { + return entityId; + } + public void setEntityId(String entityId) { + this.entityId = entityId; + } + public String getEnrmtKey() { + return enrmtKey; + } + public void setEnrmtKey(String enrmtKey) { + this.enrmtKey = enrmtKey; + } + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + public String getCertUrl() { + return certUrl; + } + public void setCertUrl(String certUrl) { + this.certUrl = certUrl; + } + } + + private Http http; + private Coap coap; + private Mqtt mqtt; + + private String keId; + + private String deviceModel; + private String networkInfo; + + public String toString() { + StringBuilder sbd = new StringBuilder(); + + sbd.append("AuthData] ").append(http).append(coap).append(mqtt); + sbd.append("\tkeId=").append(keId).append(NL); + sbd.append("\tdeviceModel=").append(deviceModel).append(NL); + sbd.append("\tnetworkInfo=").append(networkInfo).append(NL); + + return sbd.toString(); + } + + public Http getHttp() { + return http; + } + public void setHttp(Http http) { + this.http = http; + } + public Coap getCoap() { + return coap; + } + public void setCoap(Coap coap) { + this.coap = coap; + } + public Mqtt getMqtt() { + return mqtt; + } + public void setMqtt(Mqtt mqtt) { + this.mqtt = mqtt; + } + public String getDeviceModel() { + return deviceModel; + } + public void setDeviceModel(String deviceModel) { + this.deviceModel = deviceModel; + } + public String getNetworkInfo() { + return networkInfo; + } + public void setNetworkInfo(String networkInfo) { + this.networkInfo = networkInfo; + } + public String getKeId() { + return keId; + } + public void setKeId(String keId) { + this.keId = keId; + } + +} \ No newline at end of file diff --git a/src/main/java/net/herit/iot/onem2m/ae/lib/dto/ServerAuthReqDTO.java b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/ServerAuthReqDTO.java new file mode 100644 index 0000000..83cef8a --- /dev/null +++ b/src/main/java/net/herit/iot/onem2m/ae/lib/dto/ServerAuthReqDTO.java @@ -0,0 +1,45 @@ +package net.herit.iot.onem2m.ae.lib.dto; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "auth") +public class ServerAuthReqDTO { + + @XmlElement(name = "svcServerCdSeq") + private String svcServerCdSeq; + + @XmlElement(name = "svcCdSeq") + private String svcCdSeq; + + @XmlElement(name = "svcCdNum") + private String svcCdNum; + + public String getSvcServerCdSeq() { + return svcServerCdSeq; + } + + public void setSvcServerCdSeq(String svcServerCdSeq) { + this.svcServerCdSeq = svcServerCdSeq; + } + + public String getSvcCdSeq() { + return svcCdSeq; + } + + public void setSvcCdSeq(String svcCdSeq) { + this.svcCdSeq = svcCdSeq; + } + + public String getSvcCdNum() { + return svcCdNum; + } + + public void setSvcCdNum(String svcCdNum) { + this.svcCdNum = svcCdNum; + } + +} diff --git a/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClient.java b/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClient.java index 99fd314..74f5e25 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClient.java +++ b/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClient.java @@ -154,7 +154,7 @@ public boolean processAsyncRequest(String url, OneM2mRequest reqMessage, AsyncRe } } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception",e); } return res; @@ -180,8 +180,8 @@ public boolean processAsyncRequest(String url, OneM2mRequest reqMessage, AsyncRe //log.debug(channelFuture.cause().toString()); } } catch (Exception e) { - log.error("execption=", e); - e.printStackTrace(); + log.error("execption=", e); + log.debug("Handled exception",e); resMessage = null; } @@ -223,7 +223,7 @@ public void handleHttpResponse(ChannelHandlerContext ctx, FullHttpResponse respo try { resMessage = ResponseCodec.decode(response, ((InetSocketAddress)ctx.channel().remoteAddress()).getHostString()); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); resMessage = null; } } diff --git a/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClientBasic.java b/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClientBasic.java index 7d57dad..3720e9c 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClientBasic.java +++ b/src/main/java/net/herit/iot/onem2m/bind/http/client/HttpClientBasic.java @@ -131,8 +131,7 @@ public FullHttpResponse process(String url, DefaultFullHttpRequest request) { channel.closeFuture().sync(); } catch (Exception e) { - System.out.println("exception: " + e); - e.printStackTrace(); + log.debug("Handled exception", e); } finally { // Shut down executor threads to exit. group.shutdownGracefully(); diff --git a/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServer.java b/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServer.java index b636035..602a18f 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServer.java +++ b/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServer.java @@ -98,9 +98,8 @@ public void stop() { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); bindChannel.closeFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } catch (InterruptedException e) { + log.debug("Handled exception",e); } finally { } diff --git a/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServerHandler.java b/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServerHandler.java index 8d571f5..6401535 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServerHandler.java +++ b/src/main/java/net/herit/iot/onem2m/bind/http/server/HttpServerHandler.java @@ -315,7 +315,6 @@ public void operationComplete(ChannelFuture future) throws Exception { } } catch (Exception exception) { log.error("sendHTTPMessage_error=", exception); - exception.printStackTrace(); response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR); channel.writeAndFlush(response); diff --git a/src/main/java/net/herit/iot/onem2m/bind/http/util/Utils.java b/src/main/java/net/herit/iot/onem2m/bind/http/util/Utils.java index d821f20..c6c404f 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/http/util/Utils.java +++ b/src/main/java/net/herit/iot/onem2m/bind/http/util/Utils.java @@ -13,7 +13,7 @@ public static HashMap urlQueryParse(String url) { HashMap map = new HashMap(); - int indx = url.indexOf("?"); + int indx = url.indexOf('?'); if (indx == -1) { if (url.startsWith("http:")) url = url.substring(5); if (url.startsWith("https:")) url = url.substring(6); diff --git a/src/main/java/net/herit/iot/onem2m/bind/mqtt/MqttCseClient.java b/src/main/java/net/herit/iot/onem2m/bind/mqtt/MqttCseClient.java index a3c28b7..f009584 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/mqtt/MqttCseClient.java +++ b/src/main/java/net/herit/iot/onem2m/bind/mqtt/MqttCseClient.java @@ -1,5 +1,8 @@ package net.herit.iot.onem2m.bind.mqtt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.herit.iot.message.onem2m.OneM2mRequest; import net.herit.iot.message.onem2m.OneM2mResponse; import net.herit.iot.onem2m.bind.mqtt.api.MqttClientListener; @@ -9,6 +12,8 @@ public class MqttCseClient implements MqttClientListener { // String brokerURL = "tcp://10.211.55.8:1883"; String brokerURL = "tcp://iot.eclipse.org:1883"; String CES_ID = "herit-in"; + + private Logger log = LoggerFactory.getLogger(MqttCseClient.class); public static void main(String[] args) { // TODO Auto-generated method stub @@ -21,7 +26,7 @@ public void init() { MqttClientHandler.getInstance(CES_ID).connect(brokerURL); MqttClientHandler.getInstance().setListener(this); } catch(Exception e) { - e.printStackTrace(System.out); + log.debug("Handled exception", e); } } @@ -39,7 +44,7 @@ public void receiveMqttMessage(OneM2mRequest request) { try { MqttClientHandler.getInstance().sendResMessage(from, res); } catch(Exception e) { - e.printStackTrace(System.out); + log.debug("Handled exception", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/bind/mqtt/client/MqttClientHandler.java b/src/main/java/net/herit/iot/onem2m/bind/mqtt/client/MqttClientHandler.java index 2abc54c..413ae25 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/mqtt/client/MqttClientHandler.java +++ b/src/main/java/net/herit/iot/onem2m/bind/mqtt/client/MqttClientHandler.java @@ -139,7 +139,7 @@ public void messageArrived(String topic, MqttMessage message) throws Exception { } } catch (Exception e) { - e.printStackTrace(System.out); + log.debug("Handled exception", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/RequestCodec.java b/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/RequestCodec.java index 673d7c9..ef15f5c 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/RequestCodec.java +++ b/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/RequestCodec.java @@ -54,8 +54,7 @@ public static OneM2mRequest decode(byte[] contents) throws OneM2MException { // reqMessage = (OneM2mRequest)decodeJsonConvertor.unmarshal(strContents); // } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + //log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -104,8 +103,7 @@ public static byte[] encode(OneM2mRequest reqMessage) throws OneM2MException { } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + //log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } diff --git a/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/ResponseCodec.java b/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/ResponseCodec.java index d205d19..c5333ab 100644 --- a/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/ResponseCodec.java +++ b/src/main/java/net/herit/iot/onem2m/bind/mqtt/codec/ResponseCodec.java @@ -1,5 +1,8 @@ package net.herit.iot.onem2m.bind.mqtt.codec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.herit.iot.message.onem2m.OneM2mResponse; import net.herit.iot.message.onem2m.format.Enums.CONTENT_TYPE; import net.herit.iot.onem2m.bind.mqtt.util.Utils; @@ -17,6 +20,8 @@ public class ResponseCodec { new JSONConvertor(OneM2mResponse.class); private static final JSONConvertor encodeJsonConvertor = new JSONConvertor(ResponsePrimitive.class); + + private static Logger log = LoggerFactory.getLogger(ResponseCodec.class); public static OneM2mResponse decode(byte[] contents) throws OneM2MException { @@ -53,8 +58,7 @@ public static OneM2mResponse decode(byte[] contents) throws OneM2MException { // throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); // } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -106,8 +110,7 @@ public static byte[] encode(OneM2mResponse resMessage) throws OneM2MException { } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } diff --git a/src/main/java/net/herit/iot/onem2m/core/convertor/ConvertorFactory.java b/src/main/java/net/herit/iot/onem2m/core/convertor/ConvertorFactory.java index 028e110..4f34dc6 100644 --- a/src/main/java/net/herit/iot/onem2m/core/convertor/ConvertorFactory.java +++ b/src/main/java/net/herit/iot/onem2m/core/convertor/ConvertorFactory.java @@ -1,6 +1,8 @@ package net.herit.iot.onem2m.core.convertor; +import java.util.ArrayList; import java.util.HashMap; +import java.util.concurrent.atomic.AtomicInteger; import net.herit.iot.message.onem2m.OneM2mResponse.RESPONSE_STATUS; import net.herit.iot.onem2m.core.util.OneM2MException; @@ -11,6 +13,18 @@ public class ConvertorFactory { private static HashMap, JSONConvertor> jsonMap = new HashMap, JSONConvertor>(); private static HashMap, XMLConvertor> xmlMap = new HashMap, XMLConvertor>(); + + private static int maxCiCount = 10; + private static AtomicInteger curCiIndex; + private static ArrayList> xmlCiCvtArr = new ArrayList>(); + + public static void initialize(int maxCnt) throws OneM2MException { + curCiIndex.set(0); + maxCiCount = maxCnt; + for (int i = 0; i< maxCiCount; i++) { + xmlCiCvtArr.add((XMLConvertor)createXMLConvertor(ContentInstance.class, ContentInstance.SCHEMA_LOCATION)); + } + } public static JSONConvertor getJSONConvertor(Class t, String schema) throws OneM2MException { @@ -32,6 +46,12 @@ public static XMLConvertor getXMLConvertor(Class t, String schema) throws return cvt; } + public static XMLConvertor getXMLConvertorCI() throws OneM2MException { + + XMLConvertor cvt = xmlCiCvtArr.get(curCiIndex.addAndGet(1) % maxCiCount); + + return cvt; + } static JSONConvertor createJSONConvertor(Class t, String schema) throws OneM2MException { diff --git a/src/main/java/net/herit/iot/onem2m/core/convertor/JSONConvertor.java b/src/main/java/net/herit/iot/onem2m/core/convertor/JSONConvertor.java index 05b260e..2834738 100644 --- a/src/main/java/net/herit/iot/onem2m/core/convertor/JSONConvertor.java +++ b/src/main/java/net/herit/iot/onem2m/core/convertor/JSONConvertor.java @@ -18,6 +18,8 @@ import org.eclipse.persistence.jaxb.JAXBContextProperties; import org.eclipse.persistence.jaxb.UnmarshallerProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JSONConvertor { @@ -25,6 +27,7 @@ public class JSONConvertor { private JAXBContext context; private Unmarshaller um; private Marshaller m; + private Logger log = LoggerFactory.getLogger(JSONConvertor.class); public JSONConvertor(Class type, Class[] types) { this.t = type; @@ -62,7 +65,7 @@ public JSONConvertor(Class type) { initialize(); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/core/convertor/XMLConvertor.java b/src/main/java/net/herit/iot/onem2m/core/convertor/XMLConvertor.java index 1de7a2c..14b58a6 100644 --- a/src/main/java/net/herit/iot/onem2m/core/convertor/XMLConvertor.java +++ b/src/main/java/net/herit/iot/onem2m/core/convertor/XMLConvertor.java @@ -15,6 +15,8 @@ import org.eclipse.persistence.jaxb.MarshallerProperties; import org.eclipse.persistence.jaxb.UnmarshallerProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper; @@ -27,6 +29,8 @@ public class XMLConvertor { private Unmarshaller um; private Marshaller m; + private static Logger log = LoggerFactory.getLogger(XMLConvertor.class); + // private final static String XML_HEADER = "\n"; public XMLConvertor(Class type, String schema, Class[] types) { this.t = type; @@ -44,8 +48,7 @@ public XMLConvertor(Class type, String schema, Class[] types) { initialize(schema); } catch (Exception e) { - // TBD - e.printStackTrace(); + log.debug("Handled exception", e); } } @@ -62,8 +65,7 @@ public XMLConvertor(Class type, String schema) { initialize(schema); } catch (Exception e) { - // TBD - e.printStackTrace(); + log.debug("Handled exception", e); } } @@ -1421,7 +1423,7 @@ public static void main(String[] args) { System.out.println(Double.valueOf((Double)3.1415923332233335)); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/core/util/Utils.java b/src/main/java/net/herit/iot/onem2m/core/util/Utils.java index d5a2a44..a884a08 100644 --- a/src/main/java/net/herit/iot/onem2m/core/util/Utils.java +++ b/src/main/java/net/herit/iot/onem2m/core/util/Utils.java @@ -13,6 +13,8 @@ import org.joda.time.LocalDateTime; import org.joda.time.format.DateTimeFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; @@ -30,6 +32,8 @@ public class Utils { + private static Logger log = LoggerFactory.getLogger(Utils.class); + public static String createRequestId() { return "REQ_"+UUID.randomUUID().toString(); } @@ -165,7 +169,7 @@ public static RESOURCE_TYPE getResTypeWithContentString(String pc, } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); return RESOURCE_TYPE.NONE; } diff --git a/src/main/java/net/herit/iot/onem2m/incse/HttpHandler.java b/src/main/java/net/herit/iot/onem2m/incse/HttpHandler.java index abbda1c..a0917aa 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/HttpHandler.java +++ b/src/main/java/net/herit/iot/onem2m/incse/HttpHandler.java @@ -49,8 +49,7 @@ public HttpHandler() { try { } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); } } @@ -119,8 +118,8 @@ public void receiveHttpRequest(ChannelHandlerContext ctx, FullHttpRequest reques new OperationProcessor(context).processRequest(reqMessage); } catch (Throwable th) { - th.printStackTrace(); - log.error("RequestMessage decode failed.", th); + log.debug("RequestMessage decode failed", th); + if(reqMessage != null) { removeSession(reqMessage.getRequestIdentifier()); } @@ -146,8 +145,7 @@ public boolean sendHttpResponse(OneM2mResponse resMessage) { addListener(ChannelFutureListener.CLOSE). addListener(new FilnalEventListener(ctx, true)); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); sendError(ctx); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/InCse.java b/src/main/java/net/herit/iot/onem2m/incse/InCse.java index 0559131..088c022 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/InCse.java +++ b/src/main/java/net/herit/iot/onem2m/incse/InCse.java @@ -100,14 +100,13 @@ public InCse() { CSEBaseManager manager = (CSEBaseManager)ManagerFactory.create(RESOURCE_TYPE.CSE_BASE, createContext(BINDING_TYPE.BIND_NONE)); manager.createIfNotExist(); } catch (OneM2MException e) { - e.printStackTrace(); + log.debug("Handled exception", e); } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); } } @@ -191,13 +190,12 @@ public void receiveHttpRequest(ChannelHandlerContext ctx, FullHttpRequest reques new OperationProcessor(context).processRequest(reqMessage); } catch (OneM2MException e) { - e.printStackTrace(); + log.debug("Handled exception", e); OneM2mResponse resMessage = new OneM2mResponse(e.getResponseStatusCode(), reqMessage); resMessage.setContent(new String(e.getMessage()).getBytes()); sendHttpResponseMessage(resMessage, ctx); } catch (Throwable th) { - th.printStackTrace(); log.error("RequestMessage decode failed.", th); if(reqMessage != null) { removeSession(reqMessage.getRequestIdentifier()); @@ -231,8 +229,7 @@ private boolean sendHttpResponseMessage(OneM2mResponse resMessage, ChannelHandle addListener(ChannelFutureListener.CLOSE). addListener(new FilnalEventListener(ctx, true)); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); sendError(ctx); } @@ -286,13 +283,12 @@ public void receiveMqttMessage(OneM2mRequest reqMessage) { OneM2mContext context = createContext(BINDING_TYPE.BIND_MQTT); new OperationProcessor(context).processRequest(reqMessage); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); OneM2mResponse resMessage = new OneM2mResponse(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, reqMessage); resMessage.setContent("Internal server".getBytes()); sendMqttMessage(resMessage); } catch (Throwable th) { - th.printStackTrace(); log.error("RequestMessage decode failed.", th); } @@ -349,6 +345,7 @@ public void completedMqttDelivery(int messageID) { log.debug("MQTT BINDING] completed Mqtt delivery. messageID={}", messageID); } + /***************************************************************************** * END MQTT BINDING *****************************************************************************/ @@ -356,12 +353,6 @@ public void completedMqttDelivery(int messageID) { public static void main(String[] args) throws Exception { new InCse().start(); -// String host = "//127.0.0.1:8080"; -// URI uri = new URI(host); -// System.out.println(uri.toString()); -// System.out.println(uri.getHost()); - - } diff --git a/src/main/java/net/herit/iot/onem2m/incse/OperationProcessor.java b/src/main/java/net/herit/iot/onem2m/incse/OperationProcessor.java index 3484e03..1f6f291 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/OperationProcessor.java +++ b/src/main/java/net/herit/iot/onem2m/incse/OperationProcessor.java @@ -143,14 +143,14 @@ public void processRequest(OneM2mRequest reqMessage) { return; } } catch (OneM2MException e) { - e.printStackTrace(); + log.debug("Handled exception", e); OneM2mResponse resMessage = new OneM2mResponse(e.getResponseStatusCode(), reqMessage); resMessage.setContent(new String(e.getMessage()).getBytes()); context.getNseManager().sendResponseMessage(resMessage); return; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); OneM2mResponse resMessage = new OneM2mResponse(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, reqMessage); resMessage.setContent(new String(e.getMessage()).getBytes()); context.getNseManager().sendResponseMessage(resMessage); diff --git a/src/main/java/net/herit/iot/onem2m/incse/RestHandler.java b/src/main/java/net/herit/iot/onem2m/incse/RestHandler.java index 5f30d51..b3c0068 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/RestHandler.java +++ b/src/main/java/net/herit/iot/onem2m/incse/RestHandler.java @@ -104,7 +104,6 @@ public void receiveHttpRequest(ChannelHandlerContext ctx, FullHttpRequest reques new RestProcessor(context).processRequest(reqMessage); } catch (Throwable th) { - th.printStackTrace(); log.error("RequestMessage decode failed.", th); if(reqMessage != null) { removeSession(reqMessage.getRequestIdentifier()); @@ -129,8 +128,7 @@ public boolean sendResponseMessage(String requestId, String statusCode, String b addListener(ChannelFutureListener.CLOSE). addListener(new FilnalEventListener(ctx, true)); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); sendError(ctx); } @@ -195,8 +193,7 @@ public boolean sendHttpResponse(OneM2mResponse resMessage) { addListener(ChannelFutureListener.CLOSE). addListener(new FilnalEventListener(ctx, true)); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); sendError(ctx); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/RestProcessor.java b/src/main/java/net/herit/iot/onem2m/incse/RestProcessor.java index a712c03..5113776 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/RestProcessor.java +++ b/src/main/java/net/herit/iot/onem2m/incse/RestProcessor.java @@ -122,9 +122,7 @@ public void processRequest(OneM2mRequest reqMessage) { return; } catch (Exception e) { - e.printStackTrace(); - //OneM2mResponse resMessage = new OneM2mResponse(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, reqMessage); - //resMessage.setContent(new String(e.getMessage()).getBytes()); + log.debug("Handled exception", e); Document doc = new Document(); doc.put("code", RESPONSE_STATUS.INTERNAL_SERVER_ERROR.name()); diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/ForwardingController.java b/src/main/java/net/herit/iot/onem2m/incse/controller/ForwardingController.java index 0d48ff2..99a348d 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/ForwardingController.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/ForwardingController.java @@ -2,6 +2,9 @@ import java.net.MalformedURLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.herit.iot.message.onem2m.OneM2mRequest; import net.herit.iot.message.onem2m.OneM2mResponse; import net.herit.iot.onem2m.bind.http.client.AsyncResponseListener; @@ -11,6 +14,8 @@ public class ForwardingController extends AbsController implements AsyncResponseListener { + + private Logger log = LoggerFactory.getLogger(ForwardingController.class); public ForwardingController(OneM2mContext context) { super(context); @@ -29,7 +34,7 @@ public OneM2mResponse processRequest(OneM2mRequest reqMessage) { reqMessage.setTo(resPath); return getContext().getNseManager().sendRequestMessage(baseUrl, reqMessage); } catch (MalformedURLException e) { - e.printStackTrace(); + log.debug("Handled exception", e); return null; } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/InterworkingController.java b/src/main/java/net/herit/iot/onem2m/incse/controller/InterworkingController.java index a09d49c..c8d4567 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/InterworkingController.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/InterworkingController.java @@ -54,7 +54,7 @@ public void run() { Thread.sleep(delayStart); this.registerRemoteCSE(CfgManager.getInstance().getRemoteCSEList()); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); log.debug("Exception in InterworkingController.run:"+e.getMessage()); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/MgmtCmdController.java b/src/main/java/net/herit/iot/onem2m/incse/controller/MgmtCmdController.java index ecd8287..bb51538 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/MgmtCmdController.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/MgmtCmdController.java @@ -3,6 +3,9 @@ import java.util.Iterator; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.sun.corba.se.impl.util.Utility; import net.herit.iot.message.onem2m.OneM2mRequest; @@ -36,6 +39,8 @@ public class MgmtCmdController implements Runnable { private MgmtCmd mgmtCmd; private Node node; + private Logger log = LoggerFactory.getLogger(MgmtCmdController.class); + public MgmtCmdController(OneM2mContext context, MgmtCmd mgmtCmd, ExecInstance execInst, Node node) { this.context = context; @@ -81,9 +86,8 @@ public void run() { } catch (OneM2MException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - + log.debug("Handled exception", e); + execInst.setExecResult(EXEC_RESULT.INTERNAL_ERROR.Value()); execInst.setExecStatus(EXEC_STATUS.FINISHED.Value()); @@ -93,7 +97,7 @@ public void run() { dao.update(execInst); } catch (OneM2MException e) { - e.printStackTrace(); + log.debug("Handled exception", e); } } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/NonBlockRequestController.java b/src/main/java/net/herit/iot/onem2m/incse/controller/NonBlockRequestController.java index dd1fd20..0470ae4 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/NonBlockRequestController.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/NonBlockRequestController.java @@ -3,17 +3,18 @@ import java.util.Iterator; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.herit.iot.message.onem2m.OneM2mRequest; import net.herit.iot.message.onem2m.OneM2mResponse; import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; -import net.herit.iot.message.onem2m.OneM2mRequest.RESOURCE_TYPE; import net.herit.iot.message.onem2m.OneM2mRequest.RESPONSE_TYPE; import net.herit.iot.message.onem2m.format.Enums.*; import net.herit.iot.onem2m.core.util.OneM2MException; import net.herit.iot.onem2m.incse.context.OneM2mContext; import net.herit.iot.onem2m.incse.facility.CfgManager; import net.herit.iot.onem2m.incse.facility.OneM2mUtil; -import net.herit.iot.onem2m.incse.manager.ManagerFactory; import net.herit.iot.onem2m.incse.manager.ManagerInterface; import net.herit.iot.onem2m.incse.manager.RequestManager; import net.herit.iot.onem2m.resource.OperationResult; @@ -30,6 +31,8 @@ public class NonBlockRequestController implements Runnable { private Resource tgtResource; private OneM2mRequest request; + private Logger log = LoggerFactory.getLogger(NonBlockRequestController.class); + public NonBlockRequestController(OneM2mContext context, RequestManager reqManager, Request reqResource, ManagerInterface resManager, OneM2mRequest reqMessage) { this.context = context; @@ -110,10 +113,7 @@ public void run() { } catch (OneM2MException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - - + log.debug("Handled exception", e); try { OneM2mResponse response = new OneM2mResponse(e.getResponseStatusCode(), request); @@ -127,8 +127,7 @@ public void run() { reqManager.getDAO().update(reqResource); } catch (OneM2MException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + log.debug("Handled exception", e); } if (request.getResponseTypeEnum() == RESPONSE_TYPE.NBLOCK_REQ_ASYNC) { diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/RestCommandController.java b/src/main/java/net/herit/iot/onem2m/incse/controller/RestCommandController.java index 644fb6f..c8356e6 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/RestCommandController.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/RestCommandController.java @@ -118,13 +118,12 @@ public OneM2mResponse processCommand(RestCommand command) { OneM2mResponse response = new OneM2mResponse(); response.setResponseStatusCode(ex.getResponseStatusCode()); response.setRequest(reqMessage); - ex.printStackTrace(); + log.debug("Handled exception", ex); return response; } } catch (Exception e) { - - e.printStackTrace(); + log.debug("Handled exception", e); return null; } @@ -182,10 +181,10 @@ public void processResult(ContentInstance ci) { } } catch (Base64DecodingException e) { - e.printStackTrace(); + log.debug("Handled exception", e); return; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); return; } @@ -229,7 +228,7 @@ private String extractToFromFullUri(String fullUri) { } catch (URISyntaxException e) { - e.printStackTrace(); + log.debug("Handled exception", e); } return to; @@ -300,7 +299,7 @@ public void run() { } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/controller/dm/HeritDMAdaptor.java b/src/main/java/net/herit/iot/onem2m/incse/controller/dm/HeritDMAdaptor.java index e05c635..2d1390f 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/controller/dm/HeritDMAdaptor.java +++ b/src/main/java/net/herit/iot/onem2m/incse/controller/dm/HeritDMAdaptor.java @@ -7,6 +7,8 @@ import java.util.Set; import org.bson.Document; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.herit.iot.message.onem2m.OneM2mRequest; import net.herit.iot.message.onem2m.OneM2mResponse; @@ -19,6 +21,8 @@ public class HeritDMAdaptor { private String dmAddr; + + private Logger log = LoggerFactory.getLogger(HeritDMAdaptor.class); static class MOUri { @@ -143,7 +147,7 @@ private Document callApi(String to, Document content) throws HitDMException { } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new HitDMException(5001, "Invalid response:"+resMessage.toString()); //throw new OneM2MException(RESPONSE_STATUS.DMSERVER_ERROR, "Invalid response:"+resMessage.toString()); diff --git a/src/main/java/net/herit/iot/onem2m/incse/facility/CfgManager.java b/src/main/java/net/herit/iot/onem2m/incse/facility/CfgManager.java index e1df78b..1ad322b 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/facility/CfgManager.java +++ b/src/main/java/net/herit/iot/onem2m/incse/facility/CfgManager.java @@ -92,9 +92,7 @@ public void initialize() throws Exception { } catch (Exception e) { - log.error("Exception during Configuration loading!!!"); - log.error(e.toString()); - e.printStackTrace(); + log.error("Exception during Configuration loading!!!", e); } // remoteCSE 목록 추가 diff --git a/src/main/java/net/herit/iot/onem2m/incse/facility/OneM2mUtil.java b/src/main/java/net/herit/iot/onem2m/incse/facility/OneM2mUtil.java index fc2a10b..9c96a0a 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/facility/OneM2mUtil.java +++ b/src/main/java/net/herit/iot/onem2m/incse/facility/OneM2mUtil.java @@ -7,6 +7,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.herit.iot.message.onem2m.OneM2mRequest; import net.herit.iot.message.onem2m.OneM2mRequest.OPERATION; import net.herit.iot.message.onem2m.OneM2mRequest.Originator; @@ -26,6 +29,9 @@ public class OneM2mUtil { + + private static Logger log = LoggerFactory.getLogger(OneM2mUtil.class); + public static String createRequestId() { return "REQ_"+UUID.randomUUID().toString(); } @@ -109,7 +115,7 @@ public static boolean checkAccessControlPolicy(OneM2mRequest req, OPERATION op, } } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); } return false; @@ -385,7 +391,7 @@ public static RESOURCE_TYPE getResTypeWithContentString(String pc, } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); return RESOURCE_TYPE.NONE; } @@ -457,11 +463,11 @@ public static Originator createOriginator(OneM2mRequest reqMessage, OneM2mContex return ori; } catch (OneM2MException e) { - e.printStackTrace(); + log.debug("Handled exception", e); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); } return null; diff --git a/src/main/java/net/herit/iot/onem2m/incse/facility/QosManager.java b/src/main/java/net/herit/iot/onem2m/incse/facility/QosManager.java index 63a145c..c028c31 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/facility/QosManager.java +++ b/src/main/java/net/herit/iot/onem2m/incse/facility/QosManager.java @@ -88,9 +88,7 @@ public void initialize(OneM2mContext context) { } catch (Exception e) { - log.error("Exception during QoS initialization!!!"); - log.error(e.toString()); - e.printStackTrace(); + log.error("Exception during QoS initialization!!!", e); } finally { diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/Manager.java b/src/main/java/net/herit/iot/onem2m/incse/manager/Manager.java index b14f0f9..d7a790c 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/Manager.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/Manager.java @@ -20,12 +20,12 @@ import net.herit.iot.onem2m.resource.UriContent; import net.herit.iot.onem2m.resource.UriListContent; -import java.util.Iterator; -import java.util.List; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Iterator; +import java.util.List; + public class Manager { protected OneM2mContext context = null; @@ -33,7 +33,7 @@ public class Manager { protected String ALLOWED_PARENT = ""; protected RESOURCE_TYPE RES_TYPE = RESOURCE_TYPE.NONE; - private Logger log = LoggerFactory.getLogger(Manager.class); + private static Logger log = LoggerFactory.getLogger(Manager.class); public void initialize(OneM2mContext context) { @@ -80,17 +80,17 @@ public static Resource getContentResource(OneM2mRequest message, ManagerInterfac System.out.println("resourceName: " + res.getResourceName()); return res; } catch(Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); return null; } case JSON: // cannot sure if content is resource or not, so just return null in case exception try { jsonCvt = manager.getJSONConveter(); res = (Resource)jsonCvt.unmarshal(str); - System.out.println("resourceName: " + res.getResourceName()); + log.debug("resourceName: " + res.getResourceName()); return res; } catch(Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); return null; } @@ -100,8 +100,7 @@ public static Resource getContentResource(OneM2mRequest message, ManagerInterfac } catch (OneM2MException e) { throw e; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -117,8 +116,7 @@ public static Resource getContentResource(OneM2mRequest req, Class cls, XMLCo //System.out.println("resourceName: " + res.getResourceName()); return res; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -178,8 +176,7 @@ public Resource getContentResource(OneM2mRequest req) throws OneM2MException { System.out.println("resourceName: " + res.getResourceName()); return res; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -195,8 +192,7 @@ public Resource getContentResource(OneM2mRequest req) throws OneM2MException { System.out.println("resourceName: " + res.getResourceName()); return res; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } @@ -210,8 +206,7 @@ public Resource getContentResource(OneM2mRequest req) throws OneM2MException { System.out.println("resourceName: " + res.getResourceName()); return res; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/RemoteCSEManager.java b/src/main/java/net/herit/iot/onem2m/incse/manager/RemoteCSEManager.java index b29915e..fb50fbf 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/RemoteCSEManager.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/RemoteCSEManager.java @@ -221,8 +221,7 @@ public void registerToRemoteCSE(String remoteCseId, List remotePoAs, One strUrl = remotePoAs.get(0); url = new URL(strUrl); } catch (MalformedURLException e) { - e.printStackTrace(); - log.debug("Ignore registerToRemoteCSE("+remoteCseId+") because cannot parse URL!!! " + e.getMessage()); + log.debug("Ignore registerToRemoteCSE("+remoteCseId+") because cannot parse URL!!! ", e); return; } @@ -271,8 +270,7 @@ public void registerToRemoteCSE(String remoteCseId, List remotePoAs, One } dao.create(remoteCse); } catch (OneM2MException e) { - e.printStackTrace(); - log.debug("Fail to createremoteCSE to Database: " + remoteCse.toString() +"\r\n"+ e.getMessage()); + log.debug("Fail to createremoteCSE to Database: " + remoteCse.toString(), e); return; } } else { diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/ResourceManager.java b/src/main/java/net/herit/iot/onem2m/incse/manager/ResourceManager.java index 50e9324..f662f82 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/ResourceManager.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/ResourceManager.java @@ -119,8 +119,7 @@ public void process(OneM2mRequest reqMessage) { } } catch (OneM2MException e) { - e.printStackTrace(); - LogManager.getInstacne().error(e.getMessage()); + log.debug("Handled exception", e); reqMessage.setContent(e.getMessage().getBytes()); @@ -131,8 +130,7 @@ public void process(OneM2mRequest reqMessage) { context.getNseManager().sendResponseMessage(resMessage); } catch (Exception e) { - e.printStackTrace(); - LogManager.getInstacne().error(e.getMessage()); + log.debug("Handled exception", e); resMessage = new OneM2mResponse(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, reqMessage); if(e.getMessage() != null) @@ -287,8 +285,7 @@ public Resource getContentResource(OneM2mRequest req, Class cls, XMLConvertor //System.out.println("resourceName: " + res.getResourceName()); return res; } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(OneM2mResponse.RESPONSE_STATUS.INVALID_ARGUMENTS, "Invalid format"); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEAnncDAO.java index 43f48ce..92922a1 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEAnncDAO.java @@ -34,7 +34,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AEAnnc)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEDAO.java index 59806ff..a7b7ee3 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AEDAO.java @@ -83,8 +83,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AE)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -109,7 +108,7 @@ public void create(Resource resource) throws OneM2MException { // context.getLogManager().debug("AE json: " + strJson); // // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in converting:"+res.toString()); // } // @@ -149,7 +148,7 @@ public void update(Resource resource) throws OneM2MException { // // dbObj = (BasicDBObject) JSON.parse(strJson); // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in converting:"+res.toString()); // } // @@ -175,8 +174,7 @@ public void update(Resource resource) throws OneM2MException { // map.put(f.getName(), val); // } // } catch (IllegalArgumentException | IllegalAccessException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during extract resource field"); // } // } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyAnncDAO.java index 6984682..bc2ea95 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyAnncDAO.java @@ -42,8 +42,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AccessControlPolicyAnnc)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyDAO.java index 5982dc7..6c2fa0d 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/AccessControlPolicyDAO.java @@ -52,8 +52,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AccessControlPolicy)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -79,7 +78,7 @@ public void create(Resource resource) throws OneM2MException { // collection.insertOne(doc); // // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Fail to create AccessControlPolicy"); // } @@ -173,7 +172,7 @@ public List getAccessControlRuleList(String acpId) { // // return res; // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Fail to retrieve AccessControlPolicy"); // } // } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/CSEBaseDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/CSEBaseDAO.java index 5e17e63..c3af47b 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/CSEBaseDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/CSEBaseDAO.java @@ -34,7 +34,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((CSEBase)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerAnncDAO.java index df9d061..85979a1 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerAnncDAO.java @@ -33,7 +33,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((ContainerAnnc)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerDAO.java index 9ab36dc..a980336 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContainerDAO.java @@ -45,8 +45,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Container)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -122,7 +121,7 @@ public void update(Resource resource) throws OneM2MException { // return res; // // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Fail to retrieve Container"); // } // } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceAnncDAO.java index 9476c0d..1807065 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceAnncDAO.java @@ -49,7 +49,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((ContentInstanceAnnc)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -198,7 +198,7 @@ public Resource retrieveOldest(String parentUri, RESULT_CONT resultContent) thro return res; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during initialization of resource using document.(retrieveOldest)"); } @@ -235,7 +235,7 @@ public Resource retrieveLatest(String parentUri, RESULT_CONT resultContent) thro return res; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during initialization of resource using document.(retrieveOldest)"); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceDAO.java index b9a57ef..bb80385 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ContentInstanceDAO.java @@ -84,8 +84,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((ContentInstance)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -155,7 +154,7 @@ public void update(Resource resource) throws OneM2MException { // return res; // // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Fail to retrieve ContentInstance"); // } // } @@ -332,7 +331,7 @@ public Resource retrieveOldest(String parentUri, RESULT_CONT resultContent) thro return res; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during initialization of resource using document.(retrieveOldest)"); } @@ -369,7 +368,7 @@ public Resource retrieveLatest(String parentUri, RESULT_CONT resultContent) thro return res; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during initialization of resource using document.(retrieveOldest)"); } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/DeliveryDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/DeliveryDAO.java index 432ed10..ab1ab24 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/DeliveryDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/DeliveryDAO.java @@ -34,7 +34,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Delivery)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ExecInstanceDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ExecInstanceDAO.java index 0485360..b85080f 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ExecInstanceDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ExecInstanceDAO.java @@ -32,7 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((ExecInstance)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupAnncDAO.java index 505b922..0086323 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupAnncDAO.java @@ -39,7 +39,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((GroupAnnc)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupDAO.java index b8a8a8d..3573bfc 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/GroupDAO.java @@ -40,7 +40,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Group)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkDeviceInfoDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkDeviceInfoDAO.java index 226b665..e515ca5 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkDeviceInfoDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkDeviceInfoDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AreaNwkDeviceInfo)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkInfoDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkInfoDAO.java index fd6410c..9daa486 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkInfoDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtAreaNwkInfoDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((AreaNwkInfo)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtBatteryDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtBatteryDAO.java index 3884fde..c2d7aec 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtBatteryDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtBatteryDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Battery)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtCmdDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtCmdDAO.java index 8553a35..edf7f37 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtCmdDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtCmdDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((MgmtCmd)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceCapabilityDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceCapabilityDAO.java index 0d99928..26515ae 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceCapabilityDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceCapabilityDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((DeviceCapability)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceInfoDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceInfoDAO.java index d6d5df6..f13baad 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceInfoDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtDeviceInfoDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((DeviceInfo)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtEventLogDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtEventLogDAO.java index 9bec13f..1a0bb39 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtEventLogDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtEventLogDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((EventLog)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtFirmwareDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtFirmwareDAO.java index 52c2681..1d8cccd 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtFirmwareDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtFirmwareDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Firmware)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtMemoryDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtMemoryDAO.java index 088f60e..5f74d4a 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtMemoryDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtMemoryDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Memory)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtObjDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtObjDAO.java index 4f14e81..e3578cd 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtObjDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtObjDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((MgmtResource)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtRebootDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtRebootDAO.java index 9c7fee2..924a58a 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtRebootDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtRebootDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Reboot)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtSoftwareDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtSoftwareDAO.java index 91ffad6..1516cb7 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtSoftwareDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/MgmtSoftwareDAO.java @@ -32,8 +32,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Software)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/NodeDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/NodeDAO.java index 3a16b2d..502487b 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/NodeDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/NodeDAO.java @@ -34,7 +34,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Node)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/PollingChannelDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/PollingChannelDAO.java index be74166..93c9799 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/PollingChannelDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/PollingChannelDAO.java @@ -39,8 +39,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((PollingChannel)res); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -61,8 +60,7 @@ public void create(Resource resource) throws OneM2MException { // try { // strJson = jc.marshal(res); // } catch (Exception e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in marshal:"+res.toString()); // } // context.getLogManager().debug("PollingChannel json: " + strJson); @@ -91,8 +89,7 @@ public void update(Resource resource) throws OneM2MException { // map.put(f.getName(), val); // } // } catch (IllegalArgumentException | IllegalAccessException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during extract resource field"); // } // } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEAnncDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEAnncDAO.java index 28aed89..005601a 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEAnncDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEAnncDAO.java @@ -33,7 +33,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((RemoteCSEAnnc)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEDAO.java index d5dcc95..c547748 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RemoteCSEDAO.java @@ -43,7 +43,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((RemoteCSE)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RequestDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RequestDAO.java index bd85a16..15fce30 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RequestDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/RequestDAO.java @@ -33,7 +33,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Request)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ResourceDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ResourceDAO.java index f685027..ee6fca6 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ResourceDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ResourceDAO.java @@ -125,7 +125,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Resource) res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:" + res.toString()); } @@ -218,8 +218,7 @@ public Resource retrieve(String key, String value, JSONConvertor cvt, // } // // } catch (Exception e) { -// e.printStackTrace(); -// // No getChildResource method resource. no problem!!! +// log.debug("Handled exception", e); // } // } else if (rc == RESULT_CONT.ATTR_N_CHILD_RES_REF || rc == RESULT_CONT.CHILD_RES_REF || rc == RESULT_CONT.ATTR_N_CHILD_RES) { @@ -239,8 +238,7 @@ public Resource retrieve(String key, String value, JSONConvertor cvt, } } catch (Exception e) { - e.printStackTrace(); - // No getChildResource method resource. no problem!!! + log.debug("Handled exception", e); } } @@ -248,7 +246,7 @@ public Resource retrieve(String key, String value, JSONConvertor cvt, } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in converting:" + doc.toString()); @@ -360,7 +358,7 @@ public Resource createResourceWithDoc(Document doc) throws OneM2MException { res.setUri(doc.getString(URI_KEY)); return res; } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in making res from doc:" + e.getMessage()); } @@ -396,7 +394,7 @@ public Resource createResourceWithDoc(Document doc) throws OneM2MException { // res.initializeWithDoc(doc); // } catch (Exception e) { // // TODO Auto-generated catch block - // e.printStackTrace(); + // log.debug("Handled exception", e); // // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, // "Exception during initialization of resource using document."); @@ -534,7 +532,7 @@ public Resource getResource(String key, String value) throws OneM2MException { res.setUri(doc.getString(URI_KEY)); // res.setId(doc.getString(OID_KEY)); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "unmarshal file in ResouceDAO.getResourceWithUri:" + doc.toJson()); @@ -557,7 +555,7 @@ public Resource getResource(String id) throws OneM2MException { res.setUri(doc.getString(URI_KEY)); // res.setId(doc.getString(OID_KEY)); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "unmarshal file in ResouceDAO.getResourceWithUri:" + doc.toJson()); @@ -581,7 +579,7 @@ public Resource getResourceWithID(String resourceID) throws OneM2MException { res.setUri(doc.getString(URI_KEY)); // res.setId(doc.getString(OID_KEY)); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "unmarshal file in ResouceDAO.getResourceWithID:" + doc.toJson()); diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ScheduleDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ScheduleDAO.java index f916735..9f234b2 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ScheduleDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/ScheduleDAO.java @@ -33,7 +33,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Schedule)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } diff --git a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/SubscriptionDAO.java b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/SubscriptionDAO.java index 29bdad4..e0b2566 100644 --- a/src/main/java/net/herit/iot/onem2m/incse/manager/dao/SubscriptionDAO.java +++ b/src/main/java/net/herit/iot/onem2m/incse/manager/dao/SubscriptionDAO.java @@ -67,7 +67,7 @@ public String resourceToJson(Resource res) throws OneM2MException { return jc.marshal((Subscription)res); } catch (Exception e) { - e.printStackTrace(); + log.debug("Handled exception", e); throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Json generation error:"+res.toString()); } } @@ -115,8 +115,7 @@ public void update(Resource resource) throws OneM2MException { // map.put(f.getName(), val); // } // } catch (IllegalArgumentException | IllegalAccessException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception during extract resource field"); // } // } @@ -153,7 +152,7 @@ public void update(Resource resource) throws OneM2MException { // return ae; // // } catch (Exception e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Fail to retrieve AE"); // } // diff --git a/src/main/java/net/herit/iot/onem2m/resource/MetaInformation.java b/src/main/java/net/herit/iot/onem2m/resource/MetaInformation.java index 77ed552..7259f30 100644 --- a/src/main/java/net/herit/iot/onem2m/resource/MetaInformation.java +++ b/src/main/java/net/herit/iot/onem2m/resource/MetaInformation.java @@ -134,7 +134,7 @@ public MetaInformation(OneM2mRequest reqMessage) throws OneM2MException { // du = DatatypeFactory.newInstance().newDuration(reqMessage.getResultPersistenceString()); // this.setResultPersistence(du); // } catch (DatatypeConfigurationException e) { -// e.printStackTrace(); +// log.debug("Handled exception", e); // throw new OneM2MException(RESPONSE_STATUS.BAD_REQUEST, "Fail to decode result persistence:" + reqMessage.toString()); // } // } diff --git a/src/main/java/net/herit/iot/onem2m/resource/PrimitiveContent.java b/src/main/java/net/herit/iot/onem2m/resource/PrimitiveContent.java index 8a28042..3298bc8 100644 --- a/src/main/java/net/herit/iot/onem2m/resource/PrimitiveContent.java +++ b/src/main/java/net/herit/iot/onem2m/resource/PrimitiveContent.java @@ -107,7 +107,7 @@ public PrimitiveContent(Object contentObj) { // throws OneM2MException { //// } //// //// } catch (Exception e) { -//// e.printStackTrace(); +//// log.debug("Handled exception", e); //// throw new OneM2MException(RESPONSE_STATUS.INTERNAL_SERVER_ERROR, "Exception in initialization of PrimitiveContent"); //// } // } else { @@ -134,8 +134,7 @@ public PrimitiveContent(Object contentObj) { // throws OneM2MException { // this.getAny().add(new String(message.getContent(), "UTF-8")); // } // } catch (Exception e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// log.debug("Handled exception", e); // } // } // }