Implements OIC/OCF resource models for cloud.
authorJee Hyeok Kim <jihyeok13.kim@samsung.com>
Mon, 4 Jul 2016 10:46:51 +0000 (19:46 +0900)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Tue, 19 Jul 2016 13:16:31 +0000 (13:16 +0000)
1. Project restructured (API Naming, Callbacks and File location).
2. Add Message Queue implementation (IETF Proposal).
3. OAuth2 authcode, accesstoken, refreshtoken based authentication support.
4. Resource Directory implementation, follows latest OIC Spec.

Change-Id: I036a9d1d54b09dc995f36f8b93029fa149963744
Signed-off-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9141
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
147 files changed:
cloud/README
cloud/account/.project [deleted file]
cloud/account/Github.jar [new file with mode: 0644]
cloud/account/pom.xml
cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserDevice.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserSession.java [deleted file]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserToken.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java [deleted file]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/Github.jar [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/OAuthServer.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/OAuthServerFactory.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java [deleted file]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java [deleted file]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/ResponseObject.java [deleted file]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/device/DeviceResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/session/SessionResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/tokenrefresh/TokenRefreshResource.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/Token.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenGenerator.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenManager.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenPolicy.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenValidator.java [new file with mode: 0644]
cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java [deleted file]
cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java [deleted file]
cloud/interface/.project [deleted file]
cloud/interface/pom.xml
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/DeviceServerSystem.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java [deleted file]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java [deleted file]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/KeepAliveResource.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/Account.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/DevicePresence.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/MessageQueue.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceDirectory.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceFind.java [new file with mode: 0644]
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourcePresence.java [new file with mode: 0644]
cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java [deleted file]
cloud/messagequeue/.classpath [new file with mode: 0644]
cloud/messagequeue/.gitignore [new file with mode: 0644]
cloud/messagequeue/pom.xml [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/Constants.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueServer.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueUtils.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaCommonWrapper.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaConsumerWrapper.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaProducerWrapper.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/resources/MQBrokerResource.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/Topic.java [new file with mode: 0644]
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/TopicManager.java [new file with mode: 0644]
cloud/resourcedirectory/.project [deleted file]
cloud/resourcedirectory/pom.xml
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/Constants.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/ResourceDirectoryServer.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/DBManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/MongoDB.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/LinksPayloadFormat.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/PublishPayloadFormat.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/InsManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishLinks.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishPayload.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishTags.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/ResourceDirectoryResource.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryLinks.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryPayload.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryResource.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryTags.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/ResPresenceManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DevicePresenceResource.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DeviceState.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresencePayload.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresenceResource.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/util/TypeCastingManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java [deleted file]
cloud/stack/.project [deleted file]
cloud/stack/pom.xml
cloud/stack/src/main/java/log4j.properties [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/OCFConstants.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/Resource.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/ServerSystem.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapClient.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapConnector.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/connector/ConnectorPool.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/connector/HttpClient.java [moved from cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java with 85% similarity]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/CoapDevice.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/Device.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/HttpDevice.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestChannel.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestEventHandler.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/device/IResponseEventHandler.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ClientException.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ServerException.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IRequest.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IResponse.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/Message.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/MessageBuilder.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapDecoder.java
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapEncoder.java
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapLogHandler.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapOption.java [moved from cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapOption.java with 65% similarity]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapResponse.java
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapMethod.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapStatus.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ContentFormat.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/Observe.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/RequestMethod.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ResponseStatus.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/http/HttpMessage.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/base/resource/Resource.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/resource/ResourceManager.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/resource/URIPathNode.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/server/CoapServer.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/server/HttpServer.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/base/server/Server.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/util/Bytes.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/util/Cbor.java
cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java [deleted file]
cloud/stack/src/main/java/org/iotivity/cloud/util/ErrorLogger.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/util/FileLogger.java [new file with mode: 0644]
cloud/stack/src/main/java/org/iotivity/cloud/util/JSONUtil.java
cloud/stack/src/main/java/org/iotivity/cloud/util/Logger.java
cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java [deleted file]
cloud/stack/src/test/java/org/iotivity/cloud/util/UtilTest.java [deleted file]

index 81b45a2..1f2f60b 100644 (file)
@@ -2,11 +2,12 @@ This project contains series of modules for building cloud services.
 
 Modules
 
-1. stack - Java 1.7 based CoAP over TCP implementation.
+1. stack - Java 1.8 based CoAP over TCP implementation.
 2. interface - cloud interface server that accept incoming IoTivity clients connection.
 3. resource_directory - resource directory server that store clients resource models.
 4. account - account server that handle clients credential using OAuth2.
-5. samples - sample IoTivity clients that show how clients working with cloud.
+5. message_queue - message queue server that provides pub/sub feature.
+6. samples - sample IoTivity clients that show how clients working with cloud.
 
 Each cloud modules has README file how to install and run.
 You can run each modules on single computer or PAAS.
@@ -15,4 +16,5 @@ Note. resource_directory should launched before interface and account.
 
 Architecture
 client--------interface_server--------resource_directory_server--------mongo_db
-                      \---------------account_server-------------------mongo_db
\ No newline at end of file
+                      \---------------account_server-------------------mongo_db
+                                         \---------------message_queue_server-------------kafka
\ No newline at end of file
diff --git a/cloud/account/.project b/cloud/account/.project
deleted file mode 100644 (file)
index 336bb80..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>CloudAccount</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.m2e.core.maven2Builder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-               <nature>org.eclipse.m2e.core.maven2Nature</nature>
-       </natures>
-</projectDescription>
diff --git a/cloud/account/Github.jar b/cloud/account/Github.jar
new file mode 100644 (file)
index 0000000..c7b8f8a
Binary files /dev/null and b/cloud/account/Github.jar differ
index e4d08ab..d066f10 100644 (file)
@@ -6,6 +6,7 @@
   
   <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.test.skip>true</maven.test.skip>
        </properties>
        
   <dependencies>
                        <artifactId>org.apache.oltu.oauth2.client</artifactId>
                        <version>1.0.1</version>
                </dependency>
+               <dependency>
+                       <groupId>org.apache.oltu.oauth2</groupId>
+                       <artifactId>
+                               org.apache.oltu.oauth2.common
+                       </artifactId>
+                       <version>1.0.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.oltu.oauth2</groupId>
+                       <artifactId>
+                               org.apache.oltu.oauth2.authzserver
+                       </artifactId>
+                       <version>1.0.1</version>
+               </dependency>
   </dependencies>
        
   <build>
@@ -38,8 +53,8 @@
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
-                                       <source>1.7</source>
-                                       <target>1.7</target>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
                                        <encoding>UTF-8</encoding>
                                </configuration>
                        </plugin>
index 5a0e32b..f9c00a9 100644 (file)
@@ -1,33 +1,37 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver;
 
 import java.net.InetSocketAddress;
 import java.util.Scanner;
 
-import org.iotivity.cloud.accountserver.resources.AccountResource;
-import org.iotivity.cloud.accountserver.resources.AuthResource;
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
+import org.iotivity.cloud.accountserver.resources.account.AccountResource;
+import org.iotivity.cloud.accountserver.resources.account.device.DeviceResource;
+import org.iotivity.cloud.accountserver.resources.account.session.SessionResource;
+import org.iotivity.cloud.accountserver.resources.account.tokenrefresh.TokenRefreshResource;
+import org.iotivity.cloud.base.ServerSystem;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.util.ErrorLogger;
+import org.iotivity.cloud.util.FileLogger;
 import org.iotivity.cloud.util.Logger;
 
 /**
@@ -38,28 +42,35 @@ import org.iotivity.cloud.util.Logger;
 public class AccountServer {
 
     public static void main(String[] args) throws Exception {
+        System.setOut(FileLogger.createLoggingProxy(System.out));
 
         System.out.println("-----Account SERVER-----");
 
-        if (args.length != 1) {
-            Logger.e("coap server port required");
+        if (args.length != 2) {
+            Logger.e("coap server port and TLS mode required\n"
+                    + "ex) 5685 0\n");
             return;
         }
 
-        ResourceManager resourceManager = null;
+        ErrorLogger.Init();
+
+        ServerSystem serverSystem = new ServerSystem();
+
+        serverSystem.addResource(new AccountResource());
+
+        serverSystem.addResource(new SessionResource());
 
-        CoapServer coapServer = null;
+        serverSystem.addResource(new TokenRefreshResource());
 
-        coapServer = new CoapServer();
+        // Temporally added
+        serverSystem.addResource(new DeviceResource());
 
-        resourceManager = new ResourceManager();
-        coapServer.addHandler(resourceManager);
+        serverSystem.addServer(new CoapServer(
+                new InetSocketAddress(Integer.parseInt(args[0]))));
 
-        resourceManager.registerResource(new AuthResource());
-        resourceManager.registerResource(new AccountResource());
+        boolean tlsMode = Integer.parseInt(args[1]) == 1;
 
-        coapServer
-                .startServer(new InetSocketAddress(Integer.parseInt(args[0])));
+        serverSystem.startSystem(tlsMode);
 
         Scanner in = new Scanner(System.in, "UTF-8");
 
@@ -71,7 +82,7 @@ public class AccountServer {
 
         System.out.println("Terminating...");
 
-        coapServer.stopServer();
+        serverSystem.stopSystem();
 
         System.out.println("Terminated");
     }
index 5749a7a..2214ebc 100644 (file)
@@ -1,31 +1,32 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver;
 
 import java.util.ArrayList;
-import java.util.Random;
 
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
-import org.iotivity.cloud.accountserver.oauth.GitHub;
+import org.iotivity.cloud.accountserver.oauth.OAuthServerFactory;
+import org.iotivity.cloud.accountserver.token.Token;
+import org.iotivity.cloud.accountserver.token.TokenManager;
 import org.iotivity.cloud.util.Logger;
 
 /**
@@ -36,9 +37,11 @@ import org.iotivity.cloud.util.Logger;
  */
 public class AccountServerManager {
 
+    private OAuthServerFactory factory = null;
+
     /**
      * API for requesting user account
-     *
+     * 
      * @param userId
      *            user identifier
      * @param deviceId
@@ -59,63 +62,68 @@ public class AccountServerManager {
     /**
      * API for requesting user account and getting session code for registered
      * user.
-     *
+     * 
      * @param userId
      *            user identifier
      * @return String - session code for registered user
      */
-    public String registerUserAccount(String userId) {
+    public Token registerUserAccount(String userId) {
 
-        String sessionCode = null;
-        sessionCode = generateSessionCode();
+        // String sessionCode = null;
+        // sessionCode = generateSessionCode();
+
+        TokenManager tokenManager = new TokenManager();
+        Token token = tokenManager.generateToken();
 
         // store info to OAuthDBManager
-        AccountDBManager.getInstance().registerUserSessionCode(userId,
-                sessionCode);
+        AccountDBManager.getInstance().registerUserToken(userId,
+                token.getAccessToken(), token.getRefreshToken());
 
-        return sessionCode;
+        // return sessionCode;
+        return token;
     }
 
     /**
      * API for requesting user identifier corresponding with authorization
      * information.
-     *
+     * 
      * @param authCode
      *            authorization code
      * @param authServer
      *            authorization server
      * @return String - user identifier
      */
-    public String requestUserId(String authCode, String authServer) {
+    public String requestUserId(String authCode, String authServer,
+            String authServerUrl, String apiServerUrl) {
 
         String userId = null;
 
-        String accessToken = getAccessToken(authCode, authServer);
-        userId = getUserId(accessToken, authServer);
+        userId = getUserId(authCode, authServer, authServerUrl, apiServerUrl);
 
         return userId;
     }
 
     /**
      * API for requesting user identifier corresponding with session code.
-     *
+     * 
      * @param sessionCode
      *            session code
      * @return String - user identifier
      */
-    public String requestUserId(String sessionCode) {
+    public String requestUserId(String accessToken) {
 
         String userId = null;
 
         // get userId from MongDB
-        userId = AccountDBManager.getInstance().getUserId(sessionCode);
+        userId = AccountDBManager.getInstance()
+                .getUserIdByAccessToken(accessToken);
 
         return userId;
     }
 
     /**
      * API for getting devices corresponding with user identifier.
-     *
+     * 
      * @param userId
      *            user identifier
      * @return ArrayList<String> - list of devices
@@ -130,68 +138,27 @@ public class AccountServerManager {
         return deviceList;
     }
 
-    private String getAccessToken(String authCode, String authServer) {
-
-        String accessToken = null;
-
-        if (authServer.equals(Constants.GITHUB)) {
-
-            GitHub gitHub = new GitHub();
-            accessToken = gitHub.requestAccessToken(authCode);
+    public Boolean loadAuthServer(String authServer) {
+        factory = new OAuthServerFactory();
 
-        } else {
-
-            Logger.e("unsupported auth.server = " + authServer);
-        }
-
-        return accessToken;
+        return factory.create(authServer);
     }
 
-    private String getUserId(String accessToken, String authServer) {
+    private String getUserId(String authCode, String authServer,
+            String authServerUrl, String apiServerUrl) {
 
         String userId = null;
 
-        if (authServer.equals(Constants.GITHUB)) {
-
-            GitHub gitHub = new GitHub();
-            userId = gitHub.requestGetUserInfo(accessToken);
+        String accessToken = factory.requestAccessToken(authCode,
+                authServerUrl);
 
+        if (accessToken == null) {
+            return null;
         } else {
-
-            Logger.e("unsupported auth.server = " + authServer);
+            userId = factory.requestGetUserInfo(accessToken, apiServerUrl);
         }
 
         return userId;
     }
 
-    private String generateSessionCode() {
-
-        StringBuffer sessionCode = new StringBuffer();
-
-        Random random = new Random();
-        int randomNum = random.nextInt(122);
-        char code;
-
-        // generate 16byte key with 0-9, A-Z, a-z
-        for (int k = 0; k < 16; k++) {
-            while (true) {
-                if ((randomNum >= 48 && randomNum <= 57)
-                        || (randomNum >= 65 && randomNum <= 90)
-                        || (randomNum >= 97 && randomNum <= 122)) {
-
-                    code = (char) randomNum;
-                    sessionCode.append(code);
-
-                    randomNum = random.nextInt(122);
-                    break;
-
-                } else {
-
-                    randomNum = random.nextInt(122);
-                }
-            }
-        }
-
-        return sessionCode.toString();
-    }
 }
index c350789..393d4fa 100644 (file)
@@ -1,64 +1,91 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver;
 
-public class Constants {
+import org.iotivity.cloud.base.OCFConstants;
+
+public class Constants extends OCFConstants {
 
     // MongoDB
-    public static final String DEVICE_TABLE          = "USER_DEVICE";
-    public static final String SESSION_TABLE         = "USER_SESSION";
-    public static final String DB_NAME               = "ACCOUNTSERVER_DB";
-    public static final String USER_ID               = "userId";
-    public static final String DEVICE_ID             = "deviceId";
-    public static final String SESSION_CODE          = "sessionCode";
-
-    // Resource Uri
-    public static final String AUTH_URI              = "oic/auth";
-    public static final String ACCOUNT_URI           = "oic/account";
-
-    // query parameter
-    public static final String REQ_TYPE              = "reqtype";
-
-    // request type
-    public static final String TYPE_REGISTER         = "register";
-    public static final String TYPE_LOGIN            = "login";
-    public static final String TYPE_PUBLISH          = "publish";
-    public static final String TYPE_FIND             = "find";
-
-    // request payload
-    public static final String REQUEST_AUTH_CODE     = "authcode";
-    public static final String REQUEST_AUTH_SERVER   = "authprovider";
-    public static final String REQUEST_DEVICE_ID     = "deviceid";
-    public static final String REQUEST_USER_ID       = "userid";
-    public static final String REQUEST_SESSION_CODE  = "session";
-
-    // response
-    public static final String RESPONSE_SESSION_CODE = "session";
-    public static final String RESPONSE_USER_ID      = "userid";
-    public static final String RESPONSE_STATE        = "state";
-    public static final String RESPONSE_DEVICES      = "devices";
+
+    public static final String DB_NAME             = "ACCOUNTSERVER_DB";
+
+    public static final String DEVICE_TABLE        = "USER_DEVICE";
+
+    public static final String TOKEN_TABLE         = "USER_TOKEN";
+
+    public static final String KEY_USER_ID         = "userId";
+
+    public static final String KEY_DEVICE_ID       = "deviceId";
+
+    public static final String KEY_ACCESS_TOKEN    = "accesstoken";
+
+    public static final String KEY_REFRESH_TOKEN   = "refreshtoken";
+
+    public static final String KEY_ISSUED_TIME     = "issuedTime";
+
+    // request payload key
+
+    public static final String REQ_DEVICE_ID       = "di";
+
+    public static final String REQ_AUTH_CODE       = "authcode";
+
+    public static final String REQ_AUTH_PROVIDER   = "authprovider";
+
+    public static final String REQ_ACCESS_TOKEN    = "accesstoken";
+
+    public static final String REQ_STATUS          = "status";
+
+    public static final String REQ_REFRESH_TOKEN   = "refreshtoken";
+
+    public static final String REQ_AUTH_OPTIONS    = "options";
+
+    public static final String REQ_AUTH_SERVER_URL = "auth_server_url";
+
+    public static final String REQ_API_SERVER_URL  = "api_server_url";
+
+    // response payload key
+
+    public static final String RESP_ACCESS_TOKEN   = "accesstoken";
+
+    public static final String RESP_REFRESH_TOKEN  = "refreshtoken";
+
+    public static final String RESP_TOKEN_TYPE     = "tokentype";
+
+    public static final String RESP_EXPIRES_IN     = "expiresin";
+
+    public static final String RESP_DEVICES        = "devices";
+
+    public static final String RESP_USER_ID        = "uid";
 
     // auth servers
-    public static final String GITHUB                = "github";
-    public static final String GOOGLE                = "google";
-    public static final String FACEBOOK              = "facebook";
+
+    public static final String GITHUB              = "Github";
+
+    public static final String SAMSUNG             = "Samsung";
+
+    public static final String KEY_ACCESS_TOKEN_GH = "access_token";
+
+    // etc
+
+    public static final String ERROR_MESSAGE       = "error_message";
 }
index dbb0e20..9f859b6 100644 (file)
@@ -1,23 +1,23 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver.db;
 
@@ -42,14 +42,11 @@ public class AccountDBManager {
             mongoDB = new MongoDB(Constants.DB_NAME);
 
             mongoDB.createTable(Constants.DEVICE_TABLE);
-            mongoDB.createTable(Constants.SESSION_TABLE);
-
-            registerAdminAccount();
+            // mongoDB.createTable(Constants.SESSION_TABLE);
+            mongoDB.createTable(Constants.TOKEN_TABLE);
 
         } catch (Exception e) {
-
             e.printStackTrace();
-
         }
     }
 
@@ -58,31 +55,38 @@ public class AccountDBManager {
         return accoutDBManager;
     }
 
-    /**
-     * API for storing session information of authorized user
-     *
-     * @param userId
-     *            user identifier
-     * @param sessionCode
-     *            session code
-     * @return Boolean - true if stored, otherwise false
-     */
-    public Boolean registerUserSessionCode(String userId, String sessionCode) {
-
-        UserSession userSession = new UserSession();
+    public Boolean registerUserToken(String userId, String accessToken,
+            String refreshToken) {
 
-        userSession.setUserId(userId);
-        userSession.setSessionCode(sessionCode);
+        UserToken userToken = new UserToken();
 
-        mongoDB.createResource(userSession);
+        userToken.setUserToken(userId, accessToken, refreshToken);
+        mongoDB.createResource(userToken);
         mongoDB.printResources();
 
         return true;
     }
 
+    public Boolean updateUserToken(String userId, String oldRefreshToken,
+            String newAccessToken, String newRefreshToken) {
+
+        Boolean updateUserToken = false;
+
+        UserToken oldUserToken = new UserToken();
+        oldUserToken.setUserToken(userId, null, oldRefreshToken);
+
+        UserToken newUserToken = new UserToken();
+        newUserToken.setUserToken(userId, newAccessToken, newRefreshToken);
+
+        updateUserToken = mongoDB.updateResource(oldUserToken, newUserToken);
+        mongoDB.printResources();
+
+        return updateUserToken;
+    }
+
     /**
      * API for storing device information of authorized user
-     *
+     * 
      * @param userId
      *            user identifier
      * @param deviceId
@@ -105,47 +109,67 @@ public class AccountDBManager {
     /**
      * API for getting user identifier information corresponding with session
      * code
-     *
+     * 
      * @param userId
      *            identifier of authorized user
      * @param sessionCode
      *            session code
      * @return Boolean - true if stored, otherwise false
      */
-    public String getUserId(String sessionCode) {
+    public String getUserIdByAccessToken(String token) {
+
+        String userId = null;
+
+        userId = mongoDB.getUserIdByAccessToken(token);
+
+        return userId;
+    }
+
+    public String getUserIdByRefreshToken(String token) {
 
         String userId = null;
 
-        userId = mongoDB.getUserId(sessionCode);
+        userId = mongoDB.getUserIdByRefreshToken(token);
 
         return userId;
     }
 
     /**
      * API for getting devices corresponding with user identifier
-     *
+     * 
      * @param userId
      *            user identifier
      * @return ArrayList<String> - list of devices
      */
     public ArrayList<String> getDevices(String userId) {
 
-        ArrayList<String> deviceList = mongoDB.getDevices(userId);
+        ArrayList<String> deviceList = new ArrayList<>();
+
+        deviceList = mongoDB.getDevices(userId);
 
         return deviceList;
     }
 
-    private void registerAdminAccount() {
+    public Boolean hasAccessToken(String token) {
 
-        String adminId = "admin";
-        String adminSessionCode = "00000000";
+        Boolean hasAccessToken = false;
+        hasAccessToken = mongoDB.hasAccessToken(token);
 
-        UserSession userSession = new UserSession();
+        return hasAccessToken;
+    }
 
-        userSession.setUserId(adminId);
-        userSession.setSessionCode(adminSessionCode);
+    public Boolean hasRefreshToken(String token) {
+
+        Boolean hasRefreshToken = false;
+        hasRefreshToken = mongoDB.hasRefreshToken(token);
+
+        return hasRefreshToken;
+    }
+
+    public String getIssuedTime(String accessToken) {
+
+        String issuedTime = mongoDB.getIssuedTime(accessToken);
+        return issuedTime;
 
-        mongoDB.createResource(userSession);
-        mongoDB.printResources();
     }
 }
index 191d17a..b86cc8b 100644 (file)
@@ -1,27 +1,30 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver.db;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 
 import org.bson.Document;
 import org.iotivity.cloud.accountserver.Constants;
@@ -88,23 +91,20 @@ public class MongoDB {
         return db;
     }
 
-    /**
-     * API for storing session information of user
-     * 
-     * @param UserSession
-     *            session information of user
-     */
-    public void createResource(UserSession userSession) {
-
-        Document doc = createDocument(userSession);
+    public void createResource(UserToken userToken) {
+        Document doc = createDocument(userToken);
         MongoCollection<Document> collection = db
-                .getCollection(Constants.SESSION_TABLE);
-
-        if (collection.findOneAndReplace(Filters.and(
-                Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)),
-                Filters.eq(Constants.SESSION_CODE, doc.get(Constants.SESSION_CODE))),
+                .getCollection(Constants.TOKEN_TABLE);
+
+        if (collection.findOneAndReplace(
+                Filters.and(
+                        Filters.eq(Constants.KEY_USER_ID,
+                                doc.get(Constants.KEY_USER_ID)),
+                        Filters.eq(Constants.KEY_ACCESS_TOKEN,
+                                doc.get(Constants.KEY_ACCESS_TOKEN)),
+                        Filters.eq(Constants.KEY_REFRESH_TOKEN,
+                                doc.get(Constants.KEY_REFRESH_TOKEN))),
                 doc) == null) {
-
             collection.insertOne(doc);
         }
 
@@ -123,9 +123,13 @@ public class MongoDB {
         MongoCollection<Document> collection = db
                 .getCollection(Constants.DEVICE_TABLE);
 
-        if (collection.findOneAndReplace(Filters.and(
-                Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)),
-                Filters.eq(Constants.DEVICE_ID, doc.get(Constants.DEVICE_ID))), doc) == null) {
+        if (collection.findOneAndReplace(
+                Filters.and(
+                        Filters.eq(Constants.KEY_USER_ID,
+                                doc.get(Constants.KEY_USER_ID)),
+                        Filters.eq(Constants.KEY_DEVICE_ID,
+                                doc.get(Constants.KEY_DEVICE_ID))),
+                doc) == null) {
 
             collection.insertOne(doc);
         }
@@ -141,24 +145,54 @@ public class MongoDB {
      *            session code
      * @return String - user identifier
      */
-    public String getUserId(String sessionCode) {
+    public String getUserIdByAccessToken(String token) {
+
+        String userId = null;
+
+        MongoCollection<Document> collection = db
+                .getCollection(Constants.TOKEN_TABLE);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_ACCESS_TOKEN, token)).iterator();
+
+        try {
+
+            while (cursor.hasNext()) {
+
+                Document doc = cursor.next();
+                UserToken userToken = convertTokenDocToResource(doc);
+
+                userId = userToken.getUserId();
+                break;
+            }
+
+        } finally {
+
+            cursor.close();
+        }
+
+        return userId;
+    }
+
+    public String getUserIdByRefreshToken(String token) {
 
         String userId = null;
 
         MongoCollection<Document> collection = db
-                .getCollection(Constants.SESSION_TABLE);
+                .getCollection(Constants.TOKEN_TABLE);
 
-        MongoCursor<Document> cursor = collection.find(
-                Filters.eq(Constants.SESSION_CODE, sessionCode)).iterator();
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_REFRESH_TOKEN, token))
+                .iterator();
 
         try {
 
             while (cursor.hasNext()) {
 
                 Document doc = cursor.next();
-                UserSession userSession = convertSessionDocToResource(doc);
+                UserToken userToken = convertTokenDocToResource(doc);
 
-                userId = userSession.getUserId();
+                userId = userToken.getUserId();
                 break;
             }
 
@@ -178,13 +212,13 @@ public class MongoDB {
      */
     public ArrayList<String> getDevices(String userId) {
 
-        ArrayList<String> deviceList = new ArrayList<String>();
+        ArrayList<String> deviceList = new ArrayList<>();
 
         MongoCollection<Document> collection = db
                 .getCollection(Constants.DEVICE_TABLE);
 
-        MongoCursor<Document> cursor = collection.find(
-                Filters.eq(Constants.USER_ID, userId)).iterator();
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_USER_ID, userId)).iterator();
 
         try {
 
@@ -204,12 +238,108 @@ public class MongoDB {
         return deviceList;
     }
 
+    public Boolean hasAccessToken(String token) {
+
+        Boolean hasAccessToken = false;
+
+        MongoCollection<Document> collection = db
+                .getCollection(Constants.TOKEN_TABLE);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_ACCESS_TOKEN, token)).iterator();
+
+        if (cursor.hasNext())
+            hasAccessToken = true;
+
+        cursor.close();
+
+        return hasAccessToken;
+    }
+
+    public Boolean hasRefreshToken(String token) {
+
+        Boolean hasRefreshToken = false;
+
+        MongoCollection<Document> collection = db
+                .getCollection(Constants.TOKEN_TABLE);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_REFRESH_TOKEN, token))
+                .iterator();
+
+        if (cursor.hasNext())
+            hasRefreshToken = true;
+
+        cursor.close();
+
+        return hasRefreshToken;
+    }
+
+    public Boolean updateResource(UserToken oldUserToken,
+            UserToken newUserToken) {
+
+        Boolean updateResource = false;
+        String userId = oldUserToken.getUserId();
+        String oldRefreshToken = oldUserToken.getRefreshToken();
+
+        Document doc = createDocument(newUserToken);
+
+        MongoCollection<Document> collection = db
+                .getCollection(Constants.TOKEN_TABLE);
+
+        // update
+        if (collection.findOneAndReplace(
+                Filters.and(Filters.eq(Constants.KEY_USER_ID, userId), Filters
+                        .eq(Constants.KEY_REFRESH_TOKEN, oldRefreshToken)),
+                doc) != null) {
+
+            // collection.insertOne(doc);
+            updateResource = true;
+
+        } else {
+            Logger.e("UpdateResource failed!");
+        }
+
+        return updateResource;
+    }
+
+    public String getIssuedTime(String accessToken) {
+
+        MongoCollection<Document> collection = db
+                .getCollection(Constants.TOKEN_TABLE);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.KEY_ACCESS_TOKEN, accessToken))
+                .iterator();
+
+        String issuedTime = null;
+
+        try {
+
+            while (cursor.hasNext()) {
+
+                Document doc = cursor.next();
+                UserToken userToken = convertTokenDocToResource(doc);
+
+                issuedTime = userToken.getIssuedTime();
+                break;
+            }
+
+        } finally {
+
+            cursor.close();
+        }
+
+        return issuedTime;
+
+    }
+
     public void printResources() {
 
         ArrayList<UserDevice> dlist = readDeviceResources();
         int size = dlist.size();
-
-        Logger.i("*Table: " + Constants.DEVICE_TABLE);
+        
+        Logger.i("[" + Constants.DEVICE_TABLE + "]Table");
         for (int i = 0; i < size; i++) {
 
             UserDevice item = dlist.get(i);
@@ -218,79 +348,114 @@ public class MongoDB {
                     + item.getDeviceId());
         }
 
-        ArrayList<UserSession> slist = readSessionResources();
-        size = slist.size();
-
-        Logger.i("*Table: " + Constants.SESSION_TABLE);
+        /*
+         * ArrayList<UserSession> slist = readSessionResources(); size =
+         * slist.size();
+         * 
+         * Logger.i("*Table: " + Constants.SESSION_TABLE);
+         * 
+         * for (int i = 0; i < size; i++) {
+         * 
+         * UserSession item = slist.get(i);
+         * 
+         * Logger.i("[" + i + "]" + item.getUserId() + ", " +
+         * item.getSessionCode());
+         * 
+         * }
+         */
+
+        ArrayList<UserToken> tlist = readUserTokenResources();
+        size = tlist.size();
+
+        Logger.i("[" + Constants.TOKEN_TABLE + "]Table");
 
         for (int i = 0; i < size; i++) {
 
-            UserSession item = slist.get(i);
+            UserToken item = tlist.get(i);
 
-            Logger.i("[" + i + "]" + item.getUserId() + ", "
-                    + item.getSessionCode());
+            Logger.i("[" + i + "]" + item.getUserId() + "/"
+                    + item.getAccessToken() + "/" + item.getRefreshToken() + "/"
+                    + item.getIssuedTime());
 
         }
     }
 
-    private Document createDocument(UserSession userSession) {
+    private Document createDocument(UserToken userToken) {
+
+        String userId = userToken.getUserId();
+        String accessToken = userToken.getAccessToken();
+        String refreshToken = userToken.getRefreshToken();
 
-        Document doc = new Document(Constants.USER_ID, userSession.getUserId())
-                .append(Constants.SESSION_CODE, userSession.getSessionCode());
+        DateFormat f = new SimpleDateFormat("yyyyMMddkkmm");
+        Date currentDate = new Date();
+
+        String issuedTime = f.format(currentDate);
+
+        Document doc = new Document(Constants.KEY_USER_ID, userId)
+                .append(Constants.KEY_ACCESS_TOKEN, accessToken)
+                .append(Constants.KEY_REFRESH_TOKEN, refreshToken)
+                .append(Constants.KEY_ISSUED_TIME, issuedTime);
 
         return doc;
     }
 
     private Document createDocument(UserDevice userDevice) {
 
-        Document doc = new Document(Constants.USER_ID, userDevice.getUserId())
-                .append(Constants.DEVICE_ID, userDevice.getDeviceId());
+        Document doc = new Document(Constants.KEY_USER_ID,
+                userDevice.getUserId()).append(Constants.KEY_DEVICE_ID,
+                        userDevice.getDeviceId());
 
         return doc;
     }
 
-    private UserSession convertSessionDocToResource(Document doc) {
+    private UserToken convertTokenDocToResource(Document doc) {
+
+        UserToken userToken = new UserToken();
 
-        UserSession userSession = new UserSession();
+        String userId = doc.getString(Constants.KEY_USER_ID);
+        String accessToken = doc.getString(Constants.KEY_ACCESS_TOKEN);
+        String refreshToken = doc.getString(Constants.KEY_REFRESH_TOKEN);
+        String issuedTime = doc.getString(Constants.KEY_ISSUED_TIME);
 
-        userSession.setUserId(doc.getString(Constants.USER_ID));
-        userSession.setSessionCode(doc.getString(Constants.SESSION_CODE));
+        // Logger.d("issuedTime: " + issuedTime);
+        userToken.setUserToken(userId, accessToken, refreshToken);
+        userToken.setIssuedTime(issuedTime);
 
-        return userSession;
+        return userToken;
     }
 
     private UserDevice convertDeviceDocToResource(Document doc) {
 
         UserDevice userDevice = new UserDevice();
 
-        userDevice.setUserId(doc.getString(Constants.USER_ID));
-        userDevice.setDeviceId(doc.getString(Constants.DEVICE_ID));
+        userDevice.setUserId(doc.getString(Constants.KEY_USER_ID));
+        userDevice.setDeviceId(doc.getString(Constants.KEY_DEVICE_ID));
 
         return userDevice;
     }
 
-    private ArrayList<UserSession> readSessionResources() {
+    private ArrayList<UserToken> readUserTokenResources() {
 
-        ArrayList<UserSession> userSessionList = new ArrayList<UserSession>();
+        ArrayList<UserToken> userTokenList = new ArrayList<>();
 
         MongoCollection<Document> collection = db
-                .getCollection(Constants.SESSION_TABLE);
+                .getCollection(Constants.TOKEN_TABLE);
         MongoCursor<Document> cursor = collection.find().iterator();
 
         while (cursor.hasNext()) {
 
             Document doc = cursor.next();
-            userSessionList.add(convertSessionDocToResource(doc));
+            userTokenList.add(convertTokenDocToResource(doc));
         }
 
         cursor.close();
 
-        return userSessionList;
+        return userTokenList;
     }
 
     private ArrayList<UserDevice> readDeviceResources() {
 
-        ArrayList<UserDevice> userDeviceList = new ArrayList<UserDevice>();
+        ArrayList<UserDevice> userDeviceList = new ArrayList<>();
 
         MongoCollection<Document> collection = db
                 .getCollection(Constants.DEVICE_TABLE);
index f42bc7c..b0cc3c6 100644 (file)
@@ -1,23 +1,23 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver.db;
 
@@ -47,4 +47,4 @@ public class UserDevice {
     public String getDeviceId() {
         return this.deviceId;
     }
-}
+}
\ No newline at end of file
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserSession.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserSession.java
deleted file mode 100644 (file)
index 96f6d39..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.db;
-
-/**
- *
- * This class provides a set of APIs storing session information of authorized
- * user.
- *
- */
-public class UserSession {
-
-    private String userId      = null;
-    private String sessionCode = null;
-
-    public void setUserId(String id) {
-        this.userId = id;
-    }
-
-    public void setSessionCode(String code) {
-        this.sessionCode = code;
-    }
-
-    public String getUserId() {
-        return this.userId;
-    }
-
-    public String getSessionCode() {
-        return this.sessionCode;
-    }
-}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserToken.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserToken.java
new file mode 100644 (file)
index 0000000..ef57486
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.db;
+
+/**
+ *
+ * This class provides a set of APIs storing session information of authorized
+ * user.
+ *
+ */
+public class UserToken {
+
+    private String userId       = null;
+    private String accessToken  = null;
+    private String refreshToken = null;
+    private String issuedTime   = null;
+
+    public void setUserToken(String id, String accessToken,
+            String refreshToken) {
+        this.userId = id;
+        this.accessToken = accessToken;
+        this.refreshToken = refreshToken;
+    }
+
+    public void setUserId(String id) {
+        this.userId = id;
+    }
+
+    public void setToken(String accessToken, String refreshToken) {
+        this.accessToken = accessToken;
+        this.refreshToken = refreshToken;
+    }
+
+    public void setIssuedTime(String time) {
+        this.issuedTime = time;
+    }
+
+    public String getUserId() {
+        return this.userId;
+    }
+
+    public String getAccessToken() {
+        return this.accessToken;
+    }
+
+    public String getRefreshToken() {
+        return this.refreshToken;
+    }
+
+    public String getIssuedTime() {
+        return this.issuedTime;
+    }
+}
\ No newline at end of file
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java
deleted file mode 100644 (file)
index 8e00566..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.oauth;
-
-import org.apache.oltu.oauth2.client.OAuthClient;
-import org.apache.oltu.oauth2.client.URLConnectionClient;
-import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
-import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
-import org.apache.oltu.oauth2.client.response.GitHubTokenResponse;
-import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
-import org.apache.oltu.oauth2.common.OAuth;
-import org.apache.oltu.oauth2.common.OAuthProviderType;
-import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
-import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
-import org.apache.oltu.oauth2.common.message.types.GrantType;
-import org.iotivity.cloud.util.JSONUtil;
-import org.iotivity.cloud.util.Logger;
-
-/**
- *
- * This class provides APIs relating authorization for GitHub.
- *
- */
-public class GitHub extends OAuthServer {
-
-    final static private String client_id    = "ea9c18f540323b0213d0";
-    final static private String secret       = "4bc0cd9fe21269507eb8eba3a32664a0f598dbc9";
-    final static private String resource_url = "https://api.github.com/user";
-
-    @Override
-    public String requestAccessToken(String authCode) {
-
-        String accessToken = null;
-
-        try {
-
-            OAuthClientRequest request = OAuthClientRequest
-                    .tokenProvider(OAuthProviderType.GITHUB)
-                    .setGrantType(GrantType.AUTHORIZATION_CODE)
-                    .setClientId(client_id).setClientSecret(secret)
-                    .setCode(authCode).buildBodyMessage();
-
-            OAuthClient oAuthClient = new OAuthClient(
-                    new URLConnectionClient());
-            GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(request,
-                    GitHubTokenResponse.class);
-
-            accessToken = oAuthResponse.getAccessToken();
-
-        } catch (OAuthSystemException | OAuthProblemException e) {
-            e.printStackTrace();
-        }
-
-        return accessToken;
-    }
-
-    @Override
-    public String requestGetUserInfo(String accessToken) {
-
-        String userInfo = null;
-
-        if (accessToken == null) {
-            Logger.w("accessToken is null!");
-            return null;
-        }
-
-        try {
-
-            OAuthClientRequest request = new OAuthBearerClientRequest(
-                    resource_url).setAccessToken(accessToken)
-                    .buildQueryMessage();
-
-            OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
-            
-            OAuthResourceResponse resourceResponse = oAuthClient.resource(
-                    request, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
-
-            userInfo = resourceResponse.getBody();
-            Logger.d("userInfo: " + userInfo);
-
-        } catch (OAuthSystemException | OAuthProblemException e) {
-            e.printStackTrace();
-        }
-
-        String userIdKey = "login";
-        String userId = JSONUtil.parseJSON(userInfo, userIdKey);
-
-        return userId;
-    }
-}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/Github.jar b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/Github.jar
new file mode 100644 (file)
index 0000000..c7b8f8a
Binary files /dev/null and b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/Github.jar differ
index c3c6cc7..3a946ce 100644 (file)
@@ -1,48 +1,56 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.accountserver.oauth;
 
+import java.util.HashMap;
+
 /**
  *
  * This class provides abstraction of APIs relating authorization for OAuth 2.0
  *
  */
-public abstract class OAuthServer {
+public abstract interface OAuthServer {
 
     /**
      * API for requesting access token
      * 
      * @param authCode
      *            authorization code
-     * @return access token
+     * @param authServerUrl
+     *            authorization server url
+     * @return access token and error message if error occur
      */
-    public abstract String requestAccessToken(String authCode);
+    public abstract HashMap<String, String> requestAccessToken(String authCode,
+            String authServerUrl);
 
     /**
      * API for getting user's information
      * 
      * @param accessToken
      *            access token
-     * @return String - user information of json type
+     * @param apiServerUrl
+     *            api server url
+     * @return access token and error message if error occur
      */
-    public abstract String requestGetUserInfo(String accessToken);
+    public abstract HashMap<String, String> requestGetUserInfo(
+            String accessToken, String apiServerUrl);
 }
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/OAuthServerFactory.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/OAuthServerFactory.java
new file mode 100644 (file)
index 0000000..4f4977b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.oauth;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.util.Logger;
+
+/**
+ *
+ * This class provides factory method for OAuth2.0 Servers.
+ *
+ */
+public class OAuthServerFactory {
+
+    private Class<?> authServerClass = null;
+    private Object   authServerObj   = null;
+
+    @SuppressWarnings("unchecked")
+    public String requestAccessToken(String authCode, String authServerUrl) {
+        String accessToken = null;
+        HashMap<String, String> authServerInfo = null;
+
+        try {
+            Method method = authServerClass.getMethod("requestAccessToken",
+                    new Class[] { String.class, String.class });
+            authServerInfo = (HashMap<String, String>) method
+                    .invoke(authServerObj, authCode, authServerUrl);
+            String errorMessage = authServerInfo.get(Constants.ERROR_MESSAGE);
+            if (errorMessage != null) {
+                Logger.d("Exception Error Message from Auth Server : "
+                        + errorMessage);
+            } else {
+                accessToken = authServerInfo.get(Constants.KEY_ACCESS_TOKEN_GH);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return accessToken;
+    }
+
+    @SuppressWarnings("unchecked")
+    public String requestGetUserInfo(String accessToken, String apiServerUrl) {
+        String userId = null;
+        HashMap<String, String> authServerInfo = null;
+
+        try {
+            Method method = authServerClass.getMethod("requestGetUserInfo",
+                    new Class[] { String.class, String.class });
+            authServerInfo = (HashMap<String, String>) method
+                    .invoke(authServerObj, accessToken, apiServerUrl);
+            String errorMessage = authServerInfo.get(Constants.ERROR_MESSAGE);
+            if (errorMessage != null) {
+                Logger.d("Exception Error Message from Auth Server : "
+                        + errorMessage);
+            } else {
+                userId = authServerInfo.get(Constants.KEY_USER_ID);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return userId;
+    }
+
+    /**
+     * API for creating OAuth server object
+     * 
+     * @param authServer
+     *            authorization server
+     * @return OAuthServer - object to handle authorization
+     * @throws Exception
+     */
+    public boolean create(String authServer) {
+
+        // TODO : 3rd-party provider check logic required
+        String authServerName = checkAuthServerName(authServer);
+        String fileName = authServerName + ".jar";
+        File jarFile = new File(fileName);
+        URLClassLoader classLoader = null;
+
+        try {
+            URL urls = new URL("jar:" + jarFile.toURI() + "!/");
+
+            Logger.d("urls: " + urls.toString());
+
+            classLoader = new URLClassLoader(new URL[] { urls });
+            Class<?> gitHubClass = classLoader
+                    .loadClass(this.getClass().getPackage().getName() + "."
+                            + authServerName);
+
+            authServerClass = gitHubClass;
+            Object object = gitHubClass.newInstance();
+            authServerObj = object;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+
+        } finally {
+            try {
+                classLoader.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        return true;
+    }
+
+    private String checkAuthServerName(String authServer) {
+
+        String authServerName = null;
+
+        if (authServer.equalsIgnoreCase(Constants.GITHUB)) {
+            authServerName = Constants.GITHUB;
+        } else if (authServer.equalsIgnoreCase(Constants.SAMSUNG)) {
+            authServerName = Constants.SAMSUNG;
+        }
+
+        return authServerName;
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java
deleted file mode 100644 (file)
index 72f9226..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.resources;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.iotivity.cloud.accountserver.AccountServerManager;
-import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.util.CoapMessageBuilder;
-import org.iotivity.cloud.base.Resource;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.iotivity.cloud.util.JSONUtil;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelHandlerContext;
-
-/**
- *
- * This class provides a set of APIs to manage resources corresponding with user
- * account
- *
- */
-public class AccountResource extends Resource {
-
-    public AccountResource() {
-        setUri(Constants.ACCOUNT_URI);
-    }
-
-    @Override
-    public void onRequestReceived(ChannelHandlerContext ctx,
-            CoapRequest request) {
-
-        Logger.d("AccountResource IN");
-
-        if (ctx == null || request == null) {
-            Logger.d("ctx or request msg is null");
-        }
-
-        else {
-            CoapMethod method = request.getRequestMethod();
-
-            switch (method) {
-                case GET:
-                    try {
-                        handleGetRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-
-                case POST:
-                    try {
-                        handlePostRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-
-                default:
-                    Logger.w("method[" + method + "] is not supported");
-                    break;
-            }
-        }
-    }
-
-    private void handleGetRequest(ChannelHandlerContext ctx,
-            CoapRequest request) throws Exception {
-
-        String reqType = extractQuery(request, Constants.REQ_TYPE);
-
-        if (reqType == null)
-            throw new IllegalArgumentException(
-                    "request type is null in query!");
-
-        CoapResponse response = null;
-
-        switch (reqType) {
-            case Constants.TYPE_FIND:
-                response = handleFindRequest(request);
-                break;
-            default:
-                Logger.w("reqType[" + reqType + "] is not supported");
-        }
-        if (response != null) {
-            ctx.writeAndFlush(response);
-        }
-
-    }
-
-    private void handlePostRequest(ChannelHandlerContext ctx,
-            CoapRequest request) throws Exception {
-
-        String reqType = extractQuery(request, Constants.REQ_TYPE);
-
-        if (reqType == null)
-            throw new IllegalArgumentException(
-                    "request type is null in query!");
-
-        CoapResponse response;
-
-        switch (reqType) {
-            case Constants.TYPE_PUBLISH:
-                response = handlePublishRequest(request);
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "request type is not supported");
-        }
-
-        ctx.writeAndFlush(response);
-    }
-
-    /**
-     * API for handling request for publishing resource corresponding with user
-     * account
-     *
-     * @param requeset
-     *            CoAP request message
-     * @return CoapResponse - CoAP response message with response result
-     *         information
-     */
-    private CoapResponse handlePublishRequest(CoapRequest request) {
-
-        String payload = request.getPayloadString();
-
-        String userId = JSONUtil.parseJSON(payload, Constants.REQUEST_USER_ID);
-        String deviceId = JSONUtil.parseJSON(payload,
-                Constants.REQUEST_DEVICE_ID);
-
-        Logger.d("userId: " + userId + ", deviceId: " + deviceId);
-
-        AccountServerManager oauthServerManager = new AccountServerManager();
-        Boolean status = oauthServerManager.registerUserAccount(userId,
-                deviceId);
-
-        Logger.d("status : " + status);
-
-        CoapMessageBuilder responseMessage = new CoapMessageBuilder();
-        CoapResponse coapResponse;
-
-        if (status) {
-            coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                    CoapStatus.CREATED);
-        } else {
-            coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                    CoapStatus.INTERNAL_SERVER_ERROR);
-        }
-
-        return coapResponse;
-    }
-
-    /**
-     * API for handling request for finding resource corresponding with user
-     * account
-     *
-     * @param requeset
-     *            CoAP request message
-     * @return CoapResponse - CoAP response message with response result
-     *         information
-     */
-    private CoapResponse handleFindRequest(CoapRequest request) {
-
-        String payload = request.getPayloadString();
-        // String payload = getPayloadString(request.getPayload());
-
-        JSONUtil util = new JSONUtil();
-        String userId = util.parseJSON(payload, Constants.REQUEST_USER_ID);
-
-        Logger.d("userId: " + userId);
-
-        AccountServerManager oauthServerManager = new AccountServerManager();
-        ArrayList<String> deviceList = oauthServerManager
-                .requestAccountDevices(userId);
-
-        ResponseObject response = new ResponseObject();
-        response.setDeviceList(deviceList);
-
-        String responseJson = convertFindResponseToJson(response);
-        Logger.d("responseJson: " + responseJson);
-
-        CoapMessageBuilder responseMessage = new CoapMessageBuilder();
-        CoapResponse coapResponse = responseMessage.buildCoapResponse(
-                request.getToken(), responseJson, CoapStatus.CONTENT);
-
-        return coapResponse;
-    }
-
-    private String convertFindResponseToJson(ResponseObject response) {
-
-        HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
-
-        ArrayList<String> deviceList = response.getDeviceList();
-        responseMap.put(Constants.RESPONSE_DEVICES, deviceList);
-
-        String responseJson = JSONUtil.writeJSON(responseMap);
-
-        return responseJson;
-    }
-
-    private String extractQuery(CoapRequest request, String key) {
-
-        String value = null;
-
-        List<String> Segments = request.getUriQuerySegments();
-
-        if (Segments != null) {
-            for (String s : Segments) {
-
-                String pair[] = s.split("=");
-
-                if (pair[0].equals(key)) {
-
-                    value = pair[1];
-                }
-            }
-        }
-
-        return value;
-    }
-
-    /*
-     * private static String getPayloadString(byte[] payload) {
-     *
-     * if (payload == null) return "";
-     *
-     * return new String(payload, Charset.forName("UTF-8")); }
-     */
-
-}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java
deleted file mode 100644 (file)
index 71448e4..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.resources;
-
-import java.util.HashMap;
-import java.util.List;
-
-import org.iotivity.cloud.accountserver.AccountServerManager;
-import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.util.CoapMessageBuilder;
-import org.iotivity.cloud.base.Resource;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.iotivity.cloud.util.JSONUtil;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelHandlerContext;
-
-/**
- *
- * This class provides a set of APIs to manage user account with authorization
- * process.
- *
- */
-public class AuthResource extends Resource {
-
-    public AuthResource() {
-        setUri(Constants.AUTH_URI);
-    }
-
-    @Override
-    public void onRequestReceived(ChannelHandlerContext ctx,
-            CoapRequest request) {
-
-        Logger.d("AuthResource IN");
-
-        if (ctx == null || request == null) {
-            Logger.d("ctx or request msg is null");
-        }
-
-        else {
-            CoapMethod method = request.getRequestMethod();
-
-            switch (method) {
-                case POST:
-                    try {
-                        handlePostRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-
-                default:
-                    Logger.w("method(" + method + ") is not supported");
-                    break;
-            }
-        }
-    }
-
-    private void handlePostRequest(ChannelHandlerContext ctx,
-            CoapRequest request) throws Exception {
-
-        String reqType = extractQuery(request, Constants.REQ_TYPE);
-
-        if (reqType == null)
-            throw new IllegalArgumentException(
-                    "request type is null in query!");
-
-        CoapResponse response;
-
-        switch (reqType) {
-            case Constants.TYPE_REGISTER:
-                response = handleRegisterRequest(request);
-                break;
-            case Constants.TYPE_LOGIN:
-                response = handleLoginRequest(request);
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "request type is not supported");
-        }
-
-        ctx.writeAndFlush(response);
-    }
-
-    /**
-     * API for handling request for login by user account
-     *
-     * @param request
-     *            CoAP request message
-     * @return CoapResponse - CoAP response message with response result
-     *         information
-     */
-    private CoapResponse handleLoginRequest(CoapRequest request) {
-
-        String payload = request.getPayloadString();
-
-        String sessionCode = JSONUtil.parseJSON(payload,
-                Constants.REQUEST_SESSION_CODE);
-
-        Logger.d("sessionCode: " + sessionCode);
-
-        AccountServerManager oauthServerManager = new AccountServerManager();
-        String userId = oauthServerManager.requestUserId(sessionCode);
-        Logger.d("userId: " + userId);
-
-        CoapMessageBuilder responseMessage = new CoapMessageBuilder();
-        CoapResponse coapResponse;
-
-        if (userId != null) {
-
-            ResponseObject response = new ResponseObject();
-            response.setUserId(userId);
-
-            String responseJson = convertLoginResponseToJson(response);
-            Logger.d("responseJson: " + responseJson);
-
-            coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                    responseJson, CoapStatus.CREATED);
-
-        } else {
-
-            coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                    CoapStatus.INTERNAL_SERVER_ERROR);
-
-        }
-
-        return coapResponse;
-    }
-
-    /**
-     * API for handling request for registering user account
-     *
-     * @param request
-     *            CoAP request message
-     * @return CoapResponse - CoAP response message with response result
-     *         information
-     */
-    private CoapResponse handleRegisterRequest(CoapRequest request) {
-
-        String payload = request.getPayloadString();
-
-        String authCode = JSONUtil.parseJSON(payload,
-                Constants.REQUEST_AUTH_CODE);
-        String authServer = JSONUtil.parseJSON(payload,
-                Constants.REQUEST_AUTH_SERVER);
-
-        Logger.d("authCode: " + authCode + ", authServer: " + authServer);
-
-        AccountServerManager oauthServerManager = new AccountServerManager();
-        String userId = null;
-        if (authCode != null && authServer != null) {
-            userId = oauthServerManager.requestUserId(authCode, authServer);
-        }
-        
-        CoapMessageBuilder responseMessage = new CoapMessageBuilder();
-        CoapResponse coapResponse;
-
-        if (userId != null) {
-            
-            String sessionCode = oauthServerManager.registerUserAccount(userId);
-
-            Logger.d("userId: " + userId + ", sessionCode: " + sessionCode);
-
-            if (sessionCode != null) {
-
-                ResponseObject response = new ResponseObject();
-                response.setSessionCode(sessionCode);
-                response.setUserId(userId);
-
-                String responseJson = convertRegisterResponseToJson(response);
-                Logger.d("responseJson: " + responseJson);
-
-                coapResponse = responseMessage.buildCoapResponse(
-                        request.getToken(), responseJson, CoapStatus.CREATED);
-            }
-            else  {
-                coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                        CoapStatus.UNAUTHORIZED);                
-            }
-
-        } else {
-
-            coapResponse = responseMessage.buildCoapResponse(request.getToken(),
-                    CoapStatus.UNAUTHORIZED);
-        }
-
-        return coapResponse;
-    }
-
-    private String convertRegisterResponseToJson(ResponseObject response) {
-
-        HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
-
-        String sessionCode = response.getSessionCode();
-        String userId = response.getUserId();
-
-        if (userId != null)
-            responseMap.put(Constants.RESPONSE_USER_ID, userId);
-
-        if (sessionCode != null)
-            responseMap.put(Constants.RESPONSE_SESSION_CODE, sessionCode);
-
-        String responseJson = JSONUtil.writeJSON(responseMap);
-
-        return responseJson;
-    }
-
-    private String convertLoginResponseToJson(ResponseObject response) {
-
-        HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
-
-        String userId = response.getUserId();
-
-        if (userId != null)
-            responseMap.put(Constants.RESPONSE_USER_ID, userId);
-
-        String responseJson = JSONUtil.writeJSON(responseMap);
-
-        return responseJson;
-    }
-
-    private String extractQuery(CoapRequest request, String key) {
-
-        String value = null;
-
-        List<String> Segments = request.getUriQuerySegments();
-
-        if (Segments != null) {
-            for (String s : Segments) {
-
-                String pair[] = s.split("=");
-
-                if (pair[0].equals(key)) {
-
-                    value = pair[1];
-                }
-            }
-        }
-
-        return value;
-    }
-
-    /*
-     * private static String getPayloadString(byte[] payload) {
-     *
-     * if (payload == null) return "";
-     *
-     * return new String(payload, Charset.forName("UTF-8")); }
-     */
-
-}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/ResponseObject.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/ResponseObject.java
deleted file mode 100644 (file)
index 4871641..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.resources;
-
-import java.util.ArrayList;
-
-/**
- * 
- * This class provides a set of APIs to manage data for response according to
- * request.
- * 
- */
-public class ResponseObject {
-    // private String channel = null;
-    private String            sessionCode = null;
-    private String            userId      = null;
-    private ArrayList<String> deviceList  = null;
-
-    ResponseObject() {
-        deviceList = new ArrayList<String>();
-    }
-
-    public String getUserId() {
-        return this.userId;
-    }
-
-    public void setUserId(String id) {
-        this.userId = id;
-    }
-
-    public String getSessionCode() {
-        return this.sessionCode;
-    }
-
-    public void setSessionCode(String code) {
-        this.sessionCode = code;
-    }
-
-    public void setDeviceList(ArrayList<String> list) {
-        this.deviceList = list;
-    }
-
-    public ArrayList<String> getDeviceList() {
-        return this.deviceList;
-    }
-}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountResource.java
new file mode 100644 (file)
index 0000000..88d7846
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.resources.account;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.accountserver.AccountServerManager;
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.token.Token;
+import org.iotivity.cloud.accountserver.token.TokenPolicy;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Logger;
+
+/**
+ *
+ * This class provides a set of APIs to manage resources corresponding with user
+ * account
+ *
+ */
+public class AccountResource extends Resource {
+
+    private Cbor<HashMap<String, Object>> mCbor      = new Cbor<>();
+
+    private AccountServerManager          mAsManager = new AccountServerManager();
+
+    public AccountResource() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.ACCOUNT_URI));
+
+        // addQueryHandler(Arrays.asList("if=" + Constants.INTERFACE_DEFAULT),
+        // this::onDefaultInterfaceReceived);
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+
+            case POST:
+                // Used for user sign-up
+                response = handlePostSignUp(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handlePostSignUp(IRequest request)
+            throws ServerException {
+
+        if (request.getPayload() == null) {
+            throw new BadRequestException("payload is null");
+        }
+
+        HashMap<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+
+        exceptionPayloadCheck(payloadData);
+
+        String deviceId = payloadData.get(Constants.REQ_DEVICE_ID).toString();
+        String authCode = payloadData.get(Constants.REQ_AUTH_CODE).toString();
+        String authProvider = payloadData.get(Constants.REQ_AUTH_PROVIDER)
+                .toString();
+
+        Logger.d("authCode: " + authCode);
+
+        @SuppressWarnings("unchecked")
+        HashMap<String, String> options = (HashMap<String, String>) payloadData
+                .get(Constants.REQ_AUTH_OPTIONS);
+
+        String authServerUrl = null;
+        String apiServerUrl = null;
+
+        if (options != null) {
+            authServerUrl = (String) options.get(Constants.REQ_AUTH_SERVER_URL);
+            apiServerUrl = (String) options.get(Constants.REQ_API_SERVER_URL);
+        }
+
+        boolean res = false;
+
+        res = mAsManager.loadAuthServer(authProvider);
+
+        if (!res) {
+            throw new InternalServerErrorException(
+                    authProvider + " library is not loaded");
+        }
+
+        String userId = mAsManager.requestUserId(authCode, authProvider,
+                authServerUrl, apiServerUrl);
+
+        if (userId == null) {
+            throw new BadRequestException("authCode is invalid");
+        }
+
+        Token token = new Token();
+        token = mAsManager.registerUserAccount(userId);
+
+        String accessToken = token.getAccessToken();
+        String refreshToken = token.getRefreshToken();
+
+        if (accessToken == null || refreshToken == null) {
+            throw new InternalServerErrorException("MongoDB is not operating");
+        }
+
+        HashMap<String, Object> responsePayload = null;
+
+        responsePayload = new HashMap<String, Object>();
+
+        responsePayload.put(Constants.RESP_ACCESS_TOKEN, accessToken);
+        responsePayload.put(Constants.RESP_REFRESH_TOKEN, refreshToken);
+        responsePayload.put(Constants.RESP_TOKEN_TYPE,
+                TokenPolicy.BEARER_TOKEN);
+        responsePayload.put(Constants.RESP_EXPIRES_IN, TokenPolicy.EXPIRES_IN);
+        responsePayload.put(Constants.RESP_USER_ID, userId);
+
+        res = mAsManager.registerUserAccount(userId, deviceId);
+
+        if (!res) {
+            throw new InternalServerErrorException("MongoDB is not operating");
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CREATED,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(responsePayload));
+    }
+
+    private void exceptionPayloadCheck(HashMap<String, Object> payloadData)
+            throws ServerException {
+        if (payloadData == null) {
+            throw new BadRequestException("payload is null");
+        }
+
+        // check if mandatory properties exist
+        if (!payloadData.containsKey(Constants.REQ_DEVICE_ID)) {
+            throw new PreconditionFailedException("di property is not include");
+        }
+
+        if (!payloadData.containsKey(Constants.REQ_AUTH_CODE)) {
+            throw new PreconditionFailedException(
+                    "authcode property is not include");
+        }
+
+        if (!payloadData.containsKey(Constants.REQ_AUTH_PROVIDER)) {
+            throw new PreconditionFailedException(
+                    "authprovider property is not include");
+        }
+
+        // check if mandatory properties have null values
+        if (payloadData.get(Constants.REQ_DEVICE_ID) == null) {
+            throw new PreconditionFailedException("di param is null");
+        }
+
+        if (payloadData.get(Constants.REQ_AUTH_CODE) == null) {
+            throw new PreconditionFailedException("authcode param is null");
+        }
+
+        if (payloadData.get(Constants.REQ_AUTH_PROVIDER) == null) {
+            throw new PreconditionFailedException("authprovider param is null");
+        }
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/device/DeviceResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/device/DeviceResource.java
new file mode 100644 (file)
index 0000000..8d5a600
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.resources.account.device;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.accountserver.AccountServerManager;
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.token.TokenManager;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.util.Cbor;
+
+public class DeviceResource extends Resource {
+
+    private Cbor<HashMap<String, Object>> mCbor         = new Cbor<>();
+
+    TokenManager                          mTokenManager = new TokenManager();
+
+    private AccountServerManager          mAsManager    = new AccountServerManager();
+
+    public DeviceResource() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.ACCOUNT_URI, Constants.DEVICE_URI));
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case GET:
+                // Used for getting devices.
+                response = handleGetDevice(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
+        }
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handleGetDevice(IRequest request) throws ServerException {
+
+        String accessToken = request.getUriQueryMap().get("accesstoken").get(0);
+
+        if (accessToken == null) {
+            throw new BadRequestException("AccessToken is empty");
+        }
+
+        Boolean res = false;
+
+        res = mTokenManager.verifyAccessToken(accessToken);
+
+        if (!res) {
+            throw new UnAuthorizedException("AccessToken is unauthorized");
+        }
+
+        String userId = mAsManager.requestUserId(accessToken);
+
+        if (userId == null) {
+            throw new BadRequestException("userid is invalid");
+        }
+
+        ArrayList<String> deviceList = mAsManager.requestAccountDevices(userId);
+
+        if (request.getUriQueryMap().get("di") != null) {
+            String di = request.getUriQueryMap().get("di").get(0);
+            if (deviceList.contains(di)) {
+                return MessageBuilder.createResponse(request,
+                        ResponseStatus.VALID);
+            } else {
+                throw new UnAuthorizedException("di is invalid");
+            }
+        } else {
+            HashMap<String, Object> responsePayload = new HashMap<String, Object>();
+            responsePayload.put(Constants.RESP_DEVICES, deviceList);
+
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.CONTENT, ContentFormat.APPLICATION_CBOR,
+                    mCbor.encodingPayloadToCbor(responsePayload));
+        }
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/session/SessionResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/session/SessionResource.java
new file mode 100644 (file)
index 0000000..e53b664
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.resources.account.session;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.token.TokenManager;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.util.Cbor;
+
+public class SessionResource extends Resource {
+
+    private Cbor<HashMap<String, Object>> mCbor         = new Cbor<>();
+
+    TokenManager                          mTokenManager = new TokenManager();
+
+    public SessionResource() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.ACCOUNT_URI, Constants.SESSION_URI));
+
+        // addQueryHandler(Arrays.asList("if=" + Constants.INTERFACE_DEFAULT),
+        // this::onDefaultInterfaceReceived);
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case POST:
+                // Used for user sign-in & out
+                response = handlePostSigninout(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handlePostSigninout(IRequest request)
+            throws ServerException {
+
+        // exception handle before getting payload
+        if (request.getPayload() == null) {
+            throw new BadRequestException("payload is empty");
+        }
+
+        HashMap<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+
+        if (payloadData == null) {
+            throw new BadRequestException("CBOR parsing failed");
+        }
+
+        // String deviceId =
+        // payloadData.get(Constants.REQUEST_DEVICE_ID).toString();
+        String accessToken = payloadData.get(Constants.REQ_ACCESS_TOKEN)
+                .toString();
+        boolean signinRequest = (boolean) payloadData.get(Constants.REQ_STATUS);
+
+        Boolean res = false;
+
+        res = mTokenManager.verifyAccessToken(accessToken);
+
+        if (!res) {
+            throw new UnAuthorizedException("AccessToken is unauthorized");
+        }
+
+        if (!signinRequest) {
+            return MessageBuilder.createResponse(request, ResponseStatus.VALID);
+        }
+
+        HashMap<String, Object> responsePayload = null;
+
+        responsePayload = new HashMap<String, Object>();
+
+        responsePayload.put(Constants.RESP_EXPIRES_IN,
+                mTokenManager.getRemainExpiredTime(accessToken));
+
+        return MessageBuilder.createResponse(request, ResponseStatus.VALID,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(responsePayload));
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/tokenrefresh/TokenRefreshResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/tokenrefresh/TokenRefreshResource.java
new file mode 100644 (file)
index 0000000..b573a60
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.resources.account.tokenrefresh;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.token.Token;
+import org.iotivity.cloud.accountserver.token.TokenManager;
+import org.iotivity.cloud.accountserver.token.TokenPolicy;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.util.Cbor;
+
+public class TokenRefreshResource extends Resource {
+
+    private Cbor<HashMap<String, Object>> mCbor         = new Cbor<>();
+
+    TokenManager                          mTokenManager = new TokenManager();
+
+    public TokenRefreshResource() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.ACCOUNT_URI, Constants.TOKEN_REFRESH_URI));
+
+        // addQueryHandler(Arrays.asList("if=" + Constants.INTERFACE_DEFAULT),
+        // this::onDefaultInterfaceReceived);
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case POST:
+                // Used for token refresh
+                response = handlePostRefreshToken(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handlePostRefreshToken(IRequest request)
+            throws ServerException {
+
+        HashMap<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+
+        if (payloadData == null) {
+            throw new BadRequestException("payload is null");
+        }
+
+        // String deviceId =
+        // payloadData.get(Constants.REQUEST_DEVICE_ID).toString();
+        String refreshToken = payloadData.get(Constants.REQ_REFRESH_TOKEN)
+                .toString();
+
+        Boolean res = false;
+
+        res = mTokenManager.verifyRefreshToken(refreshToken);
+
+        if (!res) {
+            throw new UnAuthorizedException("RefreshToken is unauthorized");
+        }
+
+        Token refreshedToken = mTokenManager.refreshToken(refreshToken);
+
+        if (refreshedToken.getAccessToken() == null
+                || refreshedToken.getRefreshToken() == null) {
+            throw new InternalServerErrorException("MongoDB is not operating");
+        }
+
+        HashMap<String, Object> responsePayload = null;
+
+        responsePayload = new HashMap<String, Object>();
+
+        responsePayload.put(Constants.RESP_ACCESS_TOKEN,
+                refreshedToken.getAccessToken());
+        responsePayload.put(Constants.RESP_REFRESH_TOKEN,
+                refreshedToken.getRefreshToken());
+        responsePayload.put(Constants.RESP_TOKEN_TYPE,
+                TokenPolicy.BEARER_TOKEN);
+        responsePayload.put(Constants.RESP_EXPIRES_IN, TokenPolicy.EXPIRES_IN);
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(responsePayload));
+
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/Token.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/Token.java
new file mode 100644 (file)
index 0000000..b837423
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.token;
+
+public class Token {
+
+    private String accessToken;
+    private String refreshToken;
+
+    public void setToken(String accessToken, String refreshToken) {
+
+        this.accessToken = accessToken;
+        this.refreshToken = refreshToken;
+    }
+
+    public String getAccessToken() {
+
+        return accessToken;
+    }
+
+    public String getRefreshToken() {
+
+        return refreshToken;
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenGenerator.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenGenerator.java
new file mode 100644 (file)
index 0000000..dcea465
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.token;
+
+import org.apache.oltu.oauth2.as.issuer.MD5Generator;
+import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
+import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.iotivity.cloud.util.Logger;
+
+public class TokenGenerator {
+
+    String generateAccessToken() {
+
+        OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
+
+        String accessToken = null;
+
+        try {
+
+            accessToken = oauthIssuerImpl.accessToken();
+            Logger.d("accessToken : " + accessToken);
+
+        } catch (OAuthSystemException e) {
+
+            e.printStackTrace();
+        }
+
+        return accessToken;
+    }
+
+    String generateRefreshToken() {
+
+        OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
+
+        String refreshToken = null;
+
+        try {
+
+            refreshToken = oauthIssuerImpl.refreshToken();
+            Logger.d("refreshToken : " + refreshToken);
+
+        } catch (OAuthSystemException e) {
+
+            e.printStackTrace();
+        }
+
+        return refreshToken;
+    }
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenManager.java
new file mode 100644 (file)
index 0000000..3a1676b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.token;
+
+import org.iotivity.cloud.accountserver.db.AccountDBManager;
+import org.iotivity.cloud.util.Logger;
+
+public class TokenManager {
+
+    private TokenGenerator tokenGenerator;
+    private TokenValidator tokenValidator;
+
+    public TokenManager() {
+        tokenGenerator = new TokenGenerator();
+        tokenValidator = new TokenValidator();
+    }
+
+    public Token generateToken() {
+
+        String accessToken = tokenGenerator.generateAccessToken();
+        String refreshToken = tokenGenerator.generateRefreshToken();
+
+        Token token = new Token();
+        token.setToken(accessToken, refreshToken);
+
+        return token;
+    }
+
+    public Boolean verifyAccessToken(String token) {
+
+        return tokenValidator.verifyAccessToken(token);
+    }
+
+    public Boolean verifyRefreshToken(String token) {
+
+        return tokenValidator.verifyRefreshToken(token);
+    }
+
+    public long getRemainExpiredTime(String token) {
+
+        return tokenValidator.getRemainedSeconds(token);
+    }
+
+    public Token refreshToken(String token) {
+
+        String userId = null;
+
+        Token refreshedToken = new Token();
+
+        Boolean verifyRefreshToken = false;
+        verifyRefreshToken = tokenValidator.verifyRefreshToken(token);
+
+        if (!verifyRefreshToken) {
+            Logger.w("RefreshToken is not existed!");
+            return null;
+        }
+
+        refreshedToken = generateToken();
+
+        userId = AccountDBManager.getInstance().getUserIdByRefreshToken(token);
+
+        AccountDBManager.getInstance().updateUserToken(userId, token,
+                refreshedToken.getAccessToken(),
+                refreshedToken.getRefreshToken());
+
+        return refreshedToken;
+    }
+
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenPolicy.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenPolicy.java
new file mode 100644 (file)
index 0000000..572bf4d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.token;
+
+public class TokenPolicy {
+
+    /* token type */
+    public final static String BEARER_TOKEN = "bearer";
+
+    /* expired time for accessToken */
+    public final static int    EXPIRES_IN = 3600;    // 1hour
+
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenValidator.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/token/TokenValidator.java
new file mode 100644 (file)
index 0000000..fcc12f7
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.token;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.iotivity.cloud.accountserver.db.AccountDBManager;
+import org.iotivity.cloud.util.Logger;
+
+public class TokenValidator {
+
+    Boolean verifyAccessToken(String token) {
+
+        Boolean valid = false;
+
+        // check token existed
+        valid = AccountDBManager.getInstance().hasAccessToken(token);
+        if (!valid) {
+            Logger.w("accessToken is not existed..");
+            return false;
+        }
+
+        // check token expired
+        if (getElaspedSeconds(token) > TokenPolicy.EXPIRES_IN) {
+
+            Logger.w("accessToken is expired..");
+            return false;
+        }
+
+        return true;
+    }
+
+    public long getElaspedSeconds(String token) {
+
+        String time = AccountDBManager.getInstance().getIssuedTime(token);
+
+        DateFormat format = new SimpleDateFormat("yyyyMMddkkmm");
+        Date currentTime = new Date();
+        Date issuedTime = null;
+
+        try {
+            issuedTime = format.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        long difference = currentTime.getTime() - issuedTime.getTime();
+        long elaspedSeconds = difference / 1000;
+        // Logger.d("currentTime : " + currentTime.getTime());
+        // Logger.d("issuedTime : " + issuedTime.getTime());
+        // Logger.d("difference : " + difference);
+        Logger.d("accessToken elasped time: " + elaspedSeconds + "s");
+
+        return elaspedSeconds;
+    }
+
+    public long getRemainedSeconds(String token) {
+        return TokenPolicy.EXPIRES_IN - getElaspedSeconds(token);
+    }
+
+    Boolean verifyRefreshToken(String token) {
+
+        Boolean valid = false;
+        // check token existed
+        valid = AccountDBManager.getInstance().hasRefreshToken(token);
+        if (!valid)
+            Logger.w("refreshToken is not existed..");
+
+        return valid;
+    }
+
+}
diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java
deleted file mode 100644 (file)
index 30029dc..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.util;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapOption;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-
-/**
- * 
- * This class provides a set of APIs to build build data of CoAP request and
- * response type.
- * 
- */
-public class CoapMessageBuilder {
-
-    public static final int APPLICATION_JSON = 50;
-
-    /**
-     * API for building data of CoAP response type without payload.
-     * 
-     * @param token
-     *            token
-     * @param status
-     *            response status
-     * @return CoapResponse - data of CoAP response type
-     */
-    public CoapResponse buildCoapResponse(byte[] token, CoapStatus status) {
-
-        return buildCoapResponse(token, null, status);
-    }
-
-    /**
-     * API for building data of CoAP response type with payload.
-     * 
-     * @param token
-     *            token
-     * @param jsonString
-     *            payload data
-     * @param status
-     *            response status
-     * @return CoapResponse - data of CoAP response type
-     */
-    public CoapResponse buildCoapResponse(byte[] token, String jsonString,
-            CoapStatus status) {
-
-        CoapResponse coapResponse = new CoapResponse(status);
-
-        coapResponse.setToken(token);
-
-        byte[] bytes = ByteBuffer.allocate(4)
-                .putInt(CoapMessageBuilder.APPLICATION_JSON).array();
-        coapResponse.addOption(CoapOption.CONTENT_FORMAT.getvalue(), bytes);
-
-        if (jsonString != null)
-            coapResponse
-                    .setPayload(jsonString.getBytes(StandardCharsets.UTF_8));
-
-        return coapResponse;
-    }
-
-    /**
-     * API for building data of CoAP requeset type with payload.
-     * 
-     * @param token
-     *            token
-     * @param jsonString
-     *            payload data
-     * @return CoapRequest - data of CoAP request type
-     */
-    public CoapRequest buildCoapRequest(byte[] token, String jsonString) {
-
-        CoapRequest coapRequest = new CoapRequest(CoapMethod.GET);
-
-        coapRequest.setToken(token);
-
-        byte[] bytes = ByteBuffer.allocate(4)
-                .putInt(CoapMessageBuilder.APPLICATION_JSON).array();
-        coapRequest.addOption(CoapOption.CONTENT_FORMAT.getvalue(), bytes);
-
-        coapRequest.setPayload(jsonString.getBytes(StandardCharsets.UTF_8));
-
-        return coapRequest;
-    }
-
-    /*
-     * 
-     * public String getJsonAuthServerResponse() {
-     * 
-     * return "{ \"" + OAuthConstant.AUTH_SERVER + "\" : \"" +
-     * OAuthConstant.AUTH_SERVER_GITHUB + "\" }"; }
-     * 
-     * public String getJsonAuthInfoResponse() {
-     * 
-     * return "\n{\n" + " \"" + OAuthConstant.AUTH_ADDRESS + "\" : \"" +
-     * OAuthConstant.GITHUB_ADDRESS + "\",\n" + " \"" +
-     * OAuthConstant.AUTH_RESPONSE_TYPE + "\" : \"" +
-     * OAuthConstant.AUTH_CODE_VALUE + "\",\n" + " \"" +
-     * OAuthConstant.AUTH_CLIENT_ID + "\" : \"" + OAuthConstant.GITHUB_CLIENT_ID
-     * + "\",\n" + " \"" + OAuthConstant.AUTH_REDIRECT_URI + "\" : \"" +
-     * OAuthConstant.GITHUB_REDIRECT_URL + "\"" + "\n}"; }
-     * 
-     * public String getJsonAuthQueryRequest(String auth_server, String
-     * auth_code, String auth_di) {
-     * 
-     * return "\n{\n" + " \"" + OAuthConstant.AUTH_TYPE + "\" : \"" +
-     * OAuthConstant.AUTH_TYPE_QUERY + "\",\n" + " \"" +
-     * OAuthConstant.AUTH_SERVER + "\" : \"" + auth_server + "\",\n" + " \"" +
-     * OAuthConstant.AUTH_CODE + "\" : \"" + auth_code + "\",\n" + " \"" +
-     * OAuthConstant.AUTH_DEVICE_ID + "\" : \"" + auth_di + "\"" + "\n}"; }
-     */
-}
diff --git a/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java b/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java
deleted file mode 100644 (file)
index aebada9..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-package org.iotivity.cloud.testaccountserver;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-
-import org.junit.Test;
-import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.resources.AccountResource;
-import org.iotivity.cloud.accountserver.resources.AuthResource;
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.util.JSONUtil;
-
-public class TestAccountServer {
-
-    private AuthResource    authResource    = new AuthResource();
-    private AccountResource accountResource = new AccountResource();
-
-    private CoapServer      coapServer      = null;
-    private CoapClient      coapClient      = null;
-    private static String   sessionCode     = null;
-
-    static class CoapClientHandler extends
-            SimpleChannelInboundHandler<CoapResponse> {
-
-        ChannelHandlerContext connectCtx = null;
-
-        @Override
-        public void channelActive(ChannelHandlerContext ctx) throws Exception {
-            connectCtx = ctx;
-        }
-
-        @Override
-        protected void channelRead0(ChannelHandlerContext arg0,
-                CoapResponse arg1) throws Exception {
-
-            if (arg1.getTokenString().equals("1111")) {
-
-                String json = arg1.getPayloadString();
-
-                sessionCode = JSONUtil.parseJSON(json, "session");
-            }
-
-        }
-    }
-
-    public void startServer() throws Exception {
-
-        coapServer = new CoapServer();
-
-        ResourceManager resourceManager = new ResourceManager();
-        coapServer.addHandler(resourceManager);
-
-        resourceManager.registerResource(new AuthResource());
-        resourceManager.registerResource(new AccountResource());
-
-        coapServer.startServer(new InetSocketAddress(5685));
-    }
-
-    public ChannelHandlerContext startClient() throws Exception {
-
-        coapClient = new CoapClient();
-
-        CoapClientHandler coapHandler = new CoapClientHandler();
-        coapClient.addHandler(coapHandler);
-
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5685));
-
-        return coapHandler.connectCtx;
-    }
-
-    @Test
-    public void testHandleRegisterRequest() throws Exception {
-
-        System.out.println("Write your authCode before test by following url.");
-        System.out
-                .println("https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F");
-
-        String authCode = "7243699de9726d05e74c"; // write your authCode here.
-        String authServer = "github";
-
-        String json = "{\"authcode\":\"" + authCode + "\",\"authprovider\":\""
-                + authServer + "\"}";
-
-        CoapRequest request = new CoapRequest(CoapMethod.POST);
-        request.setUriPath(Constants.AUTH_URI);
-        request.setUriQuery("reqtype=register");
-        request.setToken("1111".getBytes(StandardCharsets.UTF_8));
-        request.setPayload(json.getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-        authResource.onRequestReceived(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandlerLoginReqeust() throws Exception {
-
-        String json = "{\"session\":\"" + sessionCode + "\"}";
-
-        CoapRequest request = new CoapRequest(CoapMethod.POST);
-        request.setUriPath(Constants.AUTH_URI);
-        request.setUriQuery("reqtype=login");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        request.setPayload(json.getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-        authResource.onRequestReceived(ctx, request);
-
-        coapClient.sendRequest(request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandlerPublishReqeust() throws Exception {
-
-        String userId = "eyedglen";
-        String deviceId = "d0001";
-        String json = "{\"userid\":\"" + userId + "\",\"deviceId\":\""
-                + deviceId + "\"}";
-
-        CoapRequest request = new CoapRequest(CoapMethod.POST);
-        request.setUriPath(Constants.ACCOUNT_URI);
-        request.setUriQuery("reqtype=publish");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        request.setPayload(json.getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-        accountResource.onRequestReceived(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandlerFindReqeust() throws Exception {
-
-        String userId = "eyedglen";
-        String json = "{\"userid\":\"" + userId + "\"}";
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.ACCOUNT_URI);
-        request.setUriQuery("reqtype=find");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        request.setPayload(json.getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-        accountResource.onRequestReceived(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-}
diff --git a/cloud/interface/.project b/cloud/interface/.project
deleted file mode 100644 (file)
index 92dcbdb..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>CloudInterface</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.m2e.core.maven2Builder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-               <nature>org.eclipse.m2e.core.maven2Nature</nature>
-       </natures>
-</projectDescription>
index 3c29dfd..b8528f6 100644 (file)
@@ -1,30 +1,42 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.iotivity.cloud</groupId>
-  <artifactId>CloudInterface</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
-  
-  <properties>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.iotivity.cloud</groupId>
+       <artifactId>CloudInterface</artifactId>
+       <version>0.0.1-SNAPSHOT</version>
+
+       <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.test.skip>true</maven.test.skip>
        </properties>
-       
-  <dependencies>
-               <dependency>
+
+       <dependencies>
+               <dependency>
                        <groupId>org.iotivity.cloud</groupId>
                        <artifactId>CloudStack</artifactId>
                        <version>0.0.1-SNAPSHOT</version>
-               </dependency>   
+               </dependency>
+               <dependency>
+                       <groupId>org.iotivity.cloud</groupId>
+                       <artifactId>CloudResourceDirectory</artifactId>
+                       <version>0.0.1-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.17</version>
+               </dependency>
        </dependencies>
-       
-  <build>
+
+       <build>
                <plugins>
                        <plugin>
                                <inherited>true</inherited>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
-                                       <source>1.7</source>
-                                       <target>1.7</target>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
                                        <encoding>UTF-8</encoding>
                                </configuration>
                        </plugin>
@@ -60,5 +72,5 @@
                        </plugin>
                </plugins>
        </build>
-  
+
 </project>
\ No newline at end of file
index a165393..cea7878 100644 (file)
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.ciserver;
 
 import java.net.InetSocketAddress;
 import java.util.Scanner;
 
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
-import org.iotivity.cloud.base.SessionManager;
-import org.iotivity.cloud.ciserver.protocols.CoapAuthHandler;
-import org.iotivity.cloud.ciserver.protocols.CoapRelayHandler;
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.ciserver.DeviceServerSystem.CoapDevicePool;
+import org.iotivity.cloud.ciserver.resources.DiResource;
 import org.iotivity.cloud.ciserver.resources.KeepAliveResource;
-import org.iotivity.cloud.util.CoapLogHandler;
+import org.iotivity.cloud.ciserver.resources.proxy.Account;
+import org.iotivity.cloud.ciserver.resources.proxy.DevicePresence;
+import org.iotivity.cloud.ciserver.resources.proxy.MessageQueue;
+import org.iotivity.cloud.ciserver.resources.proxy.ResourceDirectory;
+import org.iotivity.cloud.ciserver.resources.proxy.ResourceFind;
+import org.iotivity.cloud.ciserver.resources.proxy.ResourcePresence;
+import org.iotivity.cloud.util.ErrorLogger;
+import org.iotivity.cloud.util.FileLogger;
 import org.iotivity.cloud.util.Logger;
 
 public class CloudInterfaceServer {
 
     public static void main(String[] args) throws Exception {
 
+        System.setOut(FileLogger.createLoggingProxy(System.out));
+
         System.out.println("-----CI SERVER-------");
 
-        if (args.length != 5) {
+        if (args.length != 8) {
             Logger.e(
-                    "coap server port and RDServer_Address port AccountServer_Address Port required\n"
-                            + "ex) 5683 127.0.0.1 5684 127.0.0.1 5685\n");
+                    "coap server port and RDServer_Address port AccountServer_Address Port MQBroker_Address Port and TLS mode required\n"
+                            + "ex) 5683 127.0.0.1 5684 127.0.0.1 5685 127.0.0.1 5686 0\n");
             return;
         }
 
-        ResourceManager resourceManager = null;
-        SessionManager sessionManager = null;
-        CoapServer coapServer = null;
+        boolean tlsMode = Integer.parseInt(args[7]) == 1;
 
-        CoapRelayHandler relayHandler = null;
-        CoapAuthHandler authHandler = null;
+        ConnectorPool.addConnection("rd",
+                new InetSocketAddress(args[1], Integer.parseInt(args[2])),
+                tlsMode);
+        ConnectorPool.addConnection("account",
+                new InetSocketAddress(args[3], Integer.parseInt(args[4])),
+                tlsMode);
+        ConnectorPool.addConnection("mq",
+                new InetSocketAddress(args[5], Integer.parseInt(args[6])),
+                tlsMode);
 
-        KeepAliveResource keepAliveResource = null;
+        ErrorLogger.Init();
 
-        coapServer = new CoapServer();
+        DeviceServerSystem deviceServer = new DeviceServerSystem();
 
-        sessionManager = new SessionManager();
+        Account acHandler = new Account();
+        ResourceDirectory rdHandler = new ResourceDirectory();
+        ResourceFind resHandler = new ResourceFind();
+        ResourcePresence adHandler = new ResourcePresence();
+        DevicePresence prsHandler = new DevicePresence();
+        MessageQueue mqHandler = new MessageQueue();
 
-        resourceManager = new ResourceManager();
+        CoapDevicePool devicePool = deviceServer.getDevicePool();
 
-        relayHandler = new CoapRelayHandler(sessionManager);
+        deviceServer.addResource(acHandler);
 
-        authHandler = new CoapAuthHandler();
+        deviceServer.addResource(rdHandler);
 
-        keepAliveResource = new KeepAliveResource(sessionManager,
-                new int[] { 1, 2, 4, 8 });
+        deviceServer.addResource(resHandler);
+
+        deviceServer.addResource(adHandler);
 
-        coapServer.addHandler(new CoapLogHandler());
+        deviceServer.addResource(prsHandler);
 
-        coapServer.addHandler(authHandler);
+        deviceServer.addResource(mqHandler);
 
-        coapServer.addHandler(relayHandler);
+        KeepAliveResource resKeepAlive = new KeepAliveResource(
+                new int[] { 1, 2, 4, 8 });
 
-        coapServer.addHandler(resourceManager);
+        deviceServer.addResource(resKeepAlive);
 
-        resourceManager.registerResource(keepAliveResource);
+        deviceServer.addResource(new DiResource(devicePool));
 
-        authHandler.startHandler(args[3], Integer.parseInt(args[4]));
+        deviceServer.addServer(new CoapServer(
+                new InetSocketAddress(Integer.parseInt(args[0]))));
 
-        relayHandler.startHandler(args[1], Integer.parseInt(args[2]), args[3],
-                Integer.parseInt(args[4]));
+        // deviceServer.addServer(new HttpServer(new InetSocketAddress(8080)));
 
-        coapServer
-                .startServer(new InetSocketAddress(Integer.parseInt(args[0])));
+        deviceServer.startSystem(tlsMode);
 
-        keepAliveResource.startSessionChecker();
+        resKeepAlive.startSessionChecker();
 
-        Scanner in = new Scanner(System.in, "UTF-8");
+        Scanner in = new Scanner(System.in);
 
         System.out.println("press 'q' to terminate");
 
@@ -98,13 +117,9 @@ public class CloudInterfaceServer {
 
         System.out.println("Terminating...");
 
-        keepAliveResource.stopSessionChecker();
-
-        coapServer.stopServer();
-
-        relayHandler.stopHandler();
+        resKeepAlive.stopSessionChecker();
 
-        authHandler.stopHandler();
+        deviceServer.stopSystem();
 
         System.out.println("Terminated");
     }
index 164c9e8..7c3a2cb 100644 (file)
@@ -1,42 +1,37 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.ciserver;
 
-import io.netty.util.AttributeKey;
+import org.iotivity.cloud.base.OCFConstants;
 
-public class Constants {
-    public static final String RD_URI         = "oic/rd";   // resource
-                                                            // publish uri
-    public static final String KEEP_ALIVE_URI = "oic/ping"; // keepalive
-                                                            // resource uri
-    public static final String WELL_KNOWN_URI = "oic/res";  // resource
-                                                            // discover uri
+public class Constants extends OCFConstants {
 
-    public static final String DEVICE_LIST = "st=didList"; // oauth device
-                                                           // list riquery
+    public static final int    MIN_TO_LIVE          = 10;
 
-    public static final String AUTH_URI    = "oic/auth";
-    public static final String ACCOUNT_URI = "oic/account";
+    public static final String DEVICE_ID            = "di";
+    public static final String PRESENCE_STATE       = "state";
+
+    public static final String SEARCH_ACCESS_TOKEN  = "accesstoken";
+    public static final Object SEARCH_REFRESH_TOKEN = "refreshtoken";
+    public static final Object EXPIRES_IN           = "expiresin";
 
-    public static final AttributeKey<String> Attribute_UserId = AttributeKey
-            .newInstance("userId");
 }
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/DeviceServerSystem.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/DeviceServerSystem.java
new file mode 100644 (file)
index 0000000..82d7ba7
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver;
+
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.ServerSystem;
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.base.server.HttpServer;
+import org.iotivity.cloud.base.server.Server;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.ErrorLogger;
+
+import io.netty.channel.ChannelDuplexHandler;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+
+public class DeviceServerSystem extends ServerSystem {
+
+    public class CoapDevicePool {
+        HashMap<String, Device> mMapDevice = new HashMap<>();
+
+        public void addDevice(Device device) {
+            String deviceId = ((CoapDevice) device).getDeviceId();
+            synchronized (mMapDevice) {
+                mMapDevice.put(deviceId, device);
+            }
+        }
+
+        public void removeDevice(Device device) {
+            String deviceId = ((CoapDevice) device).getDeviceId();
+            synchronized (mMapDevice) {
+                if (mMapDevice.get(deviceId) == device) {
+                    mMapDevice.remove(deviceId);
+                }
+            }
+        }
+
+        public Device queryDevice(String deviceId) {
+            Device device = null;
+            synchronized (mMapDevice) {
+                device = mMapDevice.get(deviceId);
+            }
+            return device;
+        }
+    }
+
+    CoapDevicePool mDevicePool = new CoapDevicePool();
+
+    @Sharable
+    class CoapLifecycleHandler extends ChannelDuplexHandler {
+        @Override
+        public void channelRead(ChannelHandlerContext ctx, Object msg) {
+
+            if (msg instanceof CoapRequest) {
+                try {
+                    CoapDevice coapDevice = (CoapDevice) ctx.channel()
+                            .attr(keyDevice).get();
+
+                    if (coapDevice.getIssuedTime() != null
+                            && coapDevice.isExpiredTime()) {
+                        throw new UnAuthorizedException("token is expired");
+                    }
+
+                } catch (Throwable t) {
+                    ResponseStatus responseStatus = t instanceof ServerException
+                            ? ((ServerException) t).getErrorResponse()
+                            : ResponseStatus.BAD_REQUEST;
+                    ctx.channel().writeAndFlush(MessageBuilder
+                            .createResponse((CoapRequest) msg, responseStatus));
+                    ErrorLogger.write(ctx.channel(), t);
+                }
+            }
+
+            ctx.fireChannelRead(msg);
+        }
+
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) {
+
+            // Authenticated device connected
+            Device device = ctx.channel().attr(keyDevice).get();
+            mDevicePool.addDevice(device);
+            device.onConnected();
+
+            sendDevicePresence(device.getDeviceId(), "on");
+        }
+
+        @Override
+        public void channelInactive(ChannelHandlerContext ctx) {
+            Device device = ctx.channel().attr(keyDevice).get();
+            // Some cases, this event occurs after new device connected using
+            // same di.
+            // So compare actual value, and remove if same.
+            if (device != null) {
+                mDevicePool.removeDevice(device);
+                device.onDisconnected();
+                ctx.channel().attr(keyDevice).remove();
+
+                sendDevicePresence(device.getDeviceId(), "off");
+            }
+        }
+
+        private void sendDevicePresence(String deviceId, String state) {
+
+            Cbor<HashMap<String, Object>> cbor = new Cbor<>();
+            IRequestChannel RDServer = ConnectorPool.getConnection("rd");
+            HashMap<String, Object> payload = new HashMap<String, Object>();
+            payload.put(Constants.DEVICE_ID, deviceId);
+            payload.put(Constants.PRESENCE_STATE, state);
+            StringBuffer uriPath = new StringBuffer();
+            uriPath.append("/" + Constants.PREFIX_WELL_KNOWN);
+            uriPath.append("/" + Constants.PREFIX_OCF);
+            uriPath.append("/" + Constants.DEVICE_PRESENCE_URI);
+            RDServer.sendRequest(MessageBuilder.createRequest(
+                    RequestMethod.POST, uriPath.toString(), null,
+                    ContentFormat.APPLICATION_CBOR,
+                    cbor.encodingPayloadToCbor(payload)), null);
+        }
+    }
+
+    @Sharable
+    class CoapAuthHandler extends ChannelDuplexHandler {
+        private Cbor<HashMap<String, Object>> mCbor = new Cbor<HashMap<String, Object>>();
+
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) {
+            // Actual channel active should decided after authentication.
+        }
+
+        @Override
+        public void write(ChannelHandlerContext ctx, Object msg,
+                ChannelPromise promise) {
+
+            try {
+                if (!(msg instanceof CoapResponse)) {
+                    throw new BadRequestException(
+                            "this msg type is not CoapResponse");
+                }
+                // This is CoapResponse
+                // Once the response is valid, add this to deviceList
+                CoapResponse response = (CoapResponse) msg;
+
+                switch (response.getStatus()) {
+                    // TODO: below section is exceptional case for ping from
+                    // clients
+                    case CREATED:
+                    case CONTENT:
+                        break;
+
+                    case VALID:
+                        if (response.getPayload() != null) {
+                            HashMap<String, Object> payloadData = mCbor
+                                    .parsePayloadFromCbor(response.getPayload(),
+                                            HashMap.class);
+                            int remainTime = (int) payloadData
+                                    .get(Constants.EXPIRES_IN);
+
+                            Device device = ctx.channel().attr(keyDevice).get();
+                            ((CoapDevice) device).setExpiredPolicy(remainTime);
+
+                            // Remove current auth handler
+                            ctx.channel().pipeline().remove(this);
+
+                            // Raise event that we have Authenticated device
+                            ctx.fireChannelActive();
+                        }
+                        break;
+
+                    default:
+                }
+
+                ctx.writeAndFlush(msg);
+
+            } catch (Throwable t) {
+                ErrorLogger.write(ctx.channel(), t);
+                ctx.writeAndFlush(msg);
+                ctx.close();
+            }
+        }
+
+        @Override
+        public void channelRead(ChannelHandlerContext ctx, Object msg) {
+
+            try {
+                if (!(msg instanceof CoapRequest)) {
+                    throw new BadRequestException(
+                            "this msg type is not CoapRequest");
+                }
+
+                // And check first response is VALID then add or cut
+                CoapRequest request = (CoapRequest) msg;
+                // Check whether first request is about account
+                if (request.getUriPathSegments().size() < 2) {
+                    throw new UnAuthorizedException(
+                            "first request must be about account or keepAlive");
+                }
+
+                // TODO: device sends ping whether not authorized
+                if (request.getUriPathSegments().get(1)
+                        .equals(Constants.KEEP_ALIVE_URI)) {
+                    // Go upperlayer
+                    ctx.fireChannelRead(msg);
+                    return;
+                }
+
+                if (request.getUriPathSegments().size() < 3
+                        || request.getUriPathSegments().get(2)
+                                .equals(Constants.ACCOUNT_URI) == false) {
+                    throw new UnAuthorizedException(
+                            "authentication required first");
+                }
+
+                HashMap<String, Object> authPayload = mCbor
+                        .parsePayloadFromCbor(request.getPayload(),
+                                HashMap.class);
+
+                if (authPayload.containsKey("di") == false) {
+                    throw new PreconditionFailedException(
+                            "di property is not included");
+                }
+
+                CoapDevice device = new CoapDevice(ctx,
+                        (String) authPayload.get("di"),
+                        (String) authPayload.get("accesstoken"));
+
+                // Create device first and pass to upperlayer
+                ctx.channel().attr(keyDevice).set(device);
+
+                ctx.fireChannelRead(msg);
+
+            } catch (Throwable t) {
+                ResponseStatus responseStatus = t instanceof ServerException
+                        ? ((ServerException) t).getErrorResponse()
+                        : ResponseStatus.UNAUTHORIZED;
+                ctx.channel().writeAndFlush(MessageBuilder
+                        .createResponse((CoapRequest) msg, responseStatus));
+                ErrorLogger.write(ctx.channel(), t);
+            }
+        }
+    }
+
+    @Sharable
+    class HttpAuthHandler extends ChannelDuplexHandler {
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) throws Exception {
+            // After current channel authenticated, raise to upper layer
+        }
+    }
+
+    @Override
+    public void addServer(Server server) {
+        if (server instanceof CoapServer) {
+            server.addHandler(new CoapAuthHandler());
+            server.addHandler(new CoapLifecycleHandler());
+        }
+
+        if (server instanceof HttpServer) {
+            server.addHandler(new HttpAuthHandler());
+        }
+
+        super.addServer(server);
+    }
+
+    public CoapDevicePool getDevicePool() {
+        return mDevicePool;
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java
deleted file mode 100644 (file)
index 3e626e3..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 Samsung Electronics All Rights Reserved.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- * //
- * // Licensed under the Apache License, Version 2.0 (the "License");
- * // you may not use this file except in compliance with the License.
- * // You may obtain a copy of the License at
- * //
- * //      http://www.apache.org/licenses/LICENSE-2.0
- * //
- * // Unless required by applicable law or agreed to in writing, software
- * // distributed under the License is distributed on an "AS IS" BASIS,
- * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * // See the License for the specific language governing permissions and
- * // limitations under the License.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.ciserver.protocols;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.iotivity.cloud.ciserver.Constants;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.JSONUtil;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.util.AttributeKey;
-
-@Sharable
-public class CoapAuthHandler extends ChannelDuplexHandler {
-
-    private static final AttributeKey<ChannelHandlerContext> keyAuthClient = AttributeKey
-            .newInstance("authCtx");
-
-    private class AccountHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-
-        @Override
-        public void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
-                throws Exception {
-            Logger.d("Receive response from account, forward to client");
-
-            ChannelHandlerContext ctxToDevice = ctx.channel()
-                    .attr(keyAuthClient).get();
-
-            if (msg.getResponseCode() == CoapStatus.CREATED) {
-                Map<String, String> response = JSONUtil.parseJSON(
-                        new String(msg.getPayload(), StandardCharsets.UTF_8));
-
-                if (response != null) {
-                    String userId = response.get("userid");
-                    if (userId != null) {
-                        ctxToDevice.channel().attr(Constants.Attribute_UserId)
-                                .set(userId);
-                    }
-                    msg.setPayload(cbor.encodingPayloadToCbor(response));
-
-                    CoapAuthHandler authHandler = ctxToDevice.channel()
-                            .pipeline().get(CoapAuthHandler.class);
-
-                    ctxToDevice.channel().pipeline().remove(authHandler);
-                }
-            }
-
-            ctxToDevice.writeAndFlush(msg);
-
-            if (msg.getResponseCode() != CoapStatus.CREATED)
-                ctxToDevice.close();
-        }
-
-        @Override
-        public void exceptionCaught(ChannelHandlerContext ctx,
-                Throwable cause) {
-            cause.printStackTrace();
-            ctx.close();
-        }
-    }
-
-    private CoapClient asClient = new CoapClient();
-
-    public CoapAuthHandler() {
-
-        asClient.addHandler(new AccountHandler());
-
-    }
-
-    public void startHandler(String acAddress, int acPort) throws Exception {
-        asClient.startClient(new InetSocketAddress(acAddress, acPort));
-    }
-
-    public void stopHandler() throws Exception {
-        asClient.stopClient();
-    }
-
-    private Cbor<HashMap<Object, Object>> cbor = new Cbor<HashMap<Object, Object>>();
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg)
-            throws Exception {
-
-        if (msg instanceof CoapRequest) {
-            CoapRequest request = (CoapRequest) msg;
-            String uriPath = request.getUriPath();
-            if (uriPath != null) {
-                switch (uriPath) {
-                    // This handler only used for initial handshake
-                    case Constants.AUTH_URI:
-                        HashMap<Object, Object> payloadData = cbor
-                                .parsePayloadFromCbor(request.getPayload(),
-                                        HashMap.class);
-                        String writejson = JSONUtil.writeJSON(payloadData);
-                        if (writejson != null) {
-                            request.setPayload(
-                                    writejson.getBytes(StandardCharsets.UTF_8));
-                            asClient.getChannelFuture().channel()
-                                    .attr(keyAuthClient).set(ctx);
-                            asClient.sendRequest(request);
-                        }
-                        return;
-
-                    case Constants.KEEP_ALIVE_URI:
-                        super.channelRead(ctx, msg);
-                        return;
-
-                    default:
-                        CoapResponse response = new CoapResponse(
-                                CoapStatus.UNAUTHORIZED);
-                        Logger.e("Sending UNAUTHORIZED to client");
-                        ctx.writeAndFlush(response);
-                        break;
-                }
-            }
-        }
-
-        Logger.d("Invalid packet for authenticating");
-        ctx.close();
-    }
-}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java
deleted file mode 100644 (file)
index 533811e..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.ciserver.protocols;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.SessionManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.iotivity.cloud.ciserver.Constants;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.util.AttributeKey;
-
-/**
- *
- * This class is relay handler relating Cloud Interface
- *
- */
-@Sharable
-public class CoapRelayHandler extends ChannelDuplexHandler {
-
-    /////////// Handler for Resource Directory
-    private static final AttributeKey<ChannelHandlerContext> keyRDClient = AttributeKey
-            .newInstance("rdCtx");
-
-    private static class RDHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-        @Override
-        public void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
-                throws Exception {
-            Logger.d("Receive response from RD, forward to client");
-
-            ChannelHandlerContext ctxToDevice = ctx.channel().attr(keyRDClient)
-                    .get();
-            ctxToDevice.writeAndFlush(msg);
-        }
-
-        @Override
-        public void exceptionCaught(ChannelHandlerContext ctx,
-                Throwable cause) {
-            cause.printStackTrace();
-            ctx.close();
-        }
-    }
-
-    private CoapClient                                   rdClient         = null;
-                                                                          ///////////
-
-    ////////// Handler for Account Server
-    private static final AttributeKey<List<CoapRequest>> keyAccountClient = AttributeKey
-            .newInstance("accountCtx");
-
-    private class AccountHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-        @Override
-        public void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
-                throws Exception {
-            Logger.d("Receive response from AS, make request to RD");
-
-            CoapRequest rdRequest = null;
-
-            switch (msg.getResponseCode()) {
-                case CREATED:
-                    // response of POST request
-                    rdRequest = ctx.channel().attr(keyAccountClient).get()
-                            .remove(0);
-                    rdClient.sendRequest(rdRequest);
-                    break;
-
-                case CONTENT:
-                    // response of GET request, contains did list
-                    rdRequest = ctx.channel().attr(keyAccountClient).get()
-                            .remove(0);
-                    // change uri to send RD
-                    rdRequest.setUriPath(Constants.RD_URI);
-                    rdRequest.setUriQuery(Constants.DEVICE_LIST);
-                    rdRequest.setPayload(msg.getPayload());
-                    rdClient.sendRequest(rdRequest);
-                    break;
-
-                default:
-                    break;
-            }
-        }
-
-        @Override
-        public void exceptionCaught(ChannelHandlerContext ctx,
-                Throwable cause) {
-            cause.printStackTrace();
-            ctx.close();
-        }
-    }
-
-    private CoapClient     asClient       = null;
-    //////////
-
-    private SessionManager sessionManager = null;
-
-    public CoapRelayHandler(SessionManager sessionManager) {
-        this.sessionManager = sessionManager;
-
-        rdClient = new CoapClient();
-
-        rdClient.addHandler(new RDHandler());
-
-        asClient = new CoapClient();
-
-        asClient.addHandler(new AccountHandler());
-    }
-
-    public void startHandler(String rdAddress, int rdPort, String acAddress,
-            int acPort) throws Exception {
-        rdClient.startClient(new InetSocketAddress(rdAddress, rdPort));
-
-        asClient.startClient(new InetSocketAddress(acAddress, acPort));
-
-        asClient.getChannelFuture().channel().attr(keyAccountClient)
-                .set(new ArrayList<CoapRequest>());
-    }
-
-    public void stopHandler() throws Exception {
-        asClient.stopClient();
-
-        rdClient.stopClient();
-    }
-
-    private static final AttributeKey<ChannelHandlerContext> keyDevice = AttributeKey
-            .newInstance("deviceCtx");
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg)
-            throws Exception {
-
-        if (msg instanceof CoapRequest) {
-            CoapRequest request = (CoapRequest) msg;
-            // Parse uri, send to RD
-            String uriPath = request.getUriPath();
-            CoapRequest accountRequest = null;
-            String userId, deviceId, authPayload;
-            CoapResponse response;
-
-            Logger.d("Request received, URI: " + uriPath);
-            if (uriPath != null) {
-                switch (uriPath) {
-                    case Constants.AUTH_URI:
-                        // This case user wants to logout
-                        String uriQuery = request.getUriQuery();
-                        if (uriQuery != null) {
-                            if (uriQuery.endsWith("logout")) {
-                                ctx.channel().attr(Constants.Attribute_UserId)
-                                        .remove();
-                                response = new CoapResponse(CoapStatus.DELETED);
-                            } else {
-                                response = new CoapResponse(
-                                        CoapStatus.BAD_REQUEST);
-                            }
-                            ctx.writeAndFlush(response);
-                        }
-                        break;
-
-                    case Constants.RD_URI:
-                        // RD POST means publish device to server
-                        switch (request.getRequestMethod()) {
-                            case POST:
-                                userId = ctx.channel()
-                                        .attr(Constants.Attribute_UserId).get();
-                                deviceId = request.decodeDeviceId();
-                                authPayload = String.format(
-                                        "{\"userid\":\"%s\",\"deviceid\":\"%s\"}",
-                                        userId, deviceId);
-                                accountRequest = new CoapRequest(
-                                        CoapMethod.POST);
-                                accountRequest
-                                        .setUriPath(Constants.ACCOUNT_URI);
-                                accountRequest.setUriQuery("reqtype=publish");
-                                accountRequest.setToken(request.getToken());
-                                accountRequest.setPayload(authPayload
-                                        .getBytes(StandardCharsets.UTF_8));
-
-                                // TODO: deviceId must be registered after
-                                // session
-                                // granted
-                                Logger.d("Adding deviceId to session: "
-                                        + deviceId);
-                                sessionManager.addSession(deviceId, ctx);
-                                break;
-
-                            default:
-                                Logger.e("Unsupported request type");
-                                break;
-                        }
-
-                        rdClient.getChannelFuture().channel().attr(keyRDClient)
-                                .set(ctx);
-
-                        // Add original request to list for future use
-                        asClient.getChannelFuture().channel()
-                                .attr(keyAccountClient).get().add(request);
-                        asClient.sendRequest(accountRequest);
-                        return;
-
-                    case Constants.WELL_KNOWN_URI:
-                        switch (request.getRequestMethod()) {
-                            case GET:
-                                userId = ctx.channel()
-                                        .attr(Constants.Attribute_UserId).get();
-                                authPayload = String
-                                        .format("{\"userid\":\"%s\"}", userId);
-                                accountRequest = new CoapRequest(
-                                        CoapMethod.GET);
-                                accountRequest
-                                        .setUriPath(Constants.ACCOUNT_URI);
-                                accountRequest.setUriQuery("reqtype=find");
-                                accountRequest.setToken(request.getToken());
-                                accountRequest.setPayload(authPayload
-                                        .getBytes(StandardCharsets.UTF_8));
-                                break;
-
-                            default:
-                                Logger.e("Unsupported request type");
-                                break;
-                        }
-
-                        rdClient.getChannelFuture().channel().attr(keyRDClient)
-                                .set(ctx);
-
-                        // Add original request to list for future use
-                        asClient.getChannelFuture().channel()
-                                .attr(keyAccountClient).get().add(request);
-                        asClient.sendRequest(accountRequest);
-                        return;
-
-                    case Constants.KEEP_ALIVE_URI:
-                        break;
-
-                    default:
-                        List<String> uriPathList = request.getUriPathSegments();
-                        if (uriPathList != null) {
-                            Logger.i("uriPahtList: " + uriPathList.toString());
-
-                            String did = uriPathList.get(0);
-
-                            Logger.i("did: " + did);
-
-                            // TODO: Clustering algorithm required
-                            // find ctx about did, and send msg
-                            StringBuffer resource = new StringBuffer();
-                            List<String> pathSegments = uriPathList.subList(1,
-                                    uriPathList.size());
-                            for (String path : pathSegments) {
-                                resource.append("/");
-                                resource.append(path);
-                            }
-                            Logger.i("resource: " + resource);
-                            request.setUriPath(resource.toString());
-
-                            ChannelHandlerContext deviceCtx = sessionManager
-                                    .querySession(did);
-                            if (deviceCtx != null) {
-                                deviceCtx.attr(keyDevice).set(ctx);
-                                deviceCtx.writeAndFlush(request);
-                            } else {
-                                Logger.e("deviceCtx is null");
-                                response = new CoapResponse(
-                                        CoapStatus.FORBIDDEN);
-                                response.setToken(request.getToken());
-                                ctx.writeAndFlush(response);
-                            }
-                        }
-                        return;
-                }
-            }
-
-        } else if (msg instanceof CoapResponse) {
-            ChannelHandlerContext resourceClient = ctx.attr(keyDevice).get();
-            if (resourceClient != null) {
-                Logger.i("Forwards message to client");
-
-                CoapResponse response = (CoapResponse) msg;
-
-                // If response contains path, add di
-                String did = sessionManager.queryDid(ctx);
-                if (response.getOption(11) != null && did != null) {
-                    response.getOption(11).add(0,
-                            did.getBytes(StandardCharsets.UTF_8));
-                }
-
-                Logger.i(
-                        "ctx.channel : " + resourceClient.channel().toString());
-                resourceClient.writeAndFlush(response);
-                return;
-            }
-        }
-
-        super.channelRead(ctx, msg);
-    }
-
-    @Override
-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-        Logger.d("Channel Inactive");
-        sessionManager.removeSessionByChannel(ctx);
-        super.channelInactive(ctx);
-    }
-
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
-
-        cause.printStackTrace();
-        ctx.close();
-    }
-}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java
new file mode 100644 (file)
index 0000000..84b8675
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.device.IResponseEventHandler;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.NotFoundException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+import org.iotivity.cloud.ciserver.DeviceServerSystem.CoapDevicePool;
+import org.iotivity.cloud.util.Cbor;
+
+public class DiResource extends Resource {
+
+    private CoapDevicePool mDevicePool = null;
+
+    public DiResource(CoapDevicePool devicePool) {
+        super(Arrays.asList(Constants.DEVICE_ID));
+        mDevicePool = devicePool;
+
+        addQueryHandler(
+                Arrays.asList(Constants.RS_INTERFACE + "="
+                        + Constants.LINK_INTERFACE),
+                this::onLinkInterfaceRequestReceived);
+    }
+
+    private IRequestChannel getTargetDeviceChannel(IRequest request)
+            throws ServerException {
+        List<String> uriPathSegment = request.getUriPathSegments();
+
+        if (uriPathSegment.size() < 2) {
+            throw new PreconditionFailedException();
+        }
+
+        String deviceId = uriPathSegment.get(1);
+        CoapDevice targetDevice = (CoapDevice) mDevicePool
+                .queryDevice(deviceId);
+
+        if (targetDevice == null) {
+            throw new NotFoundException();
+        }
+
+        // Do request and receive response
+        return targetDevice.getRequestChannel();
+    }
+
+    private String extractTargetUriPath(IRequest request) {
+        List<String> uriPathSegment = request.getUriPathSegments();
+
+        // Remove prefix path
+        uriPathSegment.remove(0);
+        uriPathSegment.remove(0);
+
+        StringBuilder uriPath = new StringBuilder();
+        for (String path : uriPathSegment) {
+            uriPath.append("/" + path);
+        }
+
+        return uriPath.toString();
+    }
+
+    class LinkInterfaceHandler implements IResponseEventHandler {
+        private Cbor<List<HashMap<String, Object>>> mCbor      = new Cbor<>();
+        private String                              mTargetDI  = null;
+        private Device                              mSrcDevice = null;
+
+        public LinkInterfaceHandler(String targetDI, Device srcDevice) {
+            mTargetDI = targetDI;
+            mSrcDevice = srcDevice;
+        }
+
+        private void convertHref(List<HashMap<String, Object>> linkPayload) {
+            for (HashMap<String, Object> link : linkPayload) {
+                link.put("href", "/di/" + mTargetDI + link.get("href"));
+            }
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response) {
+            List<HashMap<String, Object>> linkPayload = null;
+            if (response.getStatus() == ResponseStatus.CONTENT) {
+                linkPayload = mCbor.parsePayloadFromCbor(response.getPayload(),
+                        ArrayList.class);
+                convertHref(linkPayload);
+            }
+
+            mSrcDevice.sendResponse(MessageBuilder.modifyResponse(response,
+                    ContentFormat.APPLICATION_CBOR, linkPayload != null
+                            ? mCbor.encodingPayloadToCbor(linkPayload) : null));
+        }
+    }
+
+    public void onLinkInterfaceRequestReceived(Device srcDevice,
+            IRequest request) throws ServerException {
+        IRequestChannel requestChannel = getTargetDeviceChannel(request);
+
+        if (requestChannel == null) {
+            throw new NotFoundException();
+        }
+
+        String deviceId = request.getUriPathSegments().get(1);
+
+        requestChannel.sendRequest(
+                MessageBuilder.modifyRequest(request,
+                        extractTargetUriPath(request), null, null, null),
+                new LinkInterfaceHandler(deviceId, srcDevice));
+    }
+
+    // This is optional method for packet handling
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Find proper request channel using di in URI path field.
+        IRequestChannel requestChannel = getTargetDeviceChannel(request);
+
+        if (requestChannel == null) {
+            throw new NotFoundException();
+        }
+
+        requestChannel.sendRequest(
+                MessageBuilder.modifyRequest(request,
+                        extractTargetUriPath(request), null, null, null),
+                srcDevice);
+    }
+}
index 804bf81..7f0ccc5 100644 (file)
@@ -1,27 +1,28 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.ciserver.resources;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -30,16 +31,17 @@ import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
 
-import org.iotivity.cloud.base.Resource;
-import org.iotivity.cloud.base.SessionManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelHandlerContext;
 
 /**
  *
@@ -48,149 +50,100 @@ import io.netty.channel.ChannelHandlerContext;
  *
  */
 public class KeepAliveResource extends Resource {
-
-    private int[]                                intervals;
-    private HashMap<ChannelHandlerContext, Long> connectPool;
-    private Timer                                timer;
-    private Cbor<HashMap<String, Integer>>       cbor;
-    private SessionManager                       sessionManager = null;
-
-    public void setIntervals(int[] intervals) {
-        this.intervals = intervals;
-    }
-
-    public int[] getIntervals() {
-        return this.intervals;
+    private int[]                          mIntervals      = null;
+    private Timer                          mTimer          = new Timer();
+    private Cbor<HashMap<String, Integer>> mCbor           = new Cbor<>();
+    private HashMap<Device, Long>          mConnectionPool = new HashMap<>();
+
+    public KeepAliveResource(int[] intervals) {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.KEEP_ALIVE_URI));
+        mIntervals = intervals;
     }
 
-    public KeepAliveResource(SessionManager sessionManager, int[] intervals) {
-        setUri(Constants.KEEP_ALIVE_URI);
-        setIntervals(intervals);
-        this.sessionManager = sessionManager;
-        connectPool = new HashMap<ChannelHandlerContext, Long>();
-        timer = new Timer();
-        cbor = new Cbor<HashMap<String, Integer>>();
-    }
-
-    public void startSessionChecker() {
-        timer.schedule(new KeepAliveTask(), 30000, 60000);
-    }
-
-    public void stopSessionChecker() {
-        timer.cancel();
-    }
-
-    /**
-     * API for receiving message(message to keepalive resource)
-     *
-     * @param ctx
-     *            ChannelHandlerContext of request message
-     * @param request
-     *            CoAP request message
-     */
     @Override
-    public void onRequestReceived(ChannelHandlerContext ctx,
-            CoapRequest request) {
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
 
-        CoapResponse response = null;
+        IResponse response = null;
 
-        switch (request.getRequestMethod()) {
-            // First message to KeepAlive from resource
+        switch (request.getMethod()) {
             case GET:
-                if (intervals != null) {
-                    response = makePingConfigMessage(request);
-                    connectPool.put(ctx, System.currentTimeMillis()
-                            + (intervals[0] * (long) 60000));
-                }
+                response = handleGetPingConfig(request);
+                mConnectionPool.put(srcDevice, System.currentTimeMillis()
+                        + (mIntervals[0] * (long) 60000));
                 break;
-            // interval Message to KeepAlive After receiving GET Message
-            case PUT:
-                HashMap<String, Integer> payloadData = null;
-                payloadData = cbor.parsePayloadFromCbor(request.getPayload(),
-                        HashMap.class);
 
-                Logger.d("Receive payloadData : " + payloadData);
-                if (payloadData != null) {
-                    if (payloadData.containsKey("in")) {
-                        Logger.d("interval : " + payloadData.get("in"));
-
-                        connectPool.put(ctx, System.currentTimeMillis()
-                                + (payloadData.get("in") * (long) 60000));
-                    }
-                }
-                response = makeResponse(request);
-                break;
-
-            case POST:
+            case PUT:
+                response = handlePutPingConfig(srcDevice, request);
                 break;
 
-            case DELETE:
-                break;
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
         }
 
-        ctx.writeAndFlush(response);
+        srcDevice.sendResponse(response);
     }
 
-    /**
-     * API for making response to Resource
-     *
-     * @param request
-     *            ChannelHandlerContext of request message
-     */
-    private CoapResponse makeResponse(CoapRequest request) {
-        CoapResponse response = new CoapResponse(CoapStatus.VALID);
-        response.setToken(request.getToken());
+    public void startSessionChecker() {
+        mTimer.schedule(new KeepAliveTask(), 30000, 60000);
+    }
 
-        return response;
+    public void stopSessionChecker() {
+        mTimer.cancel();
     }
 
     /**
      * API for making interval and first response to Resource
-     *
+     * 
      * @param request
      *            ChannelHandlerContext of request message
      */
-    private CoapResponse makePingConfigMessage(CoapRequest request) {
-        CoapResponse response = new CoapResponse(CoapStatus.CONTENT);
-        response.setToken(request.getToken());
-
-        HashMap<String, int[]> payloadData = new HashMap<String, int[]>();
-        payloadData.put("inarray", intervals);
+    private IResponse handleGetPingConfig(IRequest request) {
 
-        byte[] cborData = cbor.encodingPayloadToCbor(payloadData);
+        HashMap<String, int[]> payloadData = new HashMap<>();
+        payloadData.put("inarray", mIntervals);
 
-        response.setPayload(cborData);
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(payloadData));
+    }
 
-        Logger.d("Send payloadData : " + payloadData);
+    private IResponse handlePutPingConfig(Device srcDevice, IRequest request) {
 
-        return response;
+        HashMap<String, Integer> payloadData = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+        if (payloadData != null) {
+            if (payloadData.containsKey("in")) {
+                mConnectionPool.put(srcDevice, System.currentTimeMillis()
+                        + (payloadData.get("in") * (long) 60000));
+            }
+        }
+        return MessageBuilder.createResponse(request, ResponseStatus.VALID);
     }
 
     /**
      * API for managing session
      */
-    public class KeepAliveTask extends TimerTask {
+    private class KeepAliveTask extends TimerTask {
 
         @Override
         public void run() {
-            Map<ChannelHandlerContext, Long> map = Collections
-                    .synchronizedMap(connectPool);
-            Set<ChannelHandlerContext> keySet = map.keySet();
-            ArrayList<ChannelHandlerContext> deleteList = new ArrayList<ChannelHandlerContext>();
-            Iterator<ChannelHandlerContext> iterator = null;
+            Map<Device, Long> map = Collections
+                    .synchronizedMap(mConnectionPool);
+            Set<Device> keySet = map.keySet();
+            ArrayList<Device> deleteList = new ArrayList<>();
+            Iterator<Device> iterator = null;
             synchronized (map) {
                 iterator = keySet.iterator();
                 Long currentTime = System.currentTimeMillis();
                 // check interval
                 while (iterator.hasNext()) {
-                    ChannelHandlerContext key = iterator.next();
+                    Device key = iterator.next();
                     if (map.containsKey(key)) {
                         if (map.get(key) != null) {
                             Long lifeTime = (Long) map.get(key);
                             if (lifeTime != null) {
-                                Logger.d("KeepAliveTask Operating : "
-                                        + key.channel().toString() + ", Time : "
-                                        + (lifeTime - currentTime));
                                 if (lifeTime < currentTime) {
                                     deleteList.add(key);
                                 }
@@ -203,11 +156,10 @@ public class KeepAliveResource extends Resource {
             iterator = deleteList.iterator();
             // remove session
             while (iterator.hasNext()) {
-                ChannelHandlerContext key = iterator.next();
-                Logger.d("KeepAliveTask Remove");
-                connectPool.remove(key);
-                sessionManager.removeSessionByChannel(key);
-                key.close();
+                Device key = iterator.next();
+                mConnectionPool.remove(key);
+                key.getCtx().fireChannelInactive();
+                key.getCtx().close();
             }
         }
     }
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/Account.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/Account.java
new file mode 100644 (file)
index 0000000..e89dfc9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.Arrays;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+
+public class Account extends Resource {
+    IRequestChannel mAuthServer = null;
+
+    public Account() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.ACCOUNT_URI));
+
+        mAuthServer = ConnectorPool.getConnection("account");
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Token exchange is done by CoapClient
+        mAuthServer.sendRequest(request, srcDevice);
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/DevicePresence.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/DevicePresence.java
new file mode 100644 (file)
index 0000000..db39483
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.device.IResponseEventHandler;
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.exception.ClientException.BadResponseException;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+import org.iotivity.cloud.util.Cbor;
+
+public class DevicePresence extends Resource {
+    IRequestChannel mASServer = null;
+
+    public DevicePresence() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.DEVICE_PRESENCE_URI));
+
+        mASServer = ConnectorPool.getConnection("account");
+    }
+
+    class AccountReceiveHandler implements IResponseEventHandler {
+
+        IRequestChannel  mRDServer = null;
+        private Device   mSrcDevice;
+        private IRequest mRequest;
+
+        public AccountReceiveHandler(IRequest request, Device srcDevice) {
+            mRDServer = ConnectorPool.getConnection("rd");
+            mSrcDevice = srcDevice;
+            mRequest = request;
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response)
+                throws ClientException {
+
+            switch (response.getStatus()) {
+                case VALID:
+                    mRDServer.sendRequest(mRequest, mSrcDevice);
+                    break;
+
+                case CONTENT:
+                    StringBuilder additionalQuery = new StringBuilder();
+
+                    Cbor<HashMap<String, ArrayList<String>>> responsePayload = new Cbor<>();
+
+                    ArrayList<String> deviceList = responsePayload
+                            .parsePayloadFromCbor(response.getPayload(),
+                                    HashMap.class)
+                            .get("devices");
+
+                    int index = deviceList.size();
+                    for (String deviceId : deviceList) {
+                        if (!deviceId.equals(mSrcDevice.getDeviceId())) {
+                            additionalQuery.append("di=");
+                            additionalQuery.append(deviceId);
+                            if (--index > 0) {
+                                additionalQuery.append("&");
+                            }
+                        }
+                    }
+
+                    String uriQuery = (mRequest.getUriQuery() == null ? ""
+                            : mRequest.getUriQuery() + "&")
+                            + additionalQuery.toString();
+                    IRequest requestToAS = MessageBuilder.modifyRequest(
+                            mRequest, null, uriQuery, null, null);
+
+                    mRDServer.sendRequest(requestToAS, mSrcDevice);
+                    break;
+
+                default:
+                    throw new BadResponseException(
+                            response.getStatus().toString()
+                                    + " response type is not supported");
+            }
+        }
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Token exchange is done by CoapClient
+        CoapDevice coapDevice = (CoapDevice) srcDevice;
+        StringBuffer uriQuery = new StringBuffer();
+        uriQuery.append(Constants.SEARCH_ACCESS_TOKEN + "=");
+        uriQuery.append(coapDevice.getAccessToken());
+
+        if (request.getUriQueryMap() != null) {
+            if (request.getUriQueryMap().get("di") != null) {
+                String di = request.getUriQueryMap().get("di").get(0);
+                if (di != null) {
+                    uriQuery.append("&");
+                    uriQuery.append("di" + "=");
+                    uriQuery.append(di);
+                }
+            }
+        }
+
+        StringBuffer uriPath = new StringBuffer();
+        uriPath.append(Constants.PREFIX_WELL_KNOWN + "/");
+        uriPath.append(Constants.PREFIX_OCF + "/");
+        uriPath.append(Constants.ACCOUNT_URI + "/");
+        uriPath.append(Constants.DEVICE_URI);
+
+        IRequest requestToAS = MessageBuilder.createRequest(RequestMethod.GET,
+                uriPath.toString(), uriQuery.toString());
+
+        mASServer.sendRequest(requestToAS,
+                new AccountReceiveHandler(request, srcDevice));
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/MessageQueue.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/MessageQueue.java
new file mode 100644 (file)
index 0000000..a4153f9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.Arrays;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+
+public class MessageQueue extends Resource {
+    IRequestChannel mPSServer = null;
+
+    public MessageQueue() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.MQ_BROKER_URI));
+
+        mPSServer = ConnectorPool.getConnection("mq");
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        // Token exchange is done by CoapClient
+        mPSServer.sendRequest(request, srcDevice);
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceDirectory.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceDirectory.java
new file mode 100644 (file)
index 0000000..8764ab6
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.Arrays;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+
+public class ResourceDirectory extends Resource {
+    IRequestChannel mRDServer = null;
+
+    public ResourceDirectory() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.RD_URI));
+
+        mRDServer = ConnectorPool.getConnection("rd");
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Token exchange is done by CoapClient
+        mRDServer.sendRequest(request, srcDevice);
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceFind.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourceFind.java
new file mode 100644 (file)
index 0000000..dcee4ba
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.device.IResponseEventHandler;
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.exception.ClientException.BadResponseException;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+import org.iotivity.cloud.util.Cbor;
+
+public class ResourceFind extends Resource {
+    IRequestChannel mASServer = null;
+
+    public ResourceFind() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.WELL_KNOWN_URI));
+
+        mASServer = ConnectorPool.getConnection("account");
+    }
+
+    class AccountReceiveHandler implements IResponseEventHandler {
+
+        IRequestChannel  mRDServer = null;
+        private Device   mSrcDevice;
+        private IRequest mRequest;
+
+        public AccountReceiveHandler(IRequest request, Device srcDevice) {
+            mRDServer = ConnectorPool.getConnection("rd");
+            mSrcDevice = srcDevice;
+            mRequest = request;
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response)
+                throws ClientException {
+
+            switch (response.getStatus()) {
+                case VALID:
+                    mRDServer.sendRequest(mRequest, mSrcDevice);
+                    break;
+
+                case CONTENT:
+                    StringBuilder additionalQuery = new StringBuilder();
+
+                    Cbor<HashMap<String, ArrayList<String>>> responsePayload = new Cbor<>();
+
+                    ArrayList<String> deviceList = responsePayload
+                            .parsePayloadFromCbor(response.getPayload(),
+                                    HashMap.class)
+                            .get("devices");
+
+                    int index = deviceList.size();
+
+                    for (String deviceId : deviceList) {
+                        if (!deviceId.equals(mSrcDevice.getDeviceId())) {
+                            additionalQuery.append("di=");
+                            additionalQuery.append(deviceId);
+                            if (--index > 0) {
+                                additionalQuery.append("&");
+                            }
+                        }
+                    }
+                    String uriQuery = (mRequest.getUriQuery() == null ? ""
+                            : mRequest.getUriQuery() + "&")
+                            + additionalQuery.toString();
+                    IRequest requestToAS = MessageBuilder.modifyRequest(
+                            mRequest, null, uriQuery, null, null);
+
+                    mRDServer.sendRequest(requestToAS, mSrcDevice);
+                    break;
+
+                default:
+                    throw new BadResponseException(
+                            response.getStatus().toString()
+                                    + " response type is not supported");
+            }
+        }
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Token exchange is done by CoapClient
+        CoapDevice coapDevice = (CoapDevice) srcDevice;
+        StringBuffer uriQuery = new StringBuffer();
+        uriQuery.append(Constants.SEARCH_ACCESS_TOKEN + "=");
+        uriQuery.append(coapDevice.getAccessToken());
+
+        if (request.getUriQueryMap().get("di") != null) {
+            String di = request.getUriQueryMap().get("di").get(0);
+            if (di != null) {
+                uriQuery.append("&");
+                uriQuery.append("di" + "=");
+                uriQuery.append(di);
+            }
+        }
+
+        StringBuffer uriPath = new StringBuffer();
+        uriPath.append(Constants.PREFIX_WELL_KNOWN + "/");
+        uriPath.append(Constants.PREFIX_OCF + "/");
+        uriPath.append(Constants.ACCOUNT_URI + "/");
+        uriPath.append(Constants.DEVICE_URI);
+
+        IRequest requestToAS = MessageBuilder.createRequest(RequestMethod.GET,
+                uriPath.toString(), uriQuery.toString());
+
+        mASServer.sendRequest(requestToAS,
+                new AccountReceiveHandler(request, srcDevice));
+    }
+}
diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourcePresence.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/ResourcePresence.java
new file mode 100644 (file)
index 0000000..ff22d95
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.ciserver.resources.proxy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.connector.ConnectorPool;
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.device.IResponseEventHandler;
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.exception.ClientException.BadResponseException;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.ciserver.Constants;
+import org.iotivity.cloud.util.Cbor;
+
+public class ResourcePresence extends Resource {
+    IRequestChannel mASServer = null;
+
+    public ResourcePresence() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.RES_PRESENCE_URI));
+
+        mASServer = ConnectorPool.getConnection("account");
+    }
+
+    class AccountReceiveHandler implements IResponseEventHandler {
+
+        IRequestChannel  mRDServer = null;
+        private Device   mSrcDevice;
+        private IRequest mRequest;
+
+        public AccountReceiveHandler(IRequest request, Device srcDevice) {
+            mRDServer = ConnectorPool.getConnection("rd");
+            mSrcDevice = srcDevice;
+            mRequest = request;
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response)
+                throws ClientException {
+
+            switch (response.getStatus()) {
+                case VALID:
+                    mRDServer.sendRequest(mRequest, mSrcDevice);
+                    break;
+
+                case CONTENT:
+                    StringBuilder additionalQuery = new StringBuilder();
+
+                    Cbor<HashMap<String, ArrayList<String>>> responsePayload = new Cbor<>();
+
+                    ArrayList<String> deviceList = responsePayload
+                            .parsePayloadFromCbor(response.getPayload(),
+                                    HashMap.class)
+                            .get("devices");
+
+                    int index = deviceList.size();
+                    for (String deviceId : deviceList) {
+                        if (!deviceId.equals(mSrcDevice.getDeviceId())) {
+                            additionalQuery.append("di=");
+                            additionalQuery.append(deviceId);
+                            if (--index > 0) {
+                                additionalQuery.append("&");
+                            }
+                        }
+                    }
+
+                    String uriQuery = (mRequest.getUriQuery() == null ? ""
+                            : mRequest.getUriQuery() + "&")
+                            + additionalQuery.toString();
+                    IRequest requestToAS = MessageBuilder.modifyRequest(
+                            mRequest, null, uriQuery, null, null);
+
+                    mRDServer.sendRequest(requestToAS, mSrcDevice);
+                    break;
+
+                default:
+                    throw new BadResponseException(
+                            response.getStatus().toString()
+                                    + " response type is not supported");
+            }
+        }
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Token exchange is done by CoapClient
+        CoapDevice coapDevice = (CoapDevice) srcDevice;
+        StringBuffer uriQuery = new StringBuffer();
+        uriQuery.append(Constants.SEARCH_ACCESS_TOKEN + "=");
+        uriQuery.append(coapDevice.getAccessToken());
+
+        if (request.getUriQueryMap() != null) {
+            String di = request.getUriQueryMap().get("di").get(0);
+            if (di != null) {
+                uriQuery.append("&");
+                uriQuery.append("di" + "=");
+                uriQuery.append(di);
+            }
+        }
+
+        StringBuffer uriPath = new StringBuffer();
+        uriPath.append(Constants.PREFIX_WELL_KNOWN + "/");
+        uriPath.append(Constants.PREFIX_OCF + "/");
+        uriPath.append(Constants.ACCOUNT_URI + "/");
+        uriPath.append(Constants.DEVICE_URI);
+
+        IRequest requestToAS = MessageBuilder.createRequest(RequestMethod.GET,
+                uriPath.toString(), uriQuery.toString());
+
+        mASServer.sendRequest(requestToAS,
+                new AccountReceiveHandler(request, srcDevice));
+    }
+}
diff --git a/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java b/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java
deleted file mode 100644 (file)
index 311dec9..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-package org.iotivity.cloud.ciserver.testci;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
-import org.iotivity.cloud.base.SessionManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.ciserver.Constants;
-import org.iotivity.cloud.ciserver.protocols.CoapAuthHandler;
-import org.iotivity.cloud.ciserver.protocols.CoapRelayHandler;
-import org.iotivity.cloud.ciserver.resources.KeepAliveResource;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.CoapLogHandler;
-import org.junit.Test;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-public class TestCloudInterface {
-
-    private SessionManager  sessionManager  = new SessionManager();
-    private ResourceManager resourceManager = new ResourceManager();
-
-    private CoapServer        coapServer        = null;
-    private CoapClient        coapClient        = null;
-    private CoapRelayHandler  coapRelayHandler  = new CoapRelayHandler(
-            sessionManager);
-    private KeepAliveResource keepAliveResource = new KeepAliveResource(
-            sessionManager, new int[] { 1, 2, 4, 8 });
-
-    static class CoapClientHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-
-        ChannelHandlerContext connectCtx = null;
-
-        @Override
-        public void channelActive(ChannelHandlerContext ctx) throws Exception {
-            connectCtx = ctx;
-        }
-
-        @Override
-        protected void channelRead0(ChannelHandlerContext arg0,
-                CoapResponse arg1) throws Exception {
-            // TODO : receive response
-            System.out.println("Get Response");
-        }
-    }
-
-    public void startServer() throws Exception {
-
-        coapServer = new CoapServer();
-
-        coapServer.addHandler(new CoapLogHandler());
-        coapServer.addHandler(coapRelayHandler);
-
-        coapServer.addHandler(resourceManager);
-        resourceManager.registerResource(keepAliveResource);
-
-        coapServer.startServer(new InetSocketAddress(5683));
-    }
-
-    public ChannelHandlerContext startClient() throws Exception {
-
-        coapClient = new CoapClient();
-
-        CoapClientHandler coapHandler = new CoapClientHandler();
-        coapClient.addHandler(coapHandler);
-
-        coapClient.addHandler(new CoapAuthHandler());
-
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        return coapHandler.connectCtx;
-    }
-
-    public CoapRequest makePayload(CoapRequest request) throws Exception {
-        ArrayList<Object> payload = new ArrayList<Object>();
-
-        HashMap<Object, Object> tags = new HashMap<Object, Object>();
-        tags.put("di", "98f7483c-5a31-4161-ba7e-9c13e0d");
-        tags.put("bm", (int) 1);
-        tags.put("ttl", (int) 86400);
-
-        ArrayList<LinkedHashMap<Object, Object>> publishLinks = new ArrayList<LinkedHashMap<Object, Object>>();
-        LinkedHashMap<Object, Object> link = new LinkedHashMap<Object, Object>();
-        link.put("href", "/a/light");
-        ArrayList<String> rt = new ArrayList<String>();
-        ArrayList<String> itf = new ArrayList<String>();
-        ArrayList<String> mt = new ArrayList<String>();
-        rt.add("core.light");
-        link.put("rt", rt);
-
-        itf.add("oic.if.baseline");
-        link.put("if", itf);
-
-        mt.add("application/json");
-        link.put("mt", mt);
-
-        link.put("ins", 1);
-
-        publishLinks.add(link);
-
-        payload.add(tags);
-        payload.add(publishLinks);
-
-        Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
-
-        request.setPayload(cbor.encodingPayloadToCbor(payload));
-
-        return request;
-    }
-
-    public CoapRequest makeinterval(CoapRequest request) throws Exception {
-
-        HashMap<Object, Object> payload = new HashMap<Object, Object>();
-        payload.put("in", 1);
-
-        Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
-
-        request.setPayload(cbor.encodingPayloadToCbor(payload));
-
-        return request;
-    }
-
-    @Test
-    public void TestKeepAlivePutInterval() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.PUT);
-        request.setUriPath(Constants.KEEP_ALIVE_URI);
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makeinterval(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        System.out.println("Waiting for KeepAliveTask..");
-        Thread.sleep(30000);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void TestKeepAliveGetFirst() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.KEEP_ALIVE_URI);
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void TestDiscoveryDevice() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.WELL_KNOWN_URI);
-        request.setUriQuery("rt=oic.wk.rdpub");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void TestPublishDevice() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.POST);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("rt=oic.wk.rdpub");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makePayload(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void TestAuthURI() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.AUTH_URI);
-        request.setUriQuery("rt=oic.wk.rdpub");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makePayload(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void TestRequestGetMessageToDeviceCIOwner() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(
-                "/10.113.64.98/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makePayload(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapServer.stopServer();
-        coapClient.stopClient();
-    }
-
-    @Test
-    public void TestRequestGetMessageToDeviceNotCIOwner() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(
-                "/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makePayload(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapServer.stopServer();
-        coapClient.stopClient();
-    }
-
-    @Test
-    public void TestRequestPutMessageToDevice() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.PUT);
-        request.setUriPath(
-                "/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        makePayload(request);
-
-        startServer();
-        startClient();
-
-        coapClient.sendRequest(request);
-
-        coapServer.stopServer();
-        coapClient.stopClient();
-    }
-}
diff --git a/cloud/messagequeue/.classpath b/cloud/messagequeue/.classpath
new file mode 100644 (file)
index 0000000..af1430b
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" output="target/classes" path="src/main/java">
+               <attributes>
+                       <attribute name="optional" value="true"/>
+                       <attribute name="maven.pomderived" value="true"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+               <attributes>
+                       <attribute name="optional" value="true"/>
+                       <attribute name="maven.pomderived" value="true"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+               <attributes>
+                       <attribute name="maven.pomderived" value="true"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+               <attributes>
+                       <attribute name="maven.pomderived" value="true"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/cloud/messagequeue/.gitignore b/cloud/messagequeue/.gitignore
new file mode 100644 (file)
index 0000000..b83d222
--- /dev/null
@@ -0,0 +1 @@
+/target/
diff --git a/cloud/messagequeue/pom.xml b/cloud/messagequeue/pom.xml
new file mode 100644 (file)
index 0000000..5273a5f
--- /dev/null
@@ -0,0 +1,95 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.iotivity.cloud</groupId>
+       <artifactId>CloudMessageQueue</artifactId>
+       <version>0.0.1-SNAPSHOT</version>
+
+       <properties>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.test.skip>true</maven.test.skip>
+       </properties>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.iotivity.cloud</groupId>
+                       <artifactId>CloudStack</artifactId>
+                       <version>0.0.1-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.mongodb</groupId>
+                       <artifactId>mongo-java-driver</artifactId>
+                       <version>3.2.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.12</version>
+               </dependency>
+               <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka_2.11</artifactId>
+            <version>0.9.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jmxri</artifactId>
+                    <groupId>com.sun.jmx</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jmxtools</artifactId>
+                    <groupId>com.sun.jdmk</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jms</artifactId>
+                    <groupId>javax.jms</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+       </dependencies>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <inherited>true</inherited>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <configuration>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
+                                       <encoding>UTF-8</encoding>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                               <configuration>
+                                       <archive>
+                                               <manifest>
+                                                       <mainClass>org.iotivity.cloud.mqserver.MessageQueueServer</mainClass>
+                                                       <addClasspath>true</addClasspath>
+                                                       <classpathPrefix>lib/</classpathPrefix>
+                                               </manifest>
+                                       </archive>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <id>copy-dependencies</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>copy-dependencies</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                               <configuration>
+                                       <outputDirectory>target/lib</outputDirectory>
+                                       <overWriteIfNewer>true</overWriteIfNewer>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+
+</project>
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/Constants.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/Constants.java
new file mode 100644 (file)
index 0000000..23d6318
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver;
+
+import org.iotivity.cloud.base.OCFConstants;
+
+public class Constants extends OCFConstants {
+
+    public static final String MQ_TOPIC                = "topic";
+    public static final String MQ_LOCATION             = "location";
+    public static final String MQ_TOPICLIST            = "topiclist";
+
+    public static final long   MIN_SEQ_NUM             = 5;
+    public static final long   MAX_SEQ_NUM             = 16777215;
+
+    // For Kafka
+    public static final int    KAFKA_SESSION_TIMEOUT   = 10000;
+    public static final int    KAFKA_CONNECT_TIMEOUT   = 10000;
+
+    public static final int    KAFKA_CONSUMMER_THREADS = 1;
+
+    public static final String KAFKA_COMMIT_INTERVAL   = "6000";
+
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueServer.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueServer.java
new file mode 100644 (file)
index 0000000..50dda52
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver;
+
+import java.net.InetSocketAddress;
+import java.util.Scanner;
+
+import org.iotivity.cloud.base.ServerSystem;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.mqserver.resources.MQBrokerResource;
+import org.iotivity.cloud.util.ErrorLogger;
+import org.iotivity.cloud.util.FileLogger;
+import org.iotivity.cloud.util.Logger;
+
+public class MessageQueueServer {
+
+    public static void main(String[] args) throws Exception {
+        System.setOut(FileLogger.createLoggingProxy(System.out));
+
+        System.out.println("-----MQ SERVER-----");
+
+        if (args.length != 6) {
+            Logger.e("coap server port, Kafka_zookeeper_Address port"
+                    + " and Kafka_broker_Address Port and TLS mode required\n"
+                    + "ex) 5686 127.0.0.1 2181 127.0.0.1 9092 0\n");
+
+            return;
+        }
+
+        ErrorLogger.Init();
+
+        ServerSystem serverSystem = new ServerSystem();
+
+        MQBrokerResource MQBroker = new MQBrokerResource();
+
+        String kafka_zookeeper = args[1] + ":" + args[2];
+        String kafka_broker = args[3] + ":" + args[4];
+        MQBroker.setKafkaInformation(kafka_zookeeper, kafka_broker);
+
+        serverSystem.addResource(MQBroker);
+
+        serverSystem.addServer(new CoapServer(
+                new InetSocketAddress(Integer.parseInt(args[0]))));
+
+        boolean tlsMode = Integer.parseInt(args[5]) == 1;
+
+        serverSystem.startSystem(tlsMode);
+
+        Scanner in = new Scanner(System.in, "UTF-8");
+
+        System.out.println("press 'q' to terminate");
+
+        while (!in.nextLine().equals("q"));
+
+        in.close();
+
+        System.out.println("Terminating...");
+
+        serverSystem.stopSystem();
+
+        System.out.println("Terminated");
+    }
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueUtils.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueUtils.java
new file mode 100644 (file)
index 0000000..19ba50a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver;
+
+import java.util.HashMap;
+
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Logger;
+
+public class MessageQueueUtils {
+
+    public static <T> T extractDataFromPayload(byte[] payload, String key) {
+
+        if (payload == null || key.isEmpty()) {
+            Logger.e("payload or key is empty");
+            return null;
+        }
+
+        Cbor<HashMap<String, T>> cbor = new Cbor<>();
+        HashMap<String, T> parsedData = null;
+
+        parsedData = cbor.parsePayloadFromCbor(payload, HashMap.class);
+
+        if (parsedData == null || parsedData.containsKey(key) == false) {
+            Logger.e("payload doesn't contain " + key + " information");
+            return null;
+        }
+
+        return parsedData.get(key);
+    }
+
+    public static <T> byte[] buildPayload(String key, T value) {
+
+        Cbor<HashMap<String, T>> cbor = new Cbor<>();
+
+        HashMap<String, T> map = new HashMap<>();
+        map.put(key, value);
+
+        return cbor.encodingPayloadToCbor(map);
+    }
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaCommonWrapper.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaCommonWrapper.java
new file mode 100644 (file)
index 0000000..0e876bf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.kafka;
+
+import java.util.Properties;
+
+import kafka.admin.AdminUtils;
+import kafka.utils.ZKStringSerializer$;
+import kafka.utils.ZkUtils;
+
+import org.I0Itec.zkclient.ZkClient;
+import org.I0Itec.zkclient.ZkConnection;
+import org.iotivity.cloud.mqserver.Constants;
+import org.iotivity.cloud.util.Logger;
+
+public class KafkaCommonWrapper {
+
+    private ZkClient mZkClient = null;
+    private ZkUtils  mZkUtils  = null;
+
+    public KafkaCommonWrapper(String zookeeperAddress, String brokerAddress) {
+
+        mZkClient = new ZkClient(zookeeperAddress,
+                Constants.KAFKA_SESSION_TIMEOUT,
+                Constants.KAFKA_CONNECT_TIMEOUT, ZKStringSerializer$.MODULE$);
+
+        mZkUtils = new ZkUtils(mZkClient, new ZkConnection(zookeeperAddress),
+                false);
+    }
+
+    public boolean createTopic(String topic) {
+
+        Logger.d("kafka createTopic - " + topic);
+
+        topic = topic.replace('/', '.');
+
+        try {
+            // TODO check options - partitions, replicationFactor
+            AdminUtils.createTopic(mZkUtils, topic, 1, 1, new Properties());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        return true;
+    }
+
+    public boolean deleteTopic(String topic) {
+
+        Logger.d("kafka deleteTopic - " + topic);
+
+        topic = topic.replace('/', '.');
+
+        try {
+            AdminUtils.deleteTopic(mZkUtils, topic);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaConsumerWrapper.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaConsumerWrapper.java
new file mode 100644 (file)
index 0000000..8c151c3
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.kafka;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import kafka.admin.AdminUtils;
+import kafka.api.FetchRequest;
+import kafka.api.FetchRequestBuilder;
+import kafka.api.PartitionOffsetRequestInfo;
+import kafka.common.TopicAndPartition;
+import kafka.consumer.Consumer;
+import kafka.consumer.ConsumerConfig;
+import kafka.consumer.KafkaStream;
+import kafka.javaapi.FetchResponse;
+import kafka.javaapi.OffsetResponse;
+import kafka.javaapi.consumer.ConsumerConnector;
+import kafka.javaapi.consumer.SimpleConsumer;
+import kafka.javaapi.message.ByteBufferMessageSet;
+import kafka.message.MessageAndMetadata;
+import kafka.message.MessageAndOffset;
+import kafka.utils.ZKStringSerializer$;
+import kafka.utils.ZkUtils;
+
+import org.I0Itec.zkclient.ZkClient;
+import org.I0Itec.zkclient.ZkConnection;
+import org.iotivity.cloud.mqserver.Constants;
+import org.iotivity.cloud.mqserver.topic.Topic;
+import org.iotivity.cloud.util.Logger;
+
+public class KafkaConsumerWrapper {
+
+    private String            mTopicName         = null;
+
+    private String            mZookeeper         = null;
+    private String            mBroker            = null;
+
+    private ZkClient          mZkClient          = null;
+    private ZkUtils           mZkUtils           = null;
+
+    private ConsumerConnector mConsumerConnector = null;
+    private ExecutorService   mConsumerExecutor  = null;
+
+    private Topic             mInternalConsumer  = null;
+
+    private boolean           mConsumerStarted   = false;
+
+    public KafkaConsumerWrapper(String zookeeperAddress, String brokerAddress,
+            Topic consumer) {
+
+        mTopicName = consumer.getName().replace("/", ".");
+
+        mZookeeper = zookeeperAddress;
+        mBroker = brokerAddress;
+        mInternalConsumer = consumer;
+
+        mZkClient = new ZkClient(zookeeperAddress,
+                Constants.KAFKA_SESSION_TIMEOUT,
+                Constants.KAFKA_CONNECT_TIMEOUT, ZKStringSerializer$.MODULE$);
+
+        mZkUtils = new ZkUtils(mZkClient, new ZkConnection(zookeeperAddress),
+                false);
+    }
+
+    public boolean consumerStarted() {
+        return mConsumerStarted;
+    }
+
+    // TODO exception handling
+    public boolean subscribeTopic() {
+
+        Logger.d("kafka subscribeTopic - " + mTopicName);
+
+        if (mConsumerStarted == true) {
+            return true;
+        }
+
+        // remove consumer group info if already exist
+        List<String> subscribers = mZkClient.getChildren(ZkUtils
+                .ConsumersPath());
+
+        if (subscribers.contains(mTopicName)) {
+            AdminUtils.deleteConsumerGroupInZK(mZkUtils, mTopicName);
+        }
+
+        ConsumerConfig consumerConfig = new ConsumerConfig(
+                buildPropertiesForSubscribe());
+
+        mConsumerConnector = Consumer
+                .createJavaConsumerConnector(consumerConfig);
+
+        Map<String, Integer> topicCountMap = new HashMap<>();
+        topicCountMap.put(mTopicName, Constants.KAFKA_CONSUMMER_THREADS);
+
+        Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = mConsumerConnector
+                .createMessageStreams(topicCountMap);
+
+        List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(mTopicName);
+
+        mConsumerExecutor = Executors
+                .newFixedThreadPool(Constants.KAFKA_CONSUMMER_THREADS);
+
+        for (final KafkaStream<byte[], byte[]> stream : streams) {
+
+            Logger.d("kafka subscribe complete");
+
+            mConsumerExecutor.execute(new Runnable() {
+
+                public void run() {
+
+                    for (final MessageAndMetadata<byte[], byte[]> messageAndMetadata : stream) {
+
+                        mInternalConsumer.onMessagePublished(messageAndMetadata
+                                .message());
+                    }
+                }
+            });
+        }
+
+        mConsumerStarted = true;
+
+        return true;
+    }
+
+    public boolean unsubscribeTopic() {
+
+        Logger.d("kafka unsubscribeTopic - " + mTopicName);
+
+        // remove consumer group info in zookeeper
+        List<String> subscribers = mZkClient.getChildren(ZkUtils
+                .ConsumersPath());
+
+        if (subscribers.contains(mTopicName)) {
+            AdminUtils.deleteConsumerGroupInZK(mZkUtils, mTopicName);
+        }
+
+        mConsumerExecutor.shutdown();
+        mConsumerConnector.shutdown();
+
+        mConsumerStarted = false;
+
+        return true;
+    }
+
+    public ArrayList<byte[]> getMessages() {
+
+        Logger.d("kafka get all messages - " + mTopicName);
+
+        String brokerHost = mBroker.substring(0, mBroker.indexOf(':'));
+        int brokerPort = Integer.parseInt(mBroker.substring(mBroker
+                .indexOf(':') + 1));
+
+        Logger.d("host " + brokerHost + ", port " + brokerPort);
+
+        // TODO check options - Timeout: Int, bufferSize: Int
+        SimpleConsumer simpleConsumer = new SimpleConsumer(brokerHost,
+                brokerPort, 100000, 64 * 1024, mTopicName);
+
+        long lastOffset = getLastOffset(simpleConsumer, mTopicName, 0,
+                kafka.api.OffsetRequest.EarliestTime(), mTopicName);
+
+        // TODO check option - fetch size
+        FetchRequest req = new FetchRequestBuilder().clientId(mTopicName)
+                .addFetch(mTopicName, 0, lastOffset, 100000).build();
+
+        FetchResponse fetchResponse = simpleConsumer.fetch(req);
+
+        if (fetchResponse == null || fetchResponse.hasError()) {
+
+            Logger.e("Error fetching data from the Broker");
+            return null;
+        }
+
+        ArrayList<byte[]> initialData = new ArrayList<>();
+
+        ByteBufferMessageSet messageSet = fetchResponse.messageSet(mTopicName,
+                0);
+
+        if (messageSet != null) {
+            for (MessageAndOffset messageAndOffset : messageSet) {
+
+                long currentOffset = messageAndOffset.offset();
+                if (currentOffset < lastOffset) {
+                    Logger.e("Found an old offset: " + currentOffset
+                            + " Expecting: " + lastOffset);
+                    continue;
+                }
+
+                lastOffset = messageAndOffset.nextOffset();
+                ByteBuffer payload = messageAndOffset.message().payload();
+
+                byte[] bytes = new byte[payload.limit()];
+                payload.get(bytes);
+
+                initialData.add(bytes);
+            }
+        }
+
+        simpleConsumer.close();
+
+        Logger.d("kafka get all messages complete");
+
+        return initialData;
+    }
+
+    private Properties buildPropertiesForSubscribe() {
+
+        // TODO check property settings
+        Properties props = new Properties();
+
+        props.put("group.id", mTopicName);
+        props.put("zookeeper.connect", mZookeeper);
+        props.put("enable.auto.commit", "true");
+        props.put("auto.commit.interval.ms", Constants.KAFKA_COMMIT_INTERVAL);
+
+        return props;
+    }
+
+    private long getLastOffset(SimpleConsumer consumer, String topic,
+            int partition, long whichTime, String clientName) {
+
+        TopicAndPartition topicAndPartition = new TopicAndPartition(topic,
+                partition);
+
+        Map<TopicAndPartition, PartitionOffsetRequestInfo> requestInfo = new HashMap<>();
+        requestInfo.put(topicAndPartition, new PartitionOffsetRequestInfo(
+                whichTime, 1));
+
+        kafka.javaapi.OffsetRequest request = new kafka.javaapi.OffsetRequest(
+                requestInfo, kafka.api.OffsetRequest.CurrentVersion(),
+                clientName);
+
+        OffsetResponse response = consumer.getOffsetsBefore(request);
+
+        if (response == null || response.hasError()) {
+            Logger.e("Error fetching data Offset Data the Broker");
+            return 0;
+        }
+
+        long[] offsets = response.offsets(topic, partition);
+        return offsets[0];
+    }
+
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaProducerWrapper.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaProducerWrapper.java
new file mode 100644 (file)
index 0000000..903f046
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.kafka;
+
+import java.util.Properties;
+
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.Producer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.iotivity.cloud.util.Logger;
+
+public class KafkaProducerWrapper {
+
+    private String                   mTopicName = null;
+    private String                   mBroker    = null;
+
+    private Producer<byte[], byte[]> mProducer  = null;
+
+    public KafkaProducerWrapper(String brokerAddress, String topic) {
+
+        mTopicName = topic.replace("/", ".");
+
+        mBroker = brokerAddress;
+
+        mProducer = new KafkaProducer<>(buildPropertiesForPublish());
+    }
+
+    // TODO handle exception
+    public boolean publishMessage(byte[] message) {
+
+        Logger.d("kafka publishMessage - " + mTopicName);
+
+        ProducerRecord<byte[], byte[]> record = new ProducerRecord<>(
+                mTopicName, message);
+
+        mProducer.send(record);
+        mProducer.flush();
+
+        return true;
+    }
+
+    private Properties buildPropertiesForPublish() {
+
+        // TODO check property settings
+        Properties props = new Properties();
+
+        props.put("bootstrap.servers", mBroker);
+        props.put("acks", "all");
+        props.put("retries", 0);
+        props.put("batch.size", 16384);
+        props.put("linger.ms", 1);
+        props.put("buffer.memory", 33554432);
+        props.put("key.serializer",
+                "org.apache.kafka.common.serialization.ByteArraySerializer");
+        props.put("value.serializer",
+                "org.apache.kafka.common.serialization.ByteArraySerializer");
+
+        return props;
+    }
+
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/resources/MQBrokerResource.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/resources/MQBrokerResource.java
new file mode 100644 (file)
index 0000000..a137f75
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.resources;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.mqserver.Constants;
+import org.iotivity.cloud.mqserver.MessageQueueUtils;
+import org.iotivity.cloud.mqserver.topic.Topic;
+import org.iotivity.cloud.mqserver.topic.TopicManager;
+
+public class MQBrokerResource extends Resource {
+
+    private TopicManager mTopicManager = new TopicManager();
+
+    public MQBrokerResource() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.MQ_BROKER_URI));
+
+        // addQueryHandler(Arrays.asList("if=" + Constants.INTERFACE_DEFAULT),
+        // this::onDefaultInterfaceReceived);
+    }
+
+    public void setKafkaInformation(String zookeeper, String broker) {
+        mTopicManager.setKafkaInformation(zookeeper, broker);
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case GET:
+                response = handleGetRequest(srcDevice, request);
+                break;
+            case PUT:
+                response = handlePutRequest(request);
+                break;
+            case POST:
+                response = handlePostRequest(request);
+                break;
+            case DELETE:
+                response = handleDeleteRequest(request);
+                break;
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    // DISCOVER, READ, SUBSCRIBE, UNSUBSCRIBE
+    private IResponse handleGetRequest(Device srcDevice, IRequest request) {
+
+        // DISCOVER
+        if (request.getUriPathSegments().size() == getUriPathSegments()
+                .size()) {
+            return discoverTopic(request);
+        }
+
+        switch (request.getObserve()) {
+            case NOTHING:
+                return readMessage(request);
+
+            case SUBSCRIBE:
+                return subscribeTopic(srcDevice, request);
+
+            case UNSUBSCRIBE:
+                return unsubscribeTopic(request);
+
+            default:
+                break;
+        }
+
+        return MessageBuilder.createResponse(request,
+                ResponseStatus.BAD_REQUEST);
+    }
+
+    // PUBLISH
+    private IResponse handlePutRequest(IRequest request) {
+
+        return publishMessage(request);
+    }
+
+    // CREATE topic
+    private IResponse handlePostRequest(IRequest request) {
+
+        return createTopic(request);
+    }
+
+    // REMOVE topic
+    private IResponse handleDeleteRequest(IRequest request) {
+
+        return removeTopic(request);
+    }
+
+    private IResponse createTopic(IRequest request) {
+
+        String uriPath = request.getUriPath();
+
+        // main topic creation request
+        if (request.getUriPathSegments().size() == getUriPathSegments()
+                .size()) {
+            return createMainTopic(request);
+        }
+
+        // subtopic creation request
+        Topic targetTopic = mTopicManager.getTopic(uriPath);
+
+        if (targetTopic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return targetTopic.handleCreateSubtopic(request);
+    }
+
+    private IResponse removeTopic(IRequest request) {
+
+        String uriPath = request.getUriPath();
+
+        String parentName = uriPath.substring(0, uriPath.lastIndexOf('/'));
+        String targetName = request.getUriPathSegments()
+                .get(request.getUriPathSegments().size() - 1);
+
+        // main topic removal request
+        if (request.getUriPathSegments().size() - 1 == getUriPathSegments()
+                .size()) {
+            return removeMainTopic(request);
+        }
+
+        // subtopic removal request
+        Topic parentTopic = mTopicManager.getTopic(parentName);
+
+        if (parentTopic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return parentTopic.handleRemoveSubtopic(request, targetName);
+    }
+
+    private IResponse subscribeTopic(Device srcDevice, IRequest request) {
+
+        Topic topic = mTopicManager.getTopic(request.getUriPath());
+
+        if (topic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return topic.handleSubscribeTopic(srcDevice, request);
+    }
+
+    private IResponse unsubscribeTopic(IRequest request) {
+
+        Topic topic = mTopicManager.getTopic(request.getUriPath());
+
+        if (topic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return topic.handleUnsubscribeTopic(request);
+    }
+
+    private IResponse publishMessage(IRequest request) {
+
+        Topic topic = mTopicManager.getTopic(request.getUriPath());
+
+        if (topic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return topic.handlePublishMessage(request);
+    }
+
+    private IResponse readMessage(IRequest request) {
+
+        Topic topic = mTopicManager.getTopic(request.getUriPath());
+
+        if (topic == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        return topic.handleReadMessage(request);
+    }
+
+    private IResponse discoverTopic(IRequest request) {
+
+        ArrayList<String> topicList = null;
+
+        HashMap<String, List<String>> query = request.getUriQueryMap();
+
+        if (query != null && query.containsKey("rt")) {
+
+            topicList = mTopicManager
+                    .getTopicListByType(query.get("rt").get(0));
+        } else {
+
+            topicList = mTopicManager.getTopicList();
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR, MessageQueueUtils
+                        .buildPayload(Constants.MQ_TOPICLIST, topicList));
+    }
+
+    private IResponse createMainTopic(IRequest request) {
+
+        String topicName = MessageQueueUtils.extractDataFromPayload(
+                request.getPayload(), Constants.MQ_TOPIC);
+
+        String type = new String();
+
+        if (request.getUriQueryMap() != null) {
+            type = request.getUriQueryMap().get("rt").get(0);
+        }
+
+        if (topicName == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        topicName = "/" + Constants.PREFIX_OIC + "/" + Constants.MQ_BROKER_URI
+                + "/" + topicName;
+
+        if (mTopicManager.getTopic(topicName) != null) {
+            // Topic already exists
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        Topic newTopic = new Topic(topicName, type, mTopicManager);
+
+        if (mTopicManager.createTopic(newTopic) == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CREATED,
+                ContentFormat.APPLICATION_CBOR, MessageQueueUtils.buildPayload(
+                        Constants.MQ_LOCATION, newTopic.getName()));
+    }
+
+    private IResponse removeMainTopic(IRequest request) {
+
+        String topicName = request.getUriPath();
+
+        Topic targetTopic = mTopicManager.getTopic(topicName);
+
+        // TODO check error
+        if (targetTopic == null) {
+            // Topic doesn't exist
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        if (mTopicManager.removeTopic(targetTopic) == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
+    }
+}
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/Topic.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/Topic.java
new file mode 100644 (file)
index 0000000..3b004c1
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.topic;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.mqserver.Constants;
+import org.iotivity.cloud.mqserver.MessageQueueUtils;
+import org.iotivity.cloud.mqserver.kafka.KafkaConsumerWrapper;
+import org.iotivity.cloud.mqserver.kafka.KafkaProducerWrapper;
+
+public class Topic {
+
+    private TopicManager           mTopicManager = null;
+
+    private String                 mName         = null;
+    private String                 mType         = null;
+    private HashMap<String, Topic> mSubtopics    = null;
+
+    private byte[]                 mLatestData   = null;
+
+    private class TopicSubscriber {
+        TopicSubscriber(Device subscriber, IRequest request) {
+            mSubscriber = subscriber;
+            mRequest = request;
+        }
+
+        public Device   mSubscriber;
+        public IRequest mRequest;
+    }
+
+    private HashMap<String, TopicSubscriber> mSubscribers           = null;
+
+    private KafkaProducerWrapper             mKafkaProducerOperator = null;
+    private KafkaConsumerWrapper             mKafkaConsumerOperator = null;
+
+    public Topic(String name, String type, TopicManager topicManager) {
+
+        mTopicManager = topicManager;
+        mName = name;
+        mType = type;
+
+        mSubtopics = new HashMap<>();
+        mSubscribers = new HashMap<>();
+
+        String kafka_zookeeper = topicManager.getKafkaZookeeper();
+        String kafka_broker = topicManager.getKafkaBroker();
+
+        mKafkaProducerOperator = new KafkaProducerWrapper(kafka_broker, name);
+        mKafkaConsumerOperator = new KafkaConsumerWrapper(kafka_zookeeper,
+                kafka_broker, this);
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public String getType() {
+        return mType;
+    }
+
+    public IResponse handleCreateSubtopic(IRequest request) {
+
+        String newTopicName = MessageQueueUtils.extractDataFromPayload(
+                request.getPayload(), Constants.MQ_TOPIC);
+
+        String newTopicType = new String();
+
+        if (request.getUriQueryMap() != null) {
+            newTopicType = request.getUriQueryMap().get("rt").get(0);
+        }
+
+        if (newTopicName == null) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        if (getSubtopic(newTopicName) != null) {
+            // topic already exists
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        Topic newTopic = new Topic(mName + "/" + newTopicName, newTopicType,
+                mTopicManager);
+
+        if (mTopicManager.createTopic(newTopic) == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        mSubtopics.put(newTopicName, newTopic);
+
+        return MessageBuilder.createResponse(
+                request,
+                ResponseStatus.CREATED,
+                ContentFormat.APPLICATION_CBOR,
+                MessageQueueUtils.buildPayload(Constants.MQ_LOCATION,
+                        newTopic.getName()));
+    }
+
+    public IResponse handleRemoveSubtopic(IRequest request, String topicName) {
+
+        Topic targetTopic = getSubtopic(topicName);
+
+        // TODO check error
+        if (targetTopic == null) {
+            // topic doesn't exist
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.BAD_REQUEST);
+        }
+
+        if (mTopicManager.removeTopic(targetTopic) == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        mSubtopics.remove(topicName);
+
+        return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
+    }
+
+    public IResponse handleSubscribeTopic(Device srcDevice, IRequest request) {
+
+        // get latest data from kafka if cosumer started for the first time
+        if (mKafkaConsumerOperator.consumerStarted() == false) {
+
+            ArrayList<byte[]> data = mKafkaConsumerOperator.getMessages();
+
+            if (data != null && !data.isEmpty()) {
+                mLatestData = data.get(data.size() - 1);
+            }
+        }
+
+        if (mKafkaConsumerOperator.subscribeTopic() == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        synchronized (mSubscribers) {
+            mSubscribers.put(request.getRequestId(), new TopicSubscriber(
+                    srcDevice, request));
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR, mLatestData);
+    }
+
+    public IResponse handleUnsubscribeTopic(IRequest request) {
+
+        synchronized (mSubscribers) {
+
+            TopicSubscriber subscriber = mSubscribers.get(request
+                    .getRequestId());
+
+            if (subscriber == null) {
+                // client is not a subscriber
+                return MessageBuilder.createResponse(request,
+                        ResponseStatus.BAD_REQUEST);
+            }
+
+            mSubscribers.remove(subscriber.mRequest.getRequestId());
+
+            // if there's no more subscriber, stop subscribing topic
+            // with kafka consumer
+            if (mSubscribers.isEmpty()) {
+                mKafkaConsumerOperator.unsubscribeTopic();
+            }
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR, mLatestData);
+    }
+
+    public IResponse handlePublishMessage(IRequest request) {
+        byte[] data = request.getPayload();
+
+        if (mKafkaProducerOperator.publishMessage(data) == false) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
+    }
+
+    public IResponse handleReadMessage(IRequest request) {
+        // if consumer is not started, get data from kafka broker
+        if (mKafkaConsumerOperator.consumerStarted() == false) {
+
+            ArrayList<byte[]> data = mKafkaConsumerOperator.getMessages();
+
+            if (data != null && !data.isEmpty()) {
+                mLatestData = data.get(data.size() - 1);
+            }
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR, mLatestData);
+    }
+
+    // callback from Kafka Consumer
+    public void onMessagePublished(byte[] message) {
+
+        mLatestData = message;
+
+        notifyPublishedMessage();
+    }
+
+    // TODO check
+    private Topic getSubtopic(String topicName) {
+
+        if (mSubtopics.containsKey(topicName) == false) {
+            return null;
+        }
+
+        return mSubtopics.get(topicName);
+    }
+
+    private void notifyPublishedMessage() {
+        synchronized (mSubscribers) {
+            for (TopicSubscriber subscriber : mSubscribers.values()) {
+                subscriber.mSubscriber.sendResponse(MessageBuilder
+                        .createResponse(subscriber.mRequest,
+                                ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR, mLatestData));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/TopicManager.java b/cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/TopicManager.java
new file mode 100644 (file)
index 0000000..c36a510
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.mqserver.topic;
+
+import java.util.ArrayList;
+
+import org.iotivity.cloud.mqserver.kafka.KafkaCommonWrapper;
+
+public class TopicManager {
+
+    private ArrayList<Topic>   mTopics              = new ArrayList<>();
+
+    // for Kafka
+    String                     mKafkaZookeeper      = null;
+    String                     mKafkaBroker         = null;
+
+    private KafkaCommonWrapper mKafkaCommonOperator = null;
+
+    public boolean createTopic(Topic topic) {
+
+        if (mKafkaCommonOperator.createTopic(topic.getName()) == false) {
+            return false;
+        }
+
+        synchronized (mTopics) {
+            mTopics.add(topic);
+        }
+
+        return true;
+    }
+
+    public boolean removeTopic(Topic topic) {
+
+        return removeTopics(topic.getName());
+    }
+
+    public ArrayList<String> getTopicList() {
+
+        ArrayList<String> topicList = new ArrayList<>();
+
+        synchronized (mTopics) {
+            for (Topic topic : mTopics) {
+                topicList.add(topic.getName());
+            }
+        }
+
+        return topicList;
+    }
+
+    public ArrayList<String> getTopicListByType(String type) {
+
+        ArrayList<String> topicList = new ArrayList<>();
+
+        synchronized (mTopics) {
+
+            for (Topic topic : mTopics) {
+                if (type.equals(topic.getType())) {
+                    topicList.add(topic.getName());
+                }
+            }
+        }
+
+        return topicList;
+    }
+
+    public Topic getTopic(String topicName) {
+
+        Topic foundTopic = null;
+
+        synchronized (mTopics) {
+
+            for (Topic topic : mTopics) {
+                if (topicName.equals(topic.getName())) {
+                    foundTopic = topic;
+                    break;
+                }
+            }
+        }
+
+        return foundTopic;
+    }
+
+    public void setKafkaInformation(String zookeeper, String broker) {
+        mKafkaZookeeper = zookeeper;
+        mKafkaBroker = broker;
+
+        mKafkaCommonOperator = new KafkaCommonWrapper(zookeeper, broker);
+    }
+
+    public String getKafkaZookeeper() {
+        return mKafkaZookeeper;
+    }
+
+    public String getKafkaBroker() {
+        return mKafkaBroker;
+    }
+
+    private boolean removeTopics(String topicName) {
+
+        synchronized (mTopics) {
+
+            for (Topic topic : new ArrayList<>(mTopics)) {
+
+                if (topic.getName().startsWith(topicName)) {
+
+                    if (mKafkaCommonOperator.deleteTopic(topic.getName()) == false) {
+                        return false;
+                    }
+
+                    mTopics.remove(topic);
+                }
+            }
+        }
+
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/cloud/resourcedirectory/.project b/cloud/resourcedirectory/.project
deleted file mode 100644 (file)
index a12b34d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>CloudResourceDirectory</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.m2e.core.maven2Builder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-               <nature>org.eclipse.m2e.core.maven2Nature</nature>
-       </natures>
-</projectDescription>
index 8976aba..75903e6 100644 (file)
@@ -7,6 +7,7 @@
 
        <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.test.skip>true</maven.test.skip>
        </properties>
 
        <dependencies>
@@ -34,8 +35,8 @@
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
-                                       <source>1.7</source>
-                                       <target>1.7</target>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
                                        <encoding>UTF-8</encoding>
                                </configuration>
                        </plugin>
index 4e14fb6..b32e718 100644 (file)
@@ -1,52 +1,71 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.rdserver;
 
-public class Constants {
-    public static final String RD_TABLE   = "RD_TABLE";
-    public static final String RD_DB_NAME = "RDDB";
-
-    public static final String RD_URI = "oic/rd";
-
-    public static final String RS_DEVICE_NAME             = "n";
-    public static final String RS_DEVICE_ID               = "di";
-    public static final String RS_BASE_URI                = "baseURI";
-    public static final String RS_BITMAP                  = "bm";
-    public static final String RS_HOSTING_PORT            = "port";
-    public static final String RS_INS                     = "ins";
-    public static final String RS_RTS                     = "rts";
-    public static final String RS_DREL                    = "drel";
-    public static final String RS_TTL                     = "ttl";
-    public static final String RS_HREF                    = "href";
-    public static final String RS_RESOURCE_TYPE           = "rt";
-    public static final String RS_INTERFACE               = "if";
-    public static final String RS_REL                     = "rel";
-    public static final String RS_OBS                     = "obs";
-    public static final String RS_TITLE                   = "title";
-    public static final String RS_URI                     = "uri";
-    public static final String RS_MEDIA_TYPE              = "mt";
-    public static final String RS_RESOURCE_TYPE_RDPUBLISH = "oic.wk.rdpub";
-
-    public static final String RS_SEARCH_TYPE             = "st";
-    public static final String RS_SEARCH_TYPE_DEVICE_LIST = "didList";
-    public static final String RS_DEVICE_LIST_KEY         = "devices";
+import java.util.Arrays;
+import java.util.List;
+
+import org.iotivity.cloud.base.OCFConstants;
+
+public class Constants extends OCFConstants {
+
+    public static final String       RD_DB_NAME              = "RD_DB";
+    public static final String       RD_TABLE                = "RD_TABLE";
+    public static final String       PRESENCE_TABLE          = "PRESENCE_TABLE";
+
+    public static final String       DEVICE_NAME             = "n";
+    public static final String       DEVICE_ID               = "di";
+    public static final String       POLICY                  = "p";
+    public static final String       BITMAP                  = "bm";
+    public static final String       INS                     = "ins";
+    public static final String       DEVICE_TTL              = "lt";
+    public static final String       RESOURCE_TTL            = "ttl";
+    public static final String       HREF                    = "href";
+    public static final String       RESOURCE_TYPE           = "rt";
+    public static final String       INTERFACE               = "if";
+    public static final String       REL                     = "rel";
+    public static final String       TITLE                   = "title";
+    public static final String       ANCHOR                  = "anchor";
+    public static final String       MEDIA_TYPE              = "type";
+    public static final String       LINKS                   = "links";
+    public static final String       RESOURCE_TYPE_RDPUBLISH = "oic.wk.rdpub";
+    public static final List<String> TAGS                    = Arrays
+            .asList(DEVICE_NAME, DEVICE_ID, DEVICE_TTL);
+
+    public static final String       SEARCH_TYPE             = "st";
+    public static final String       SEARCH_TYPE_DEVICE_LIST = "didList";
+    public static final String       DEVICE_LIST_KEY         = "devices";
+
+    // for '/oic/prs' resource
+    public static final String       PRESENCE_STATE          = "state";
+
+    public static final String       RS_NON                  = "non";
+    public static final String       RS_TRIGGER              = "trg";
+
+    public static final long         OBSERVE_REGISTER        = 0;
+    public static final long         OBSERVE_DEREGISTER      = 1;
+
+    public static final byte         RES_CREATE              = 0;
+    public static final byte         RES_CHANGE              = 1;
+    public static final byte         RES_DELETE              = 2;
+
 }
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java
deleted file mode 100644 (file)
index 889b9ce..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.rdserver;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.bson.Document;
-import org.iotivity.cloud.rdserver.resources.LinksPayloadFormat;
-import org.iotivity.cloud.rdserver.resources.PublishPayloadFormat;
-
-import com.mongodb.MongoClient;
-import com.mongodb.client.MongoCollection;
-import com.mongodb.client.MongoCursor;
-import com.mongodb.client.MongoDatabase;
-import com.mongodb.client.model.Filters;
-
-/**
- *
- * This class provides a set of APIs to use MongoDB APIs.
- *
- */
-public class MongoDB {
-
-    private MongoClient   mongoClient = null;
-    private MongoDatabase db          = null;
-
-    /**
-     * API creating MongoClient and initializing MongoDatabase
-     *
-     * @param dbname
-     *            database name to create MongoDatabase
-     * @throws Exception
-     */
-    public MongoDB(String dbname) throws Exception {
-        mongoClient = new MongoClient();
-        mongoClient.dropDatabase(dbname);
-        db = mongoClient.getDatabase(dbname);
-    }
-
-    /**
-     * API creating collection
-     *
-     * @param tableName
-     *            collection name
-     */
-    public void createTable(String tableName) {
-        db.createCollection(tableName);
-    }
-
-    /**
-     * API deleting collection
-     *
-     * @param tableName
-     *            collection name
-     */
-    public void deleteTable(String tableName) {
-        db.getCollection(tableName).drop();
-    }
-
-    private ArrayList<Document> createDocuments(
-            PublishPayloadFormat publishPayloadFormat) {
-
-        Iterator<LinksPayloadFormat> linksPayloadFormatIter = publishPayloadFormat
-                .getLinks().iterator();
-        ArrayList<Document> docList = new ArrayList<Document>();
-
-        while (linksPayloadFormatIter.hasNext()) {
-            LinksPayloadFormat links = linksPayloadFormatIter.next();
-            Document doc = new Document(Constants.RS_DEVICE_NAME,
-                    publishPayloadFormat.getDeviceName())
-                            .append(Constants.RS_DEVICE_ID,
-                                    publishPayloadFormat.getDi())
-                            .append(Constants.RS_BASE_URI,
-                                    publishPayloadFormat.getBaseUri())
-                            .append(Constants.RS_BITMAP,
-                                    publishPayloadFormat.getBitmap())
-                            .append(Constants.RS_HOSTING_PORT,
-                                    publishPayloadFormat.getPort())
-                            .append(Constants.RS_INS,
-                                    publishPayloadFormat.getIns())
-                            .append(Constants.RS_RTS,
-                                    publishPayloadFormat.getRts())
-                            .append(Constants.RS_DREL,
-                                    publishPayloadFormat.getDrel())
-                            .append(Constants.RS_TTL,
-                                    publishPayloadFormat.getTtl())
-                            .append(Constants.RS_HREF, links.getHref())
-                            .append(Constants.RS_RESOURCE_TYPE, links.getRt())
-                            .append(Constants.RS_INTERFACE, links.getItf())
-                            .append(Constants.RS_REL, links.getRel())
-                            .append(Constants.RS_OBS, links.isObs())
-                            .append(Constants.RS_TITLE, links.getTitle())
-                            .append(Constants.RS_URI, links.getUri())
-                            .append(Constants.RS_INS, links.getIns())
-                            .append(Constants.RS_MEDIA_TYPE, links.getMt());
-            docList.add(doc);
-        }
-
-        return docList;
-    }
-
-    private PublishPayloadFormat convertDocumentToResourceFormat(Document doc) {
-        PublishPayloadFormat publishPayloadFormat = new PublishPayloadFormat();
-        LinksPayloadFormat linksPayloadFormat = new LinksPayloadFormat();
-        ArrayList<LinksPayloadFormat> list = new ArrayList<LinksPayloadFormat>();
-
-        Object tmp = null;
-        
-        tmp = doc.get(Constants.RS_DEVICE_NAME);
-        if(tmp != null) {
-            publishPayloadFormat
-            .setDeviceName(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_DEVICE_ID);
-        if(tmp != null) {
-            publishPayloadFormat.setDi(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_BASE_URI);
-        if(tmp != null) {
-            publishPayloadFormat.setBaseUri(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_BITMAP);
-        if(tmp != null) {
-            publishPayloadFormat.setBitmap((int)tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_HOSTING_PORT);
-        if(tmp != null) {
-            publishPayloadFormat.setPort((int)tmp);
-        }
-       
-        tmp = doc.get(Constants.RS_INS);
-        if(tmp != null) {
-            publishPayloadFormat.setIns((int)tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_RTS);
-        if(tmp != null) {
-            publishPayloadFormat.setRts(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_DREL);
-        if(tmp != null) {
-            publishPayloadFormat.setDrel(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_TTL);
-        if(tmp != null) {
-            publishPayloadFormat.setTtl((int)tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_HREF);
-        if(tmp != null) {
-            linksPayloadFormat.setHref(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_RESOURCE_TYPE);
-        if(tmp != null) {
-            linksPayloadFormat
-            .setRt((ArrayList<String>) tmp);
-        }
-
-        tmp = doc.get(Constants.RS_INTERFACE);
-        if(tmp != null) {
-            linksPayloadFormat
-            .setItf((ArrayList<String>) tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_REL);
-        if(tmp != null) {
-            linksPayloadFormat.setRel(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_OBS);
-        if(tmp != null) {
-            linksPayloadFormat.setObs((boolean)tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_TITLE);
-        if(tmp != null) {
-            linksPayloadFormat.setTitle(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_URI);
-        if(tmp != null) {
-            linksPayloadFormat.setUri(tmp.toString());
-        }
-        
-        tmp = doc.get(Constants.RS_INS);
-        if(tmp != null) {
-            linksPayloadFormat.setIns((int)tmp);
-        }
-        
-        tmp = doc.get(Constants.RS_MEDIA_TYPE);
-        if(tmp != null) {
-            linksPayloadFormat
-            .setMt((ArrayList<String>) tmp);
-        }
-
-        list.add(linksPayloadFormat);
-        publishPayloadFormat.setLinks(list);
-
-        return publishPayloadFormat;
-    }
-
-    /**
-     * API for storing information of published resources
-     *
-     * @param publishPayloadFormat
-     *            information of published resources to store in collection
-     * @param tablename
-     *            collection name
-     */
-    public void createResource(PublishPayloadFormat publishPayloadFormat,
-            String tablename) {
-        ArrayList<Document> docList = createDocuments(publishPayloadFormat);
-        Iterator<Document> docIter = docList.iterator();
-
-        MongoCollection<Document> collection = db.getCollection(tablename);
-
-        while (docIter.hasNext()) {
-            Document doc = docIter.next();
-
-            if (collection.findOneAndReplace(
-                    Filters.and(Filters.eq(Constants.RS_DEVICE_ID,
-                            doc.get(Constants.RS_DEVICE_ID)),
-                    Filters.eq(Constants.RS_INS, doc.get(Constants.RS_INS))),
-                    doc) == null) {
-
-                collection.insertOne(doc);
-            }
-        }
-    }
-
-    /**
-     * API for finding resources matched filterValue of filterKey in collection
-     *
-     * @param filterKey
-     *            field name in collection
-     * @param filterValue
-     *            field value about field name
-     * @param tablename
-     *            collection name
-     * @return ArrayList<PublishPayloadFormat> - array list of resource
-     *         information
-     */
-    public ArrayList<PublishPayloadFormat> readResource(String filterKey,
-            String filterValue, String tablename) {
-        MongoCollection<Document> collection = db.getCollection(tablename);
-        ArrayList<PublishPayloadFormat> resourceFormatList = new ArrayList<PublishPayloadFormat>();
-        MongoCursor<Document> cursor = collection
-                .find(Filters.eq(filterKey, filterValue)).iterator();
-        try {
-            while (cursor.hasNext()) {
-                Document doc = cursor.next();
-                resourceFormatList.add(convertDocumentToResourceFormat(doc));
-            }
-        } finally {
-            cursor.close();
-        }
-
-        return resourceFormatList;
-    }
-
-    /**
-     * API for finding resources matched filterValue of filterKey and a
-     * particular device ID in collection
-     *
-     * @param di
-     *            device id
-     * @param filterKey
-     *            field name in collection
-     * @param filterValue
-     *            field value about field name
-     * @param tablename
-     *            collection name
-     * @return ArrayList<PublishPayloadFormat> - array list of resource
-     *         information
-     */
-    public ArrayList<PublishPayloadFormat> readResourceAboutDid(String di,
-            String filterKey, String filterValue, String tablename) {
-        MongoCollection<Document> collection = db.getCollection(tablename);
-        ArrayList<PublishPayloadFormat> resourceFormatList = new ArrayList<PublishPayloadFormat>();
-        MongoCursor<Document> cursor = collection
-                .find(Filters.and(Filters.eq(Constants.RS_DEVICE_ID, di),
-                        Filters.eq(filterKey, filterValue)))
-                .iterator();
-        try {
-            while (cursor.hasNext()) {
-                Document doc = cursor.next();
-                resourceFormatList.add(convertDocumentToResourceFormat(doc));
-            }
-        } finally {
-            cursor.close();
-        }
-
-        return resourceFormatList;
-    }
-
-    /**
-     * API for deleting resources about a particular device ID in collection
-     *
-     * @param di
-     *            device id
-     * @param tablename
-     *            collection name
-     */
-    public void deleteResourceAboutDid(String di, String tablename) {
-
-        MongoCollection<Document> collection = db.getCollection(tablename);
-
-        collection.findOneAndDelete(Filters.eq(Constants.RS_DEVICE_ID, di));
-    }
-
-    /**
-     * API for deleting resources about a particular device ID and ins in
-     * collection
-     *
-     * @param di
-     *            device id
-     * @param ins
-     *            ins
-     * @param tablename
-     *            collection name
-     */
-    public void deleteResourceAboutDidAndIns(String di, String ins,
-            String tablename) {
-
-        MongoCollection<Document> collection = db.getCollection(tablename);
-
-        collection.findOneAndDelete(
-                Filters.and(Filters.eq(Constants.RS_DEVICE_ID, di),
-                        Filters.eq(Constants.RS_INS, ins)));
-
-    }
-}
index c420525..24dbb9a 100644 (file)
@@ -1,61 +1,69 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.rdserver;
 
 import java.net.InetSocketAddress;
 import java.util.Scanner;
 
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
-import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource;
+import org.iotivity.cloud.base.ServerSystem;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.rdserver.resources.directory.rd.ResourceDirectoryResource;
+import org.iotivity.cloud.rdserver.resources.directory.res.DiscoveryResource;
+import org.iotivity.cloud.rdserver.resources.presence.device.DevicePresenceResource;
+import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresenceResource;
+import org.iotivity.cloud.util.ErrorLogger;
+import org.iotivity.cloud.util.FileLogger;
 import org.iotivity.cloud.util.Logger;
 
 public class ResourceDirectoryServer {
 
     public static void main(String[] args) throws Exception {
+        System.setOut(FileLogger.createLoggingProxy(System.out));
 
         System.out.println("-----RD SERVER-----");
 
-        if (args.length != 1) {
-            Logger.e("coap server port required");
+        if (args.length != 2) {
+            Logger.e("coap server port and TLS mode required\n"
+                    + "ex) 5684 0\n");
             return;
         }
 
-        ResourceManager resourceManager = null;
+        ErrorLogger.Init();
 
-        CoapServer coapServer = null;
+        ServerSystem serverSystem = new ServerSystem();
 
-        coapServer = new CoapServer();
+        serverSystem.addResource(new ResourceDirectoryResource());
+        serverSystem.addResource(new DiscoveryResource());
+        serverSystem.addResource(new DevicePresenceResource());
+        serverSystem.addResource(new ResPresenceResource());
 
-        resourceManager = new ResourceManager();
+        serverSystem.addServer(new CoapServer(
+                new InetSocketAddress(Integer.parseInt(args[0]))));
 
-        coapServer.addHandler(resourceManager);
+        boolean tlsMode = Integer.parseInt(args[1]) == 1;
 
-        resourceManager.registerResource(new ResourceDirectoryResource());
+        serverSystem.startSystem(tlsMode);
 
-        coapServer
-                .startServer(new InetSocketAddress(Integer.parseInt(args[0])));
-
-        Scanner in = new Scanner(System.in, "UTF-8");
+        Scanner in = new Scanner(System.in);
 
         System.out.println("press 'q' to terminate");
 
@@ -65,7 +73,7 @@ public class ResourceDirectoryServer {
 
         System.out.println("Terminating...");
 
-        coapServer.stopServer();
+        serverSystem.stopSystem();
 
         System.out.println("Terminated");
     }
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/DBManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/DBManager.java
new file mode 100644 (file)
index 0000000..655fec2
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.db;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
+
+public class DBManager {
+
+    private static DBManager mDBManager = new DBManager();
+    private MongoDB          mMongoDB   = null;;
+
+    private DBManager() {
+        try {
+            mMongoDB = new MongoDB(Constants.RD_DB_NAME);
+            mMongoDB.createTable(Constants.RD_TABLE);
+            mMongoDB.createTable(Constants.PRESENCE_TABLE);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    public static DBManager getInstance() {
+        return mDBManager;
+    }
+
+    public ArrayList<ResPresencePayload> registerResource(
+            ArrayList<HashMap<Object, Object>> pubResourceList) {
+        return mMongoDB.createRDResource(pubResourceList, Constants.RD_TABLE);
+    }
+
+    public ArrayList<HashMap<Object, Object>> findResourceAboutDi(String di,
+            String key, String value) {
+        return mMongoDB.readResourceAboutDid(di, key, value,
+                Constants.RD_TABLE);
+    }
+
+    public ArrayList<ResPresencePayload> deleteResourceAboutDi(String di) {
+        return mMongoDB.deleteResourceAboutDi(di, Constants.RD_TABLE);
+    }
+
+    public ArrayList<ResPresencePayload> deleteResourceAboutDiAandIns(String di,
+            String ins) {
+        return mMongoDB.deleteResourceAboutDiAndIns(di, ins,
+                Constants.RD_TABLE);
+    }
+
+    public Object findInsAboutDi(String di, String href) {
+        return mMongoDB.readInsAboutDid(di, href, Constants.RD_TABLE);
+    }
+
+    public void updateDeviceState(HashMap<Object, Object> deviceState) {
+        mMongoDB.createDevicePresenceResource(deviceState,
+                Constants.PRESENCE_TABLE);
+    }
+
+    public String findDeviceState(String deviceId) {
+        return mMongoDB.readDeviceState(deviceId, Constants.PRESENCE_TABLE);
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/MongoDB.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/MongoDB.java
new file mode 100644 (file)
index 0000000..eb820d9
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.db;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.bson.Document;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
+
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.model.Filters;
+
+/**
+ *
+ * This class provides a set of APIs to use MongoDB APIs.
+ *
+ */
+public class MongoDB {
+
+    private MongoClient   mongoClient = null;
+    private MongoDatabase db          = null;
+
+    /**
+     * API creating MongoClient and initializing MongoDatabase
+     *
+     * @param dbname
+     *            database name to create MongoDatabase
+     * @throws Exception
+     */
+    public MongoDB(String dbname) throws Exception {
+        mongoClient = new MongoClient();
+        mongoClient.dropDatabase(dbname);
+        db = mongoClient.getDatabase(dbname);
+    }
+
+    /**
+     * API creating collection
+     *
+     * @param tableName
+     *            collection name
+     */
+    public void createTable(String tableName) {
+        deleteTable(tableName);
+        db.createCollection(tableName);
+    }
+
+    /**
+     * API deleting collection
+     *
+     * @param tableName
+     *            collection name
+     */
+    public void deleteTable(String tableName) {
+        db.getCollection(tableName).drop();
+    }
+
+    private Document createDocument(HashMap<Object, Object> storeRes) {
+
+        Document doc = new Document();
+        Set<Entry<Object, Object>> resEntrySet = storeRes.entrySet();
+        Iterator<Entry<Object, Object>> entryIter = resEntrySet.iterator();
+
+        while (entryIter.hasNext()) {
+            Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) entryIter
+                    .next();
+            doc.append(entry.getKey().toString(), entry.getValue());
+        }
+
+        return doc;
+    }
+
+    private ArrayList<Document> createDocuments(
+            ArrayList<HashMap<Object, Object>> storeResList) {
+
+        Iterator<HashMap<Object, Object>> resListIter = storeResList.iterator();
+
+        ArrayList<Document> docList = new ArrayList<>();
+
+        while (resListIter.hasNext()) {
+            Document doc = new Document();
+
+            HashMap<Object, Object> storeRes = resListIter.next();
+            Set<Entry<Object, Object>> resEntrySet = storeRes.entrySet();
+            Iterator<Entry<Object, Object>> entryIter = resEntrySet.iterator();
+
+            while (entryIter.hasNext()) {
+                Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) entryIter
+                        .next();
+                doc.append(entry.getKey().toString(), entry.getValue());
+            }
+            docList.add(doc);
+        }
+
+        return docList;
+    }
+
+    private HashMap<Object, Object> convertDocumentToHashMap(Document doc) {
+        HashMap<Object, Object> resourceMap = new HashMap<Object, Object>();
+
+        Set<Entry<String, Object>> entrySet = doc.entrySet();
+        Iterator<Entry<String, Object>> entryIter = entrySet.iterator();
+        while (entryIter.hasNext()) {
+            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) entryIter
+                    .next();
+            if (entry.getValue() != null) {
+                resourceMap.put(entry.getKey().toString(), entry.getValue());
+            }
+        }
+
+        return resourceMap;
+    }
+
+    /**
+     * API for storing information of published resources
+     *
+     * @param publishPayloadFormat
+     *            information of published resources to store in collection
+     * @param tableName
+     *            collection name
+     */
+    public ArrayList<ResPresencePayload> createRDResource(
+            ArrayList<HashMap<Object, Object>> storeResList, String tableName) {
+        ArrayList<Document> docList = createDocuments(storeResList);
+        Iterator<Document> docIter = docList.iterator();
+
+        MongoCollection<Document> collection = db.getCollection(tableName);
+
+        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+
+        while (docIter.hasNext()) {
+            Document doc = docIter.next();
+            byte trigger = 0;
+
+            if (collection.findOneAndReplace(
+                    Filters.and(
+                            Filters.eq(Constants.DEVICE_ID,
+                                    doc.get(Constants.DEVICE_ID)),
+                            Filters.eq(Constants.INS, doc.get(Constants.INS))),
+                    doc) == null) {
+                collection.insertOne(doc);
+                trigger = Constants.RES_CREATE;
+
+            } else {
+                trigger = Constants.RES_CHANGE;
+
+            }
+
+            resPayloadList.add(makeResourcePresencePayload(doc, trigger));
+        }
+        return resPayloadList;
+    }
+
+    public void createDevicePresenceResource(HashMap<Object, Object> storeRes,
+            String tableName) {
+
+        Document doc = createDocument(storeRes);
+        MongoCollection<Document> collection = db.getCollection(tableName);
+
+        if (collection
+                .findOneAndReplace(
+                        Filters.and(Filters.eq(Constants.DEVICE_ID,
+                                doc.get(Constants.DEVICE_ID))),
+                        doc) == null) {
+
+            collection.insertOne(doc);
+        }
+
+        return;
+    }
+
+    private ResPresencePayload makeResourcePresencePayload(Document doc,
+            byte trigger) {
+
+        ResPresencePayload resPayload = new ResPresencePayload();
+
+        resPayload.setTrg(trigger);
+
+        Object rt = doc.get(Constants.RESOURCE_TYPE);
+        if (rt != null) {
+            resPayload.setRt(rt.toString());
+        }
+        Object href = doc.get(Constants.HREF);
+        if (rt != null) {
+            Object di = doc.get(Constants.DEVICE_ID);
+            if (di != null) {
+                resPayload.setHref(href.toString());
+            }
+        }
+        Object ttl = doc.get(Constants.RESOURCE_TTL);
+        if (ttl != null) {
+            resPayload.setTtl((int) ttl);
+        }
+        return resPayload;
+    }
+
+    public String readDeviceState(String deviceId, String tableName) {
+
+        String deviceState = null;
+
+        MongoCollection<Document> collection = db.getCollection(tableName);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.DEVICE_ID, deviceId))
+                .iterator();
+
+        try {
+
+            while (cursor.hasNext()) {
+                Document doc = cursor.next();
+                deviceState = doc.getString(Constants.PRESENCE_STATE);
+                break;
+            }
+
+        } finally {
+
+            cursor.close();
+        }
+
+        return deviceState;
+    }
+
+    /**
+     * API for finding resources matched filterValue of filterKey and a
+     * particular device ID in collection
+     *
+     * @param di
+     *            device id
+     * @param filterKey
+     *            field name in collection
+     * @param filterValue
+     *            field value about field name
+     * @param tableName
+     *            collection name
+     * @return ArrayList<PublishPayloadFormat> - array list of resource
+     *         information
+     */
+    public ArrayList<HashMap<Object, Object>> readResourceAboutDid(String di,
+            String filterKey, String filterValue, String tableName) {
+        MongoCollection<Document> collection = db.getCollection(tableName);
+        ArrayList<HashMap<Object, Object>> resList = null;
+        MongoCursor<Document> cursor = collection
+                .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
+                        Filters.eq(filterKey, filterValue)))
+                .iterator();
+
+        if (cursor.hasNext()) {
+            resList = new ArrayList<>();
+        }
+        try {
+            while (cursor.hasNext()) {
+                Document doc = cursor.next();
+                resList.add(convertDocumentToHashMap(doc));
+            }
+        } finally {
+            cursor.close();
+        }
+
+        return resList;
+    }
+
+    public Object readInsAboutDid(String di, String href, String tableName) {
+        MongoCollection<Document> collection = db.getCollection(tableName);
+        MongoCursor<Document> cursor = collection
+                .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
+                        Filters.eq(Constants.HREF, href)))
+                .iterator();
+        try {
+            while (cursor.hasNext()) {
+                Document doc = cursor.next();
+                return doc.get(Constants.INS);
+            }
+        } finally {
+            cursor.close();
+        }
+        return null;
+    }
+
+    /**
+     * API for deleting resources about a particular device ID in collection
+     *
+     * @param di
+     *            device id
+     * @param tableName
+     *            collection name
+     */
+    public ArrayList<ResPresencePayload> deleteResourceAboutDi(String di,
+            String tableName) {
+
+        MongoCollection<Document> collection = db.getCollection(tableName);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.eq(Constants.DEVICE_ID, di)).iterator();
+
+        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+
+        try {
+            while (cursor.hasNext()) {
+                Document doc = cursor.next();
+                resPayloadList.add(
+                        makeResourcePresencePayload(doc, Constants.RES_DELETE));
+            }
+
+        } finally {
+
+            cursor.close();
+        }
+
+        collection.deleteMany(Filters.eq(Constants.DEVICE_ID, di));
+
+        return resPayloadList;
+    }
+
+    /**
+     * API for deleting resources about a particular device ID and ins in
+     * collection
+     *
+     * @param di
+     *            device id
+     * @param ins
+     *            ins
+     * @param tableName
+     *            collection name
+     */
+    public ArrayList<ResPresencePayload> deleteResourceAboutDiAndIns(String di,
+            String ins, String tableName) {
+
+        MongoCollection<Document> collection = db.getCollection(tableName);
+
+        MongoCursor<Document> cursor = collection
+                .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
+                        Filters.eq(Constants.INS, ins)))
+                .iterator();
+
+        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+
+        try {
+            while (cursor.hasNext()) {
+                Document doc = cursor.next();
+                resPayloadList.add(
+                        makeResourcePresencePayload(doc, Constants.RES_DELETE));
+            }
+
+        } finally {
+
+            cursor.close();
+        }
+
+        collection.deleteOne(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
+                Filters.eq(Constants.INS, ins)));
+
+        return resPayloadList;
+
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/LinksPayloadFormat.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/LinksPayloadFormat.java
deleted file mode 100644 (file)
index 7a173d3..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.rdserver.resources;
-
-import java.util.ArrayList;
-
-public class LinksPayloadFormat {
-    /** This is the target relative URI. */
-    String            href;
-    /**
-     * Resource Type - A standard OIC specified or vendor defined resource type
-     * of the resource referenced by the target URI.
-     */
-    ArrayList<String> rt;
-    /**
-     * Interface - The interfaces supported by the resource referenced by the
-     * target URI.
-     */
-    ArrayList<String> itf;
-    /**
-     * The relation of the target URI referenced by the link to the context URI;
-     * The default value is null.
-     */
-    String            rel;
-    /**
-     * Specifies if the resource referenced by the target URIis observable or
-     * not.
-     */
-    boolean           obs;
-    /**
-     * A title for the link relation. Can be used by the UI to provide a
-     * context.
-     */
-    String            title;
-    /**
-     * This is used to override the context URI e.g. override the URI of the
-     * containing collection.
-     */
-    String            uri;
-    /**
-     * The instance identifier for this web link in an array of web links - used
-     * in links.
-     */
-    int               ins;
-    /**
-     * A hint of the media type of the representation of the resource referenced
-     * by the target URI.
-     */
-    ArrayList<String> mt;
-
-    public LinksPayloadFormat() {
-        rt = new ArrayList<String>();
-        itf = new ArrayList<String>();
-        mt = new ArrayList<String>();
-    }
-
-    public String getHref() {
-        return href;
-    }
-
-    public void setHref(String href) {
-        this.href = href;
-    }
-
-    public ArrayList<String> getRt() {
-        return rt;
-    }
-
-    public void setRt(ArrayList<String> rt) {
-        this.rt = rt;
-    }
-
-    public ArrayList<String> getItf() {
-        return itf;
-    }
-
-    public void setItf(ArrayList<String> itf) {
-        this.itf = itf;
-    }
-
-    public String getRel() {
-        return rel;
-    }
-
-    public void setRel(String rel) {
-        this.rel = rel;
-    }
-
-    public boolean isObs() {
-        return obs;
-    }
-
-    public void setObs(boolean obs) {
-        this.obs = obs;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public String getUri() {
-        return uri;
-    }
-
-    public void setUri(String uri) {
-        this.uri = uri;
-    }
-
-    public int getIns() {
-        return ins;
-    }
-
-    public void setIns(int ins) {
-        this.ins = ins;
-    }
-
-    public ArrayList<String> getMt() {
-        return mt;
-    }
-
-    public void setMt(ArrayList<String> mt) {
-        this.mt = mt;
-    }
-}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/PublishPayloadFormat.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/PublishPayloadFormat.java
deleted file mode 100644 (file)
index e7b3140..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.rdserver.resources;
-
-import java.util.ArrayList;
-
-public class PublishPayloadFormat {
-
-    /** Name of tags. */
-    String deviceName;
-    /** Device identifier. */
-    String di;
-    /** The base URI where the resources are hold. */
-    String baseUri;
-    /** Bitmap holds observable, discoverable, secure option flag. */
-    int    bitmap;
-    /** Port set in case, the secure flag is set above. */
-    int    port;
-    /** Id for each set of links i.e. tag. */
-    int    ins;
-    /**
-     * Defines the list of allowable resource types (for Target and anchors) in
-     * links included in the collection; new links being created can only be
-     * from this list.
-     */
-    String rts;
-    /**
-     * When specified this is the default relationship to use when an OIC Link
-     * does not specify an explicit relationship with *rel* parameter.
-     */
-    String drel;
-    /** Time to keep holding resource. */
-    int    ttl;
-
-    ArrayList<LinksPayloadFormat> links;
-
-    public PublishPayloadFormat() {
-        links = new ArrayList<LinksPayloadFormat>();
-    }
-
-    public String getDeviceName() {
-        return deviceName;
-    }
-
-    public void setDeviceName(String deviceName) {
-        this.deviceName = deviceName;
-    }
-
-    public String getDi() {
-        return di;
-    }
-
-    public void setDi(String di) {
-        this.di = di;
-    }
-
-    public String getBaseUri() {
-        return baseUri;
-    }
-
-    public void setBaseUri(String baseUri) {
-        this.baseUri = baseUri;
-    }
-
-    public int getBitmap() {
-        return bitmap;
-    }
-
-    public void setBitmap(int bitmap) {
-        this.bitmap = bitmap;
-    }
-
-    public int getPort() {
-        return port;
-    }
-
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public int getIns() {
-        return ins;
-    }
-
-    public void setIns(int ins) {
-        this.ins = ins;
-    }
-
-    public String getRts() {
-        return rts;
-    }
-
-    public void setRts(String rts) {
-        this.rts = rts;
-    }
-
-    public String getDrel() {
-        return drel;
-    }
-
-    public void setDrel(String drel) {
-        this.drel = drel;
-    }
-
-    public int getTtl() {
-        return ttl;
-    }
-
-    public void setTtl(int ttl) {
-        this.ttl = ttl;
-    }
-
-    public ArrayList<LinksPayloadFormat> getLinks() {
-        return links;
-    }
-
-    public void setLinks(ArrayList<LinksPayloadFormat> links) {
-        this.links = links;
-    }
-}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java
deleted file mode 100644 (file)
index ce96b64..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.rdserver.resources;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import org.iotivity.cloud.base.Resource;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapOption;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.MongoDB;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.JSONUtil;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.channel.ChannelHandlerContext;
-
-/**
- *
- * This class provides a set of APIs relating Resource Directory
- *
- */
-public class ResourceDirectoryResource extends Resource {
-
-    private Cbor<ArrayList<Object>> cbor;
-    private MongoDB                 mongoDB;
-
-    public ResourceDirectoryResource() {
-        setUri(Constants.RD_URI);
-        cbor = new Cbor<ArrayList<Object>>();
-        try {
-            mongoDB = new MongoDB(Constants.RD_DB_NAME);
-            mongoDB.createTable(Constants.RD_TABLE);
-        } catch (Exception e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void onRequestReceived(ChannelHandlerContext ctx,
-            CoapRequest request) {
-
-        Logger.d("ResourceDirectoryResource IN");
-
-        if (ctx == null || request == null) {
-            Logger.d("ctx or request msg is null");
-        }
-
-        else {
-            switch (request.getRequestMethod()) {
-                case GET:
-                    Logger.d("Request message is GET message");
-                    try {
-                        handleGetRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-
-                case PUT:
-                    Logger.d("Request message is PUT message");
-                    break;
-
-                case POST:
-                    Logger.d("Request message is POST message");
-                    try {
-                        handlePostRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-
-                case DELETE:
-                    Logger.d("Request message is DELETE message");
-                    try {
-                        handleDeleteRequest(ctx, request);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    break;
-            }
-        }
-    }
-
-    private CoapResponse makePublishResponse(CoapRequest request)
-            throws Exception {
-        CoapResponse response = new CoapResponse(CoapStatus.CREATED);
-        response.setToken(request.getToken());
-        return response;
-    }
-
-    private CoapResponse makeDeleteResponse(CoapRequest request)
-            throws Exception {
-        CoapResponse response = new CoapResponse(CoapStatus.DELETED);
-        response.setToken(request.getToken());
-        return response;
-    }
-
-    private CoapResponse makeDiscoveryResponse(CoapRequest request,
-            ArrayList<PublishPayloadFormat> foundResource) throws Exception {
-
-        CoapResponse response = new CoapResponse(CoapStatus.CONTENT);
-        response.setToken(request.getToken());
-
-        // make payload
-        ArrayList<HashMap<Object, Object>> discoverPayload = new ArrayList<HashMap<Object, Object>>();
-
-        for (PublishPayloadFormat pubPayload : foundResource) {
-
-            LinksPayloadFormat links = pubPayload.links.get(0);
-            LinkedHashMap<Object, Object> discoverLinks = new LinkedHashMap<Object, Object>();
-            discoverLinks.put(Constants.RS_HREF, links.getHref());
-            discoverLinks.put(Constants.RS_RESOURCE_TYPE, links.getRt().get(0));
-            discoverLinks.put(Constants.RS_INTERFACE, links.getItf().get(0));
-            HashMap<Object, Object> pres = new HashMap<Object, Object>();
-            pres.put(Constants.RS_BITMAP, pubPayload.getBitmap());
-            discoverLinks.put("p", pres);
-
-            ArrayList<Object> linksArray = null;
-            for (HashMap<Object, Object> segmentPayload : discoverPayload) {
-                // exist di
-                if (segmentPayload.get(Constants.RS_DEVICE_ID)
-                        .equals(pubPayload.getDi())) {
-                    linksArray = new ArrayList<Object>();
-                    linksArray = (ArrayList<Object>) segmentPayload
-                            .get("links");
-                    linksArray.add(discoverLinks);
-                    segmentPayload.put("links", linksArray);
-                }
-            }
-            if (linksArray == null) {
-                HashMap<Object, Object> discoverRes = new HashMap<Object, Object>();
-                linksArray = new ArrayList<Object>();
-                discoverRes.put(Constants.RS_DEVICE_ID, pubPayload.getDi());
-                linksArray.add(discoverLinks);
-                discoverRes.put("links", linksArray);
-                discoverPayload.add(discoverRes);
-            }
-        }
-
-        // TODO : device id is decoded to byte in IoTivity. So, temporarily we
-        // cast the type of device id to byte.
-        for (HashMap<Object, Object> segmentPayload : discoverPayload) {
-            String stringDi = segmentPayload.get(Constants.RS_DEVICE_ID)
-                    .toString();
-            segmentPayload.put(Constants.RS_DEVICE_ID,
-                    stringDi.getBytes(StandardCharsets.UTF_8));
-        }
-
-        Logger.i("discoverPayload :" + discoverPayload.toString());
-
-        byte[] bytes = ByteBuffer.allocate(4).putInt(60).array();
-        response.addOption(CoapOption.CONTENT_FORMAT.getvalue(), bytes);
-
-        byte[] encodedPaylod = cbor.encodingPayloadToCbor(discoverPayload);
-        response.setPayload(encodedPaylod);
-
-        return response;
-
-    }
-
-    private HashMap<String, String> extractFiltersFromQuery(List<String> query)
-            throws Exception {
-
-        if (query == null) {
-            throw new IllegalArgumentException("query is null!");
-        }
-
-        HashMap<String, String> filters = new HashMap<String, String>();
-        for (String queryPara : query) {
-            StringTokenizer keyValuePair = new StringTokenizer(queryPara, "=");
-            if (keyValuePair.countTokens() < 2) {
-                // query error
-                filters = null;
-            } else {
-                String key = keyValuePair.nextToken();
-                String value = keyValuePair.nextToken();
-                if (key.equals(Constants.RS_INTERFACE)) {
-                    filters.put(Constants.RS_INTERFACE, value);
-                } else if (key.equals(Constants.RS_RESOURCE_TYPE)) {
-                    filters.put(Constants.RS_RESOURCE_TYPE, value);
-                } else if (key.equals(Constants.RS_DEVICE_ID)) {
-                    filters.put(Constants.RS_DEVICE_ID, value);
-                } else if (key.equals(Constants.RS_INS)) {
-                    filters.put(Constants.RS_INS, value);
-                } else if (key.equals(Constants.RS_SEARCH_TYPE)) {
-                    filters.put(Constants.RS_SEARCH_TYPE, value);
-                }
-            }
-        }
-
-        return filters;
-    }
-
-    /**
-     * API for handling GET message(message to discovery resources)
-     *
-     * @param ctx
-     *            ChannelHandlerContext of request message
-     * @param request
-     *            CoAP request message
-     * @throws Exception
-     */
-    public void handleGetRequest(ChannelHandlerContext ctx, CoapRequest request)
-            throws Exception {
-        HashMap<String, String> filters = extractFiltersFromQuery(
-                request.getUriQuerySegments());
-
-        ArrayList<PublishPayloadFormat> foundResource = null;
-
-        if (filters == null) {
-            throw new IllegalArgumentException("filters is null");
-        } else if (filters.get(Constants.RS_SEARCH_TYPE) == null) {
-            Logger.d("st is null, so this is the get msg about public devices");
-            if (filters.get(Constants.RS_INTERFACE) != null) {
-                foundResource = mongoDB.readResource(Constants.RS_INTERFACE,
-                        filters.get(Constants.RS_INTERFACE),
-                        Constants.RD_TABLE);
-            } else if (filters.get(Constants.RS_RESOURCE_TYPE) != null) {
-                foundResource = mongoDB.readResource(Constants.RS_RESOURCE_TYPE,
-                        filters.get(Constants.RS_RESOURCE_TYPE),
-                        Constants.RD_TABLE);
-            } else {
-                throw new IllegalArgumentException("rt & if is null");
-            }
-
-            CoapResponse response = makeDiscoveryResponse(request,
-                    foundResource);
-            ctx.writeAndFlush(response);
-
-        } else {
-            if (filters.get(Constants.RS_SEARCH_TYPE)
-                    .equals(Constants.RS_SEARCH_TYPE_DEVICE_LIST)) {
-                Logger.d(
-                        "st is not null, so this is the get msg about private devices");
-                // parse payload
-                byte[] payload = request.getPayload();
-                ArrayList<String> deviceList = JSONUtil.parseJSON(payload,
-                        Constants.RS_DEVICE_LIST_KEY);
-                if (deviceList == null) {
-                    throw new IllegalArgumentException("deviceList is null");
-                }
-
-                if (filters.get(Constants.RS_INTERFACE) != null) {
-                    foundResource = new ArrayList<PublishPayloadFormat>();
-                    for (String deviceId : deviceList) {
-                        foundResource.addAll(mongoDB.readResourceAboutDid(
-                                deviceId, Constants.RS_INTERFACE,
-                                filters.get(Constants.RS_INTERFACE),
-                                Constants.RD_TABLE));
-                    }
-                } else if (filters.get(Constants.RS_RESOURCE_TYPE) != null) {
-                    foundResource = new ArrayList<PublishPayloadFormat>();
-                    for (String deviceId : deviceList) {
-                        foundResource.addAll(mongoDB.readResourceAboutDid(
-                                deviceId, Constants.RS_RESOURCE_TYPE,
-                                filters.get(Constants.RS_RESOURCE_TYPE),
-                                Constants.RD_TABLE));
-                    }
-                } else {
-                    throw new IllegalArgumentException("rt & if is null");
-                }
-
-                CoapResponse response = makeDiscoveryResponse(request,
-                        foundResource);
-                ctx.writeAndFlush(response);
-            } else {
-                throw new IllegalArgumentException("value of st is not corret");
-            }
-        }
-    }
-
-    /**
-     * API for handling POST message(message to publish or update resources)
-     *
-     * @param ctx
-     *            ChannelHandlerContext of request message
-     * @param request
-     *            CoAP request message
-     * @throws Exception
-     */
-    public void handlePostRequest(ChannelHandlerContext ctx,
-            CoapRequest request) throws Exception {
-
-        HashMap<String, String> filters = extractFiltersFromQuery(
-                request.getUriQuerySegments());
-
-        if (filters == null) {
-            throw new IllegalArgumentException("filters is null");
-        } else if (filters.get(Constants.RS_RESOURCE_TYPE) == null) {
-            throw new IllegalArgumentException("rt is null");
-        } else if (filters.get(Constants.RS_RESOURCE_TYPE)
-                .equals(Constants.RS_RESOURCE_TYPE_RDPUBLISH)) {
-            Logger.d("This request is publish msg!");
-
-            PublishPayloadFormat pubPayload = new PublishPayloadFormat();
-
-            ArrayList<Object> payloadData = cbor.parsePayloadFromCbor(
-                    request.getPayload(), ArrayList.class);
-
-            if (payloadData == null) {
-                throw new IllegalArgumentException("parsed payload is null");
-            } else {
-                Logger.i("payloadData: " + payloadData.toString());
-            }
-
-            HashMap<Object, Object> tags = (HashMap<Object, Object>) payloadData
-                    .get(0);
-
-            if (tags == null) {
-                throw new IllegalArgumentException("tags is null!");
-            }
-
-            Object di = tags.get(Constants.RS_DEVICE_ID);
-            if (di != null) {
-                pubPayload.setDi(di.toString());
-                Logger.i("di : " + pubPayload.getDi());
-            } else {
-                throw new IllegalArgumentException("device id is null!");
-            }
-
-            Object deviceName = tags.get(Constants.RS_DEVICE_NAME);
-            if (deviceName != null) {
-                pubPayload.setDeviceName(deviceName.toString());
-                Logger.i("device name : " + pubPayload.getDeviceName());
-            }
-
-            Object baseUri = tags.get(Constants.RS_BASE_URI);
-            if (baseUri != null) {
-                pubPayload.setBaseUri(baseUri.toString());
-                Logger.i("baseURI : " + pubPayload.getBaseUri());
-            }
-
-            Object bitMap = tags.get(Constants.RS_BITMAP);
-            if (bitMap != null) {
-                pubPayload.setBitmap((int) bitMap);
-                Logger.i("bm : " + pubPayload.getBitmap());
-            }
-
-            Object hostingPort = tags.get(Constants.RS_HOSTING_PORT);
-            if (hostingPort != null) {
-                pubPayload.setPort((int) hostingPort);
-                Logger.i("port : " + pubPayload.getPort());
-            }
-
-            Object ins = tags.get(Constants.RS_INS);
-            if (ins != null) {
-                pubPayload.setIns((int) ins);
-                Logger.i("ins : " + pubPayload.getIns());
-            }
-
-            Object rts = tags.get(Constants.RS_RTS);
-            if (rts != null) {
-                pubPayload.setRts(rts.toString());
-                Logger.i("rts : " + pubPayload.getRts());
-            }
-
-            Object drel = tags.get(Constants.RS_DREL);
-            if (drel != null) {
-                pubPayload.setDrel(drel.toString());
-                Logger.i("drel : " + pubPayload.getDrel());
-            }
-
-            // Object ttl = tags.get(Constants.RS_TTL);
-            // if (ttl != null) {
-            // pubPayload.setTtl((int) ttl);
-            // Logger.i("ttl : " + pubPayload.getTtl());
-            // }
-
-            ArrayList<LinkedHashMap<Object, Object>> publishLinks = (ArrayList<LinkedHashMap<Object, Object>>) payloadData
-                    .get(1);
-
-            if (publishLinks == null) {
-                throw new IllegalArgumentException("publishLinks is null!");
-            }
-
-            for (LinkedHashMap<Object, Object> o : publishLinks) {
-
-                LinksPayloadFormat storeLinks = new LinksPayloadFormat();
-
-                Object href = o.get(Constants.RS_HREF);
-                if (href != null) {
-                    String prefix = "/" + pubPayload.getDi();
-                    storeLinks.setHref(prefix + href.toString());
-                    Logger.i("href : " + storeLinks.getHref());
-                }
-
-                if (o.get(Constants.RS_RESOURCE_TYPE) != null) {
-                    Object obj = o.get(Constants.RS_RESOURCE_TYPE);
-                    if (obj != null) {
-                        storeLinks.setRt((ArrayList<String>) obj);
-                    }
-                    Object rt = storeLinks.getRt();
-                    if (rt != null) {
-                        Logger.i("rt : " + storeLinks.getRt().toString());
-                    }
-                }
-
-                if (o.get(Constants.RS_INTERFACE) != null) {
-                    storeLinks.setItf(
-                            (ArrayList<String>) o.get(Constants.RS_INTERFACE));
-                    Object itf = storeLinks.getItf();
-                    if (itf != null) {
-                        Logger.i("if : " + storeLinks.getItf().toString());
-                    }
-                }
-
-                Object rel = o.get(Constants.RS_REL);
-                if (rel != null) {
-                    storeLinks.setRel(rel.toString());
-                    Logger.i("rel : " + storeLinks.getRel());
-                }
-
-                if (o.get(Constants.RS_OBS) != null) {
-                    Object obj = o.get(Constants.RS_OBS);
-                    if (obj != null) {
-                        storeLinks.setObs((boolean) obj);
-                    }
-                    Logger.i("obs : " + storeLinks.isObs());
-                }
-
-                if (o.get(Constants.RS_TITLE) != null) {
-                    Object obj = o.get(Constants.RS_TITLE);
-                    if (obj != null) {
-                        storeLinks.setTitle(obj.toString());
-                    }
-                    Logger.i("title : " + storeLinks.getTitle());
-                }
-
-                if (o.get(Constants.RS_URI) != null) {
-                    Object obj = o.get(Constants.RS_URI);
-                    if (obj != null) {
-                        storeLinks.setUri(obj.toString());
-                    }
-                    Logger.i("uri : " + storeLinks.getUri());
-                }
-
-                if (o.get(Constants.RS_INS) != null) {
-                    Object obj = o.get(Constants.RS_INS);
-                    if (obj != null) {
-                        storeLinks.setIns((int) obj);
-                    }
-                    Logger.i("ins : " + storeLinks.getIns());
-                }
-
-                if (o.get(Constants.RS_MEDIA_TYPE) != null) {
-                    Object obj = o.get(Constants.RS_MEDIA_TYPE);
-                    if (obj != null) {
-                        storeLinks.setMt((ArrayList<String>) obj);
-                    }
-                    Object mt = storeLinks.getMt();
-                    if (mt != null) {
-                        Logger.i("mt : " + mt.toString());
-                    }
-                }
-
-                pubPayload.links.add(storeLinks);
-            }
-
-            mongoDB.createResource(pubPayload, Constants.RD_TABLE);
-
-            CoapResponse response = makePublishResponse(request);
-            ctx.writeAndFlush(response);
-
-        } else {
-            throw new IllegalArgumentException("rt is not correct");
-        }
-    }
-
-    /**
-     * API for handling Delete message(message to delete published resources)
-     *
-     * @param ctx
-     *            ChannelHandlerContext of request message
-     * @param request
-     *            CoAP request message
-     * @throws Exception
-     */
-    public void handleDeleteRequest(ChannelHandlerContext ctx,
-            CoapRequest request) throws Exception {
-        HashMap<String, String> filters = extractFiltersFromQuery(
-                request.getUriQuerySegments());
-
-        if (filters == null) {
-            throw new IllegalArgumentException("filters is null");
-        } else if (filters.get(Constants.RS_DEVICE_ID) == null) {
-            throw new IllegalArgumentException("di is null");
-        } else {
-            if (filters.get(Constants.RS_INS) == null) {
-                mongoDB.deleteResourceAboutDid(
-                        filters.get(Constants.RS_DEVICE_ID),
-                        Constants.RD_TABLE);
-            } else {
-                mongoDB.deleteResourceAboutDidAndIns(
-                        filters.get(Constants.RS_DEVICE_ID),
-                        filters.get(Constants.RS_INS), Constants.RD_TABLE);
-            }
-            CoapResponse response = makeDeleteResponse(request);
-            ctx.writeAndFlush(response);
-        }
-    }
-}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/InsManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/InsManager.java
new file mode 100644 (file)
index 0000000..980e092
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.rd;
+
+import java.util.HashMap;
+
+import org.iotivity.cloud.rdserver.db.DBManager;
+
+public class InsManager {
+
+    private HashMap<String, Integer> mNextIns      = new HashMap<>();
+    private int                      mInitialValue = 1;
+
+    public int getIns(String di, String href) {
+
+        Object objectIns = DBManager.getInstance().findInsAboutDi(di, href);
+        if (objectIns == null) {
+            return 0;
+        } else {
+            return (int) objectIns;
+
+        }
+    }
+
+    public int createIns(String di) {
+        Object objectIns;
+
+        objectIns = mNextIns.get(di);
+        if (objectIns == null) {
+            mNextIns.put(di, mInitialValue + 1);
+            return mInitialValue;
+        } else {
+            int ins = (int) objectIns;
+            mNextIns.put(di, ins + 1);
+            return ins;
+        }
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishLinks.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishLinks.java
new file mode 100644 (file)
index 0000000..6a64e36
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.rd;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.iotivity.cloud.rdserver.Constants;
+
+public class PublishLinks {
+    /** URI Reference */
+    private String            href;
+    /** Relation between target URI and context URI */
+    private String            rel;
+    /** Resource Types */
+    private ArrayList<String> rt   = new ArrayList<String>();
+    /** Resource interface */
+    private ArrayList<String> itf  = new ArrayList<String>();
+    /** policies that apply for resource */
+    private Object            p;
+    /** Title for the link relation */
+    private String            title;
+    /** This is used to override the context URI */
+    private String            anchor;
+    /** An ordinal number that is not repeated */
+    private int               ins;
+    /** Time to live for this link */
+    private int               ttl;
+    /**
+     * A hint of the media type of the representation of the resource referenced
+     * by the target URI.
+     */
+    ArrayList<String>         type = new ArrayList<String>();
+
+    public PublishLinks copy() {
+        PublishLinks links = new PublishLinks();
+        links.href = this.href;
+        links.rel = this.rel;
+        links.rt.addAll(this.rt);
+        links.itf.addAll(this.itf);
+        links.p = this.p;
+        links.title = this.title;
+        links.anchor = this.anchor;
+        links.ins = this.ins;
+        links.ttl = this.ttl;
+        return links;
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    public void setHref(Object href) {
+        this.href = href.toString();
+    }
+
+    public String getRel() {
+        return rel;
+    }
+
+    public void setRel(Object rel) {
+        this.rel = rel.toString();
+    }
+
+    public ArrayList<String> getRt() {
+        return rt;
+    }
+
+    public void setRt(Object rt) {
+        this.rt = (ArrayList<String>) rt;
+    }
+
+    public ArrayList<String> getItf() {
+        return itf;
+    }
+
+    public void setItf(Object itf) {
+        this.itf = (ArrayList<String>) itf;
+    }
+
+    public Object getP() {
+        return p;
+    }
+
+    public void setP(Object p) {
+        HashMap<Object, Object> bm = (HashMap<Object, Object>) p;
+        this.p = bm.get(Constants.BITMAP);
+    }
+
+    public void changePType() {
+        HashMap<Object, Object> bm = new HashMap<Object, Object>();
+        bm.put(Constants.BITMAP, (int) p);
+        this.p = bm;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(Object title) {
+        this.title = title.toString();
+    }
+
+    public String getAnchor() {
+        return anchor;
+    }
+
+    public void setAnchor(Object anchor) {
+        this.anchor = anchor.toString();
+    }
+
+    public int getIns() {
+        return ins;
+    }
+
+    public void setIns(Object ins) {
+        this.ins = (int) ins;
+    }
+
+    public int getTtl() {
+        return ttl;
+    }
+
+    public void setTtl(Object ttl) {
+        this.ttl = (int) ttl;
+    }
+
+    public ArrayList<String> getType() {
+        return type;
+    }
+
+    public void setType(Object type) {
+        this.type = (ArrayList<String>) type;
+    }
+
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishPayload.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishPayload.java
new file mode 100644 (file)
index 0000000..e02b726
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.rd;
+
+import java.util.ArrayList;
+
+public class PublishPayload {
+
+    private PublishTags             tags  = new PublishTags();
+
+    private ArrayList<PublishLinks> links = new ArrayList<>();
+
+    public PublishPayload copy() {
+        PublishPayload pubPayload = new PublishPayload();
+        pubPayload.tags = this.tags.copy();
+
+        pubPayload.links = new ArrayList<>();
+
+        for (PublishLinks link : this.links) {
+            pubPayload.links.add(link.copy());
+        }
+
+        return pubPayload;
+    }
+
+    public PublishTags getTags() {
+        return tags;
+    }
+
+    public void setTags(PublishTags tags) {
+        this.tags = tags;
+    }
+
+    public ArrayList<PublishLinks> getLinks() {
+        return links;
+    }
+
+    public void setLinks(ArrayList<PublishLinks> links) {
+        this.links = links;
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishTags.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishTags.java
new file mode 100644 (file)
index 0000000..f240ff9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.rd;
+
+public class PublishTags {
+    /** An unique identifier of device */
+    private String di;
+    /** A human friendly name of device */
+    private String n;
+    /** Time (in seconds) to indicate how long RD should publish this item */
+    private int    lt;
+
+    public PublishTags copy() {
+        PublishTags tags = new PublishTags();
+        tags.di = this.di;
+        tags.n = this.n;
+        tags.lt = this.lt;
+        return tags;
+    }
+
+    public String getDi() {
+        return di;
+    }
+
+    public void setDi(Object di) {
+        this.di = di.toString();
+    }
+
+    public String getN() {
+        return n;
+    }
+
+    public void setN(Object n) {
+        this.n = n.toString();
+    }
+
+    public int getLt() {
+        return lt;
+    }
+
+    public void setLt(Object lt) {
+        this.lt = (int) lt;
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/ResourceDirectoryResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/ResourceDirectoryResource.java
new file mode 100644 (file)
index 0000000..fbc5b50
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.rd;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.db.DBManager;
+import org.iotivity.cloud.rdserver.resources.presence.ResPresenceManager;
+import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
+import org.iotivity.cloud.rdserver.util.TypeCastingManager;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Logger;
+
+public class ResourceDirectoryResource extends Resource {
+
+    private Cbor<HashMap<Object, Object>>    mCbor                    = new Cbor<>();
+    private TypeCastingManager<PublishTags>  mPublishTagsTypeManager  = new TypeCastingManager<>();
+    private TypeCastingManager<PublishLinks> mPublishLinksTypeManager = new TypeCastingManager<>();
+    private InsManager                       mInsManager              = new InsManager();
+    private String                           notiDeviceId             = null;
+    private ArrayList<ResPresencePayload>    notiPayloadList          = new ArrayList<ResPresencePayload>();
+
+    public ResourceDirectoryResource() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.RD_URI));
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case POST:
+                response = handlePostRequest(request);
+                break;
+
+            case DELETE:
+                response = handleDeleteRequest(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not supported");
+        }
+
+        srcDevice.sendResponse(response);
+
+        ResPresenceManager.getInstance().notifyToObservers(notiDeviceId,
+                notiPayloadList);
+
+    }
+
+    private IResponse handlePostRequest(IRequest request)
+            throws ServerException {
+
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+
+        byte[] encodedPayload = null;
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        }
+
+        List<String> listRT = queryMap.get(Constants.RESOURCE_TYPE);
+
+        if (listRT == null) {
+            throw new PreconditionFailedException("rt property is not include");
+        } else if (listRT.get(0).equals(Constants.RESOURCE_TYPE_RDPUBLISH)) {
+
+            PublishPayload pubPayload = parsingPublishPayload(
+                    request.getPayload());
+
+            notiDeviceId = pubPayload.getTags().getDi();
+
+            PublishPayload copyPubPayload = pubPayload.copy();
+
+            ArrayList<HashMap<Object, Object>> storeResList = creatDBStoreResource(
+                    changeResourceUri(copyPubPayload));
+
+            notiPayloadList = DBManager.getInstance()
+                    .registerResource(storeResList);
+
+            encodedPayload = createPublishResponse(pubPayload);
+
+        } else {
+            throw new PreconditionFailedException(
+                    "rt property is not rd publish");
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                ContentFormat.APPLICATION_CBOR, encodedPayload);
+    }
+
+    private byte[] createPublishResponse(PublishPayload pubPayload) {
+        HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
+
+        PublishTags tags = pubPayload.getTags();
+        responseMap.putAll(mPublishTagsTypeManager.convertObjectToMap(tags));
+
+        ArrayList<PublishLinks> pubLinksList = pubPayload.getLinks();
+
+        ArrayList<HashMap<Object, Object>> links = new ArrayList<HashMap<Object, Object>>();
+
+        for (PublishLinks pubLinks : pubLinksList) {
+            mPublishLinksTypeManager.callMethod("changePType", pubLinks);
+            links.add(mPublishLinksTypeManager.convertObjectToMap(pubLinks));
+        }
+        responseMap.put(Constants.LINKS, links);
+
+        Logger.i("publish response :" + responseMap.toString());
+
+        byte[] encodedPaylod = mCbor.encodingPayloadToCbor(responseMap);
+
+        return encodedPaylod;
+    }
+
+    private PublishPayload parsingPublishPayload(byte[] payload)
+            throws ServerException {
+
+        HashMap<Object, Object> payloadData = mCbor
+                .parsePayloadFromCbor(payload, HashMap.class);
+
+        if (payloadData == null) {
+            throw new BadRequestException("payload is null");
+        } else {
+            Logger.i("publish payload: " + payloadData.toString());
+        }
+
+        PublishTags tags = new PublishTags();
+        tags = mPublishTagsTypeManager.convertMaptoObject(payloadData, tags);
+
+        String di = tags.getDi();
+
+        ArrayList<HashMap<Object, Object>> linksList = (ArrayList<HashMap<Object, Object>>) payloadData
+                .get(Constants.LINKS);
+
+        ArrayList<PublishLinks> pubLinksList = new ArrayList<PublishLinks>();
+
+        for (HashMap<Object, Object> links : linksList) {
+            PublishLinks pubLinks = new PublishLinks();
+            pubLinks = mPublishLinksTypeManager.convertMaptoObject(links,
+                    pubLinks);
+            String href = pubLinks.getHref();
+            href = "/di/" + di + href;
+            int ins = pubLinks.getIns();
+            ins = checkResourceIns(di, href, ins);
+            if (ins == 0) {
+                throw new PreconditionFailedException("ins is null");
+            }
+            pubLinks.setIns(ins);
+            pubLinksList.add(pubLinks);
+        }
+
+        PublishPayload pubPayload = new PublishPayload();
+        pubPayload.setTags(tags);
+        pubPayload.setLinks(pubLinksList);
+
+        return pubPayload;
+    }
+
+    private PublishPayload changeResourceUri(PublishPayload pubPayload) {
+
+        String di = pubPayload.getTags().getDi();
+
+        for (PublishLinks links : pubPayload.getLinks()) {
+            String originHref = links.getHref();
+            links.setHref("/di/" + di + originHref);
+        }
+
+        return pubPayload;
+    }
+
+    private int checkResourceIns(String di, String href, int ins) {
+        int storedIns = mInsManager.getIns(di, href);
+        if (ins == 0) {
+            if (storedIns == 0) {
+                ins = mInsManager.createIns(di);
+            } else {
+                ins = storedIns;
+            }
+        } else {
+            if (ins != storedIns) {
+                ins = 0;
+            }
+        }
+        return ins;
+    }
+
+    private ArrayList<HashMap<Object, Object>> creatDBStoreResource(
+            PublishPayload pubPayload) {
+        PublishTags tags = pubPayload.getTags();
+        ArrayList<PublishLinks> linksList = pubPayload.getLinks();
+
+        ArrayList<HashMap<Object, Object>> storeResList = new ArrayList<HashMap<Object, Object>>();
+        HashMap<Object, Object> storeTags = mPublishTagsTypeManager
+                .convertObjectToMap(tags);
+
+        for (PublishLinks links : linksList) {
+            HashMap<Object, Object> storeRes = new HashMap<Object, Object>();
+            storeRes.putAll(storeTags);
+            storeRes.putAll(mPublishLinksTypeManager.convertObjectToMap(links));
+            storeResList.add(storeRes);
+        }
+        return storeResList;
+    }
+
+    private IResponse handleDeleteRequest(IRequest request)
+            throws ServerException {
+
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+        List<String> diList = null;
+        List<String> insList = null;
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        } else {
+            diList = queryMap.get(Constants.DEVICE_ID);
+            insList = queryMap.get(Constants.INS);
+
+            if (diList == null) {
+                throw new PreconditionFailedException(
+                        "di property is not include");
+            } else {
+                String di = diList.get(0);
+                notiDeviceId = di;
+
+                if (insList == null) {
+                    notiPayloadList = DBManager.getInstance()
+                            .deleteResourceAboutDi(di);
+
+                } else {
+                    String ins = insList.get(0);
+                    notiPayloadList = DBManager.getInstance()
+                            .deleteResourceAboutDiAandIns(di, ins);
+                }
+            }
+        }
+
+        IResponse response = MessageBuilder.createResponse(request,
+                ResponseStatus.DELETED);
+
+        return response;
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryLinks.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryLinks.java
new file mode 100644 (file)
index 0000000..e4caa38
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.res;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.iotivity.cloud.rdserver.Constants;
+
+public class DiscoveryLinks {
+    /** URI Reference */
+    private String                  href;
+    /** Resource Types */
+    private ArrayList<String>       rt  = new ArrayList<>();
+    /** Resource interface */
+    private ArrayList<String>       itf = new ArrayList<>();
+    /** policies that apply for resource */
+    private HashMap<Object, Object> p   = new HashMap<>();
+
+    public DiscoveryLinks() {
+
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    public void setHref(Object href) {
+        this.href = href.toString();
+    }
+
+    public ArrayList<String> getRt() {
+        return rt;
+    }
+
+    public void setRt(Object rt) {
+        this.rt = (ArrayList<String>) rt;
+    }
+
+    public ArrayList<String> getItf() {
+        return itf;
+    }
+
+    public void setItf(Object itf) {
+        this.itf = (ArrayList<String>) itf;
+    }
+
+    public Object getP() {
+        return p;
+    }
+
+    public void setP(Object p) {
+        int bm = (int) p;
+        this.p.put(Constants.BITMAP, bm);
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryPayload.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryPayload.java
new file mode 100644 (file)
index 0000000..edae490
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.res;
+
+import java.util.ArrayList;
+
+public class DiscoveryPayload {
+
+    private DiscoveryTags             tags  = new DiscoveryTags();
+
+    private ArrayList<DiscoveryLinks> links = new ArrayList<>();
+
+    public DiscoveryPayload() {
+
+    }
+
+    public DiscoveryTags getTags() {
+        return tags;
+    }
+
+    public void setTags(DiscoveryTags tags) {
+        this.tags = tags;
+    }
+
+    public ArrayList<DiscoveryLinks> getLinks() {
+        return links;
+    }
+
+    public void setLinks(ArrayList<DiscoveryLinks> links) {
+        this.links = links;
+    }
+
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryResource.java
new file mode 100644 (file)
index 0000000..b99793c
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.res;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.db.DBManager;
+import org.iotivity.cloud.rdserver.util.TypeCastingManager;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Logger;
+
+public class DiscoveryResource extends Resource {
+    private Cbor<HashMap<Object, Object>>      mCbor                     = new Cbor<>();
+    private TypeCastingManager<DiscoveryTags>  mDiscoveryTagsTypeManager = new TypeCastingManager<>();
+    private TypeCastingManager<DiscoveryLinks> mDiscoveryLinkTypeManager = new TypeCastingManager<>();
+
+    public DiscoveryResource() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.WELL_KNOWN_URI));
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case GET:
+                response = handleGetRequest(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not supported");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handleGetRequest(IRequest request)
+            throws ServerException {
+
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+
+        ArrayList<DiscoveryPayload> resourceList = new ArrayList<DiscoveryPayload>();
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        }
+
+        List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
+
+        if (deviceList == null) {
+            throw new PreconditionFailedException(
+                    "di property is not included");
+        }
+
+        List<String> listRT = queryMap.get(Constants.RESOURCE_TYPE);
+        List<String> listITF = queryMap.get(Constants.INTERFACE);
+        String key, value = null;
+        ArrayList<HashMap<Object, Object>> foundResList = null;
+
+        // TODO: Multiple RT or ITF support required
+        if (listRT != null) {
+            key = Constants.RESOURCE_TYPE;
+            value = listRT.get(0);
+        } else if (listITF != null) {
+            key = Constants.INTERFACE;
+            value = listITF.get(0);
+        } else {
+            throw new PreconditionFailedException(
+                    "rt or if property is not included");
+        }
+
+        for (String deviceId : deviceList) {
+            foundResList = DBManager.getInstance().findResourceAboutDi(deviceId,
+                    key, value);
+            if (foundResList != null) {
+                resourceList.add(makeDiscoveryPayloadSegment(foundResList));
+            }
+        }
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR,
+                createDiscoveryResponse(resourceList));
+    }
+
+    private DiscoveryPayload makeDiscoveryPayloadSegment(
+            ArrayList<HashMap<Object, Object>> foundResList) {
+
+        ArrayList<DiscoveryLinks> discoveryLinksList = new ArrayList<DiscoveryLinks>();
+
+        for (HashMap<Object, Object> res : foundResList) {
+            DiscoveryLinks discoveryLinksPayload = new DiscoveryLinks();
+            discoveryLinksPayload = mDiscoveryLinkTypeManager
+                    .convertMaptoObject(res, discoveryLinksPayload);
+            discoveryLinksList.add(discoveryLinksPayload);
+        }
+
+        DiscoveryPayload discoveryPayload = new DiscoveryPayload();
+
+        DiscoveryTags tagsPayload = new DiscoveryTags();
+
+        tagsPayload = mDiscoveryTagsTypeManager
+                .convertMaptoObject(foundResList.get(0), tagsPayload);
+
+        discoveryPayload.setTags(tagsPayload);
+        discoveryPayload.setLinks(discoveryLinksList);
+
+        return discoveryPayload;
+    }
+
+    private byte[] createDiscoveryResponse(
+            ArrayList<DiscoveryPayload> discoveryPayloadList) {
+        ArrayList<HashMap<Object, Object>> responseMapList = new ArrayList<HashMap<Object, Object>>();
+
+        for (DiscoveryPayload discoveryPayload : discoveryPayloadList) {
+            HashMap<Object, Object> responseSegment = null;
+            DiscoveryTags tags = discoveryPayload.getTags();
+            responseSegment = mDiscoveryTagsTypeManager
+                    .convertObjectToMap(tags);
+
+            ArrayList<DiscoveryLinks> discoveryLinksList = discoveryPayload
+                    .getLinks();
+
+            ArrayList<HashMap<Object, Object>> links = new ArrayList<HashMap<Object, Object>>();
+
+            for (DiscoveryLinks discoveryLinks : discoveryLinksList) {
+                links.add(mDiscoveryLinkTypeManager
+                        .convertObjectToMap(discoveryLinks));
+            }
+            responseSegment.put(Constants.LINKS, links);
+
+            responseMapList.add(responseSegment);
+        }
+
+        Logger.i("discover payload :" + responseMapList.toString());
+
+        byte[] encodedPaylod = mCbor.encodingPayloadToCbor(responseMapList);
+
+        return encodedPaylod;
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryTags.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryTags.java
new file mode 100644 (file)
index 0000000..bc1fe35
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.directory.res;
+
+public class DiscoveryTags {
+    /** An unique identifier of device */
+    private String di;
+    /** A human friendly name of device */
+    private String n;
+
+    public String getDi() {
+        return di;
+    }
+
+    public void setDi(Object di) {
+        this.di = di.toString();
+    }
+
+    public String getN() {
+        return n;
+    }
+
+    public void setN(Object n) {
+        this.n = n.toString();
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/ResPresenceManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/ResPresenceManager.java
new file mode 100644 (file)
index 0000000..f0779db
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.presence;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
+import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
+
+public class ResPresenceManager {
+
+    public static ResPresenceManager mResPresenceManager = new ResPresenceManager();
+
+    private class PresenceSubscriber {
+        PresenceSubscriber(Device subscriber, IRequest request) {
+            mSubscriber = subscriber;
+            mRequest = request;
+        }
+
+        public Device   mSubscriber;
+        public IRequest mRequest;
+    }
+
+    // di , token, Subscriber list
+    private HashMap<String, HashMap<String, PresenceSubscriber>> mDeviceSubscriber         = null;
+    // token, di list
+    private HashMap<String, List<String>>                        mSubscribedDevices        = null;
+
+    private HashMap<String, Long>                                mSubscriberSequenceNumber = null;
+
+    public ResPresenceManager() {
+
+        mDeviceSubscriber = new HashMap<>();
+        mSubscribedDevices = new HashMap<>();
+        mSubscriberSequenceNumber = new HashMap<>();
+    }
+
+    public static ResPresenceManager getInstance() {
+        return mResPresenceManager;
+    }
+
+    public void addObserver(Device srcDevice, IRequest request,
+            List<String> deviceIdList) {
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = mDeviceSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                subscribers = new HashMap<>();
+                mDeviceSubscriber.put(deviceId, subscribers);
+            }
+
+            subscribers.put(request.getRequestId(),
+                    new PresenceSubscriber(srcDevice, request));
+        }
+
+        mSubscribedDevices.put(request.getRequestId(), deviceIdList);
+        mSubscriberSequenceNumber.put(request.getRequestId(), (long) 1);
+
+        return;
+    }
+
+    public void removeObserver(IRequest request) {
+
+        List<String> deviceIdList = mSubscribedDevices
+                .get(request.getRequestId());
+
+        if (deviceIdList == null) {
+            return;
+        }
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = mDeviceSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                continue;
+            }
+
+            subscribers.remove(request.getRequestId());
+        }
+    }
+
+    public void notifyToObservers(String deviceId,
+            ArrayList<ResPresencePayload> resPayloadList) {
+
+        HashMap<String, PresenceSubscriber> tokenNSubscribers = mDeviceSubscriber
+                .get(deviceId);
+
+        if (tokenNSubscribers != null) {
+
+            for (PresenceSubscriber subscriber : tokenNSubscribers.values()) {
+
+                for (ResPresencePayload resPayload : resPayloadList) {
+                    subscriber.mSubscriber.sendResponse(
+                            MessageBuilder.createResponse(subscriber.mRequest,
+                                    ResponseStatus.CONTENT,
+                                    ContentFormat.APPLICATION_CBOR,
+                                    makeResponsePayload(
+                                            subscriber.mRequest.getRequestId(),
+                                            resPayload)));
+                }
+
+            }
+        }
+    }
+
+    private byte[] makeResponsePayload(String requestId,
+            ResPresencePayload resPayload) {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        CBORFactory f = new CBORFactory();
+        try {
+            JsonGenerator gen = f.createGenerator(out, JsonEncoding.UTF8);
+            gen.writeStartObject();
+            long sequenceId = mSubscriberSequenceNumber.get(requestId);
+            gen.writeNumberField(Constants.RS_NON, sequenceId);
+            mSubscriberSequenceNumber.put(requestId, sequenceId + 1);
+            gen.writeNumberField(Constants.RESOURCE_TTL,
+                    (long) resPayload.getTtl());
+
+            gen.writeFieldName(Constants.RS_TRIGGER);
+
+            ((CBORGenerator) gen).writeRaw((byte) (224 + resPayload.getTrg()));
+
+            gen.writeStringField(Constants.RESOURCE_TYPE, resPayload.getRt());
+
+            gen.writeStringField(Constants.HREF, resPayload.getHref());
+            gen.writeEndObject();
+
+            gen.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return out.toByteArray();
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DevicePresenceResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DevicePresenceResource.java
new file mode 100644 (file)
index 0000000..4e4d669
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.presence.device;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.db.DBManager;
+import org.iotivity.cloud.rdserver.util.TypeCastingManager;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Logger;
+
+public class DevicePresenceResource extends Resource {
+
+    private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
+
+    private class PresenceSubscriber {
+        PresenceSubscriber(Device subscriber, IRequest request) {
+            mSubscriber = subscriber;
+            mRequest = request;
+        }
+
+        public Device   mSubscriber;
+        public IRequest mRequest;
+    }
+
+    // di , token, Subscriber list
+    private HashMap<String, HashMap<String, PresenceSubscriber>> mDeviceSubscriber  = null;
+    // token, di list
+    private HashMap<String, List<String>>                        mSubscribedDevices = null;
+
+    public DevicePresenceResource() {
+        super(Arrays.asList(Constants.PREFIX_WELL_KNOWN, Constants.PREFIX_OCF,
+                Constants.DEVICE_PRESENCE_URI));
+
+        mDeviceSubscriber = new HashMap<>();
+        mSubscribedDevices = new HashMap<>();
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case GET:
+                switch (request.getObserve()) {
+                    case SUBSCRIBE:
+                        response = handleRegisterRequest(srcDevice, request);
+                        break;
+                    case UNSUBSCRIBE:
+                        response = handleCancelRequest(request);
+                        break;
+                    default:
+                        throw new BadRequestException(
+                                "Subscribe or Unsubscribe required");
+                }
+                break;
+
+            case POST:
+                response = handlePostRequest(request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not supported");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    private IResponse handleRegisterRequest(Device srcDevice, IRequest request)
+            throws ServerException {
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        }
+
+        List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
+
+        if (deviceList == null) {
+            throw new PreconditionFailedException("deviceList is null");
+        }
+
+        addObserver(srcDevice, request, deviceList);
+
+        ArrayList<HashMap<String, String>> getPayload = new ArrayList<HashMap<String, String>>();
+
+        for (String deviceId : deviceList) {
+            HashMap<String, String> payloadSegment = new HashMap<String, String>();
+            payloadSegment.put(Constants.DEVICE_ID, deviceId);
+            payloadSegment.put(Constants.PRESENCE_STATE,
+                    DBManager.getInstance().findDeviceState(deviceId));
+            getPayload.add(payloadSegment);
+        }
+
+        Logger.i("Get observe response" + getPayload.toString());
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(getPayload));
+    }
+
+    private IResponse handleCancelRequest(IRequest request)
+            throws ServerException {
+
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        }
+
+        List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
+
+        if (deviceList == null) {
+            throw new PreconditionFailedException("deviceList is null");
+        }
+
+        removeObserver(request);
+
+        ArrayList<HashMap<String, String>> getPayload = new ArrayList<HashMap<String, String>>();
+
+        for (String deviceId : deviceList) {
+            HashMap<String, String> payloadSegment = new HashMap<String, String>();
+            payloadSegment.put(Constants.DEVICE_ID, deviceId);
+            payloadSegment.put(Constants.PRESENCE_STATE,
+                    DBManager.getInstance().findDeviceState(deviceId));
+            getPayload.add(payloadSegment);
+        }
+        Logger.i("Get observe response" + getPayload.toString());
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(getPayload));
+    }
+
+    public IResponse handlePostRequest(IRequest request)
+            throws ServerException {
+        // check payload
+        byte[] payload = request.getPayload();
+
+        HashMap<String, Object> parsedPayload = mCbor
+                .parsePayloadFromCbor(payload, HashMap.class);
+        String deviceId = parsedPayload.get(Constants.DEVICE_ID).toString();
+        String state = parsedPayload.get(Constants.PRESENCE_STATE).toString();
+        DeviceState deviceState = new DeviceState();
+        deviceState.setDi(deviceId);
+        deviceState.setState(state);
+
+        TypeCastingManager<DeviceState> deviceStateTypeManager = new TypeCastingManager<DeviceState>();
+        HashMap<Object, Object> storeMap = deviceStateTypeManager
+                .convertObjectToMap(deviceState);
+
+        // store db
+        DBManager.getInstance().updateDeviceState(storeMap);
+
+        // notification to observers
+        notifyToObservers(deviceId);
+        return MessageBuilder.createResponse(request, ResponseStatus.CREATED);
+    }
+
+    private void addObserver(Device srcDevice, IRequest request,
+            List<String> deviceIdList) {
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = mDeviceSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                subscribers = new HashMap<>();
+                mDeviceSubscriber.put(deviceId, subscribers);
+            }
+
+            subscribers.put(request.getRequestId(),
+                    new PresenceSubscriber(srcDevice, request));
+        }
+
+        mSubscribedDevices.put(request.getRequestId(), deviceIdList);
+    }
+
+    private void removeObserver(IRequest request) {
+
+        List<String> deviceIdList = mSubscribedDevices
+                .get(request.getRequestId());
+
+        if (deviceIdList == null) {
+            return;
+        }
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = mDeviceSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                continue;
+            }
+
+            subscribers.remove(request.getRequestId());
+        }
+    }
+
+    private void notifyToObservers(String deviceId) {
+
+        HashMap<String, String> response = new HashMap<>();
+        response.put(Constants.DEVICE_ID, deviceId);
+        String state = DBManager.getInstance().findDeviceState(deviceId);
+        response.put(Constants.PRESENCE_STATE, state);
+
+        HashMap<String, PresenceSubscriber> tokenNSubscribers = mDeviceSubscriber
+                .get(deviceId);
+
+        if (tokenNSubscribers != null) {
+            for (PresenceSubscriber subscriber : tokenNSubscribers.values()) {
+
+                subscriber.mSubscriber.sendResponse(
+                        MessageBuilder.createResponse(subscriber.mRequest,
+                                ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR,
+                                mCbor.encodingPayloadToCbor(response)));
+            }
+        }
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DeviceState.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DeviceState.java
new file mode 100644 (file)
index 0000000..72fd80c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.presence.device;
+
+public class DeviceState {
+
+    private String di;
+    private String state;
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getDi() {
+        return di;
+    }
+
+    public void setDi(String deviceId) {
+        this.di = deviceId;
+    }
+
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresencePayload.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresencePayload.java
new file mode 100644 (file)
index 0000000..8a9839a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.presence.resource;
+
+public class ResPresencePayload {
+    int    non;
+    int    ttl;
+    byte   trg;
+    String rt;
+    String href;
+
+    public int getNon() {
+        return non;
+    }
+
+    public void setNon(int non) {
+        this.non = non;
+    }
+
+    public int getTtl() {
+        return ttl;
+    }
+
+    public void setTtl(int ttl) {
+        this.ttl = ttl;
+    }
+
+    public byte getTrg() {
+        return trg;
+    }
+
+    public void setTrg(byte trg) {
+        this.trg = trg;
+    }
+
+    public String getRt() {
+        return rt;
+    }
+
+    public void setRt(String rt) {
+        this.rt = rt;
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    public void setHref(String href) {
+        this.href = href;
+    }
+}
\ No newline at end of file
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresenceResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresenceResource.java
new file mode 100644 (file)
index 0000000..1472463
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.resources.presence.resource;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.Resource;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.resources.presence.ResPresenceManager;
+
+public class ResPresenceResource extends Resource {
+
+    public ResPresenceResource() {
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.RES_PRESENCE_URI));
+    }
+
+    @Override
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        IResponse response = null;
+
+        switch (request.getMethod()) {
+            case GET:
+                response = handleRegisterRequest(srcDevice, request);
+                break;
+
+            default:
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not supported");
+        }
+
+        srcDevice.sendResponse(response);
+    }
+
+    public IResponse handleRegisterRequest(Device srcDevice, IRequest request)
+            throws ServerException {
+
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
+
+        if (queryMap == null) {
+            throw new PreconditionFailedException("query is null");
+        }
+
+        List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
+
+        if (deviceList == null) {
+            throw new PreconditionFailedException("deviceList is null");
+        }
+
+        ResPresenceManager.getInstance().addObserver(srcDevice, request,
+                deviceList);
+
+        return MessageBuilder.createResponse(request, ResponseStatus.CONTENT);
+    }
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/util/TypeCastingManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/util/TypeCastingManager.java
new file mode 100644 (file)
index 0000000..3a3597a
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.rdserver.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.iotivity.cloud.rdserver.Constants;
+
+public class TypeCastingManager<T> {
+
+    public TypeCastingManager() {
+
+    }
+
+    public void callMethod(String methodName, T objClass) {
+        try {
+            Method method = objClass.getClass().getDeclaredMethod(methodName);
+            method.invoke(objClass);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public HashMap<Object, Object> convertObjectToMap(T objClass) {
+        try {
+
+            Field[] fieldList = objClass.getClass().getDeclaredFields();
+            HashMap<Object, Object> map = new HashMap<Object, Object>();
+
+            for (Field field : fieldList) {
+                field.setAccessible(true);
+                Object value = field.get(objClass);
+                if (value != null) {
+                    String fieldName = field.getName();
+                    if (fieldName.equals("itf")) {
+                        fieldName = Constants.INTERFACE;
+                    }
+                    map.put(fieldName, value);
+                }
+            }
+
+            return map;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public T convertMaptoObject(HashMap<Object, Object> map, T objClass) {
+
+        String keyAttribute = null;
+        String methodName = null;
+        Iterator<Object> iter = map.keySet().iterator();
+        String prefixName = "set";
+        while (iter.hasNext()) {
+            keyAttribute = iter.next().toString();
+            methodName = makeMethodName(keyAttribute, prefixName);
+
+            Method[] methodList = objClass.getClass().getDeclaredMethods();
+
+            for (Method method : methodList) {
+                if (methodName.equals(method.getName())) {
+                    try {
+                        method.invoke(objClass, map.get(keyAttribute));
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        return objClass;
+    }
+
+    private String makeMethodName(String keyAttribute, String prefixName) {
+
+        // Exception case
+        if (keyAttribute.equals(Constants.INTERFACE)) {
+            keyAttribute = "itf";
+        }
+
+        String methodName = null;
+
+        methodName = prefixName + keyAttribute.substring(0, 1).toUpperCase()
+                + keyAttribute.substring(1);
+
+        return methodName;
+    }
+}
diff --git a/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java b/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java
deleted file mode 100644 (file)
index 5295d35..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.testrdserver;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.ResourceManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.JSONUtil;
-import org.junit.Test;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-public class RDServerTest {
-
-    private ResourceDirectoryResource rdResource = new ResourceDirectoryResource();
-    private CoapServer                coapServer = null;
-    private CoapClient                coapClient = null;
-
-    static class CoapClientHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-
-        ChannelHandlerContext connectCtx = null;
-
-        @Override
-        public void channelActive(ChannelHandlerContext ctx) throws Exception {
-            connectCtx = ctx;
-        }
-
-        @Override
-        protected void channelRead0(ChannelHandlerContext arg0,
-                CoapResponse arg1) throws Exception {
-            // TODO Auto-generated method stub
-
-        }
-    }
-
-    public void startServer() throws Exception {
-        coapServer = new CoapServer();
-        ResourceManager resourceManager = new ResourceManager();
-        coapServer.addHandler(resourceManager);
-        resourceManager.registerResource(new ResourceDirectoryResource());
-        coapServer.startServer(new InetSocketAddress(5683));
-    }
-
-    public ChannelHandlerContext startClient() throws Exception {
-        coapClient = new CoapClient();
-        CoapClientHandler coapHandler = new CoapClientHandler();
-        coapClient.addHandler(coapHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-        if (coapHandler.connectCtx == null) {
-                throw new IllegalArgumentException("connectCtx is null");
-        }
-        return coapHandler.connectCtx;
-    }
-
-    public CoapRequest makePublishPayload() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.POST);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("rt=oic.wk.rdpub");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        ArrayList<Object> payload = new ArrayList<Object>();
-
-        HashMap<Object, Object> tags = new HashMap<Object, Object>();
-        tags.put("di", "98f7483c-5a31-4161-ba7e-9c13e0d");
-        tags.put("bm", (int) 1);
-        tags.put("ttl", (int) 86400);
-
-        ArrayList<LinkedHashMap<Object, Object>> publishLinks = new ArrayList<LinkedHashMap<Object, Object>>();
-        LinkedHashMap<Object, Object> link = new LinkedHashMap<Object, Object>();
-        link.put("href", "/a/light");
-        ArrayList<String> rt = new ArrayList<String>();
-        ArrayList<String> itf = new ArrayList<String>();
-        ArrayList<String> mt = new ArrayList<String>();
-        rt.add("core.light");
-        link.put("rt", rt);
-
-        itf.add("oic.if.baseline");
-        link.put("if", itf);
-
-        mt.add("application/json");
-        link.put("mt", mt);
-
-        link.put("ins", 1);
-
-        publishLinks.add(link);
-
-        payload.add(tags);
-        payload.add(publishLinks);
-
-        Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
-
-        request.setPayload(cbor.encodingPayloadToCbor(payload));
-
-        return request;
-    }
-
-    @Test
-    public void testHandlePostRequest() throws Exception {
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handlePostRequest(ctx, makePublishPayload());
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-
-    }
-
-    @Test
-    public void testHandleGetRequest_notExistVaule() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("rt=core.light");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handleGetRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleGetRequest_existValue() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("rt=core.light");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handlePostRequest(ctx, makePublishPayload());
-
-        rdResource.handleGetRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleGetRequestBySt_existValue() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("rt=core.light&st=didList");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        HashMap<Object, Object> data = new HashMap<Object, Object>();
-        ArrayList<String> didList = new ArrayList<String>();
-        didList.add("98f7483c-5a31-4161-ba7e-9c13e0d");
-        data.put("devices", didList);
-        String payload = JSONUtil.writeJSON(data);
-        if (payload != null) {
-            request.setPayload(payload.getBytes(StandardCharsets.UTF_8));
-        }
-        else {
-                throw new IllegalArgumentException("payload writeJson error");
-        }
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handlePostRequest(ctx, makePublishPayload());
-
-        rdResource.handleGetRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleDeleteRequestByDi_notExistVaule() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.DELETE);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("di=98f7483c-5a31-4161-ba7e-9c13e0d");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handlePostRequest(ctx, makePublishPayload());
-
-        rdResource.handleDeleteRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleDeleteRequestByDi_existVaule() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.DELETE);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("di=98f7483c-5a31-4161-ba7e-9c13e0d");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handleDeleteRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleDeleteRequestByIns_notExistVaule() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.DELETE);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("di=98f7483c-5a31-4161-ba7e-9c13e0d&ins=1");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handleDeleteRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testHandleDeleteRequestByIns_existVaule() throws Exception {
-
-        CoapRequest request = new CoapRequest(CoapMethod.DELETE);
-        request.setUriPath(Constants.RD_URI);
-        request.setUriQuery("di=98f7483c-5a31-4161-ba7e-9c13e0d&ins=1");
-        request.setToken("1234".getBytes(StandardCharsets.UTF_8));
-
-        startServer();
-        ChannelHandlerContext ctx = startClient();
-
-        rdResource.handlePostRequest(ctx, makePublishPayload());
-
-        rdResource.handleDeleteRequest(ctx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-}
diff --git a/cloud/stack/.project b/cloud/stack/.project
deleted file mode 100644 (file)
index c3fbeb0..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>CloudStack</name>
-       <comment></comment>
-       <projects>
-       </projects>
-       <buildSpec>
-               <buildCommand>
-                       <name>org.eclipse.jdt.core.javabuilder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.m2e.core.maven2Builder</name>
-                       <arguments>
-                       </arguments>
-               </buildCommand>
-       </buildSpec>
-       <natures>
-               <nature>org.eclipse.jdt.core.javanature</nature>
-               <nature>org.eclipse.m2e.core.maven2Nature</nature>
-       </natures>
-</projectDescription>
index f04a936..faeedc7 100644 (file)
@@ -6,6 +6,7 @@
   
   <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.test.skip>true</maven.test.skip>
        </properties>
        
   <dependencies>
@@ -22,7 +23,7 @@
                <dependency>
                        <groupId>io.netty</groupId>
                        <artifactId>netty-all</artifactId>
-                       <version>4.0.29.Final</version>
+                       <version>4.1.1.Final</version>
                </dependency>
                <dependency>
                        <groupId>commons-codec</groupId>
                <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
-               <version>2.4.0</version>
+               <version>2.7.4</version>
                </dependency>
                <dependency>
                        <groupId>com.fasterxml.jackson.dataformat</groupId>
                        <artifactId>jackson-dataformat-cbor</artifactId>
-                       <version>2.4.0</version>
+                       <version>2.7.4</version>
                </dependency>
        </dependencies>
        
@@ -58,8 +59,8 @@
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <configuration>
-                                       <source>1.7</source>
-                                       <target>1.7</target>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
                                        <encoding>UTF-8</encoding>
                                </configuration>
                        </plugin>
diff --git a/cloud/stack/src/main/java/log4j.properties b/cloud/stack/src/main/java/log4j.properties
new file mode 100644 (file)
index 0000000..c8901fa
--- /dev/null
@@ -0,0 +1,11 @@
+# Root logger option
+log4j.rootLogger=FATAL, file
+
+# Redirect log messages to a log file, support file rolling.
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=./log/cloud.log
+#log4j.appender.file.DatePattern='.'yyyy-MM-dd
+log4j.appender.file.MaxFileSize=5MB
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+#log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java
deleted file mode 100644 (file)
index 0cf6142..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
-import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.util.concurrent.GenericFutureListener;
-
-public class CoapClient {
-
-    private static class CoAPClientInitializer
-            extends ChannelInitializer<SocketChannel> {
-
-        private List<ChannelHandler> additionalHandlers = new ArrayList<ChannelHandler>();
-
-        public CoAPClientInitializer() {
-        }
-
-        public void addHandler(ChannelHandler handler) {
-            additionalHandlers.add(handler);
-        }
-
-        @Override
-        public void initChannel(SocketChannel ch) {
-            ChannelPipeline p = ch.pipeline();
-            /*
-             * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); }
-             */
-            p.addLast(new CoapDecoder());
-            p.addLast(new CoapEncoder());
-            for (ChannelHandler handler : additionalHandlers) {
-                p.addLast(handler);
-            }
-        }
-    }
-
-    ChannelFuture channelFuture;
-
-    EventLoopGroup connectorGroup = new NioEventLoopGroup();
-
-    CoAPClientInitializer initializer = new CoAPClientInitializer();
-
-    public void addHandler(ChannelHandler handler) {
-        initializer.addHandler(handler);
-    }
-
-    public void startClient(final InetSocketAddress inetSocketAddress)
-            throws InterruptedException {
-                
-        try {
-            Bootstrap b = new Bootstrap();
-            b.group(connectorGroup);
-            b.channel(NioSocketChannel.class);
-            b.option(ChannelOption.TCP_NODELAY, true);
-            b.option(ChannelOption.SO_KEEPALIVE, true);
-            b.option(ChannelOption.SO_REUSEADDR, true);
-
-            b.handler(initializer);
-
-            channelFuture = b.connect(inetSocketAddress).sync();
-
-            channelFuture
-                    .addListener(new GenericFutureListener<ChannelFuture>() {
-                        @Override
-                        public void operationComplete(ChannelFuture future)
-                                throws Exception {
-                            Logger.d(
-                                    "Connection status of TCP CoAP CLIENT  : "
-                                            + future.isSuccess());
-                        }
-                    });
-        } finally {
-        }
-    }
-
-    public ChannelFuture getChannelFuture() {
-        return channelFuture;
-    }
-
-    public void sendRequest(CoapRequest request) {
-        channelFuture.channel().writeAndFlush(request);
-    }
-
-    public void stopClient() throws Exception {
-        connectorGroup.shutdownGracefully().await();
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java
deleted file mode 100644 (file)
index 849701d..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.net.ssl.SSLException;
-
-import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
-import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-import io.netty.util.concurrent.GenericFutureListener;
-
-public class CoapServer {
-
-    private static class CoAPServerInitializer
-            extends ChannelInitializer<SocketChannel> {
-
-        private List<ChannelHandler> additionalHandlers = new ArrayList<ChannelHandler>();
-
-        public CoAPServerInitializer() {
-        }
-
-        public void addHandler(ChannelHandler handler) {
-            additionalHandlers.add(handler);
-        }
-
-        @Override
-        public void initChannel(SocketChannel ch) {
-            ChannelPipeline p = ch.pipeline();
-            /*
-             * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); }
-             */
-            p.addLast(new CoapDecoder());
-            p.addLast(new CoapEncoder());
-            for (ChannelHandler handler : additionalHandlers) {
-                p.addLast(handler);
-            }
-        }
-    }
-
-    EventLoopGroup acceptorGroup = new NioEventLoopGroup(1);
-
-    EventLoopGroup workerGroup = new NioEventLoopGroup();
-
-    CoAPServerInitializer initializer = new CoAPServerInitializer();
-    
-    public void addHandler(ChannelHandler handler) {
-        initializer.addHandler(handler);
-    }
-
-    public void startServer(InetSocketAddress inetSocketAddress)
-            throws CertificateException, SSLException, InterruptedException {
-
-        try {
-            ServerBootstrap b = new ServerBootstrap();
-            b.group(acceptorGroup, workerGroup);
-            b.channel(NioServerSocketChannel.class);
-            b.option(ChannelOption.TCP_NODELAY, true);
-            b.option(ChannelOption.SO_KEEPALIVE, true);
-            b.handler(new LoggingHandler(LogLevel.INFO));
-
-            b.childHandler(initializer);
-
-            ChannelFuture channelFuture = b.bind(inetSocketAddress).sync();
-
-            channelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
-                @Override
-                public void operationComplete(ChannelFuture future)
-                        throws Exception {
-                    // TODO Auto-generated method stub
-                    Logger.d("Connection status of TCP CoAP SERVER  : "
-                                    + future.isSuccess());
-                }
-            });
-        } finally {
-        }
-    }
-
-    public void stopServer() throws Exception {
-       acceptorGroup.shutdownGracefully().await();
-       workerGroup.shutdownGracefully().await();
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java
deleted file mode 100644 (file)
index 55b5ab8..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-// package org.iotivity.cloud.base;
-//
-// import java.net.InetSocketAddress;
-// import java.security.cert.CertificateException;
-// import java.util.ArrayList;
-// import java.util.List;
-//
-// import javax.net.ssl.SSLException;
-//
-// import io.netty.bootstrap.ServerBootstrap;
-// import io.netty.channel.ChannelFuture;
-// import io.netty.channel.ChannelHandler;
-// import io.netty.channel.ChannelInitializer;
-// import io.netty.channel.ChannelPipeline;
-// import io.netty.channel.EventLoopGroup;
-// import io.netty.channel.nio.NioEventLoopGroup;
-// import io.netty.channel.socket.SocketChannel;
-// import io.netty.channel.socket.nio.NioServerSocketChannel;
-// import io.netty.handler.codec.http.HttpRequestDecoder;
-// import io.netty.handler.codec.http.HttpResponseEncoder;
-// import io.netty.handler.logging.LogLevel;
-// import io.netty.handler.logging.LoggingHandler;
-// import io.netty.util.concurrent.GenericFutureListener;
-//
-// public class HttpServer {
-//
-// private static class HttpServerInitializer
-// extends ChannelInitializer<SocketChannel> {
-//
-// private List<ChannelHandler> additionalHandlers = new
-// ArrayList<ChannelHandler>();
-//
-// public HttpServerInitializer() {
-// }
-//
-// public void addHandler(ChannelHandler handler) {
-// additionalHandlers.add(handler);
-// }
-//
-// @Override
-// public void initChannel(SocketChannel ch) {
-// ChannelPipeline p = ch.pipeline();
-// /*
-// * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); }
-// */
-// p.addLast(new HttpRequestDecoder());
-// // Uncomment the following line if you don't want to handle
-// // HttpChunks.
-// // p.addLast(new HttpObjectAggregator(1048576));
-// p.addLast(new HttpResponseEncoder());
-// // Remove the following line if you don't want automatic content
-// // compression.
-// // p.addLast(new HttpContentCompressor());
-// for (ChannelHandler handler : additionalHandlers) {
-// p.addLast(handler);
-// }
-// }
-//
-// }
-//
-// EventLoopGroup bossGroup = new NioEventLoopGroup(1);
-//
-// EventLoopGroup workerGroup = new NioEventLoopGroup();
-//
-// HttpServerInitializer initializer = new HttpServerInitializer();
-//
-// public void addHandler(ChannelHandler handler) {
-// initializer.addHandler(handler);
-// }
-//
-// public void startServer(InetSocketAddress inetSocketAddress)
-// throws CertificateException, SSLException, InterruptedException {
-//
-// try {
-// ServerBootstrap b = new ServerBootstrap();
-// b.group(bossGroup, workerGroup);
-// b.channel(NioServerSocketChannel.class);
-// b.handler(new LoggingHandler(LogLevel.INFO));
-//
-// b.childHandler(initializer);
-//
-// ChannelFuture ch = b.bind(inetSocketAddress).sync();
-// ch.addListener(new GenericFutureListener<ChannelFuture>() {
-//
-// @Override
-// public void operationComplete(ChannelFuture future)
-// throws Exception {
-// // TODO Auto-generated method stub
-// System.out
-// .println("Connection status of TCP Http SERVER : "
-// + future.isSuccess());
-// }
-//
-// });
-// } finally {
-// }
-//
-// }
-//
-// public void stopServer() {
-// // shut down all event loops
-// if (bossGroup != null) {
-// bossGroup.shutdownGracefully();
-//
-// try {
-// bossGroup.terminationFuture().sync();
-// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-// }
-//
-// if (workerGroup != null) {
-// workerGroup.shutdownGracefully();
-//
-// try {
-// workerGroup.terminationFuture().sync();
-// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-// }
-// }
-//
-// }
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/OCFConstants.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/OCFConstants.java
new file mode 100644 (file)
index 0000000..4242e92
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base;
+
+public class OCFConstants {
+    /* resource Interface for keep-alive */
+    public static final String DEFAULT_INTERFACE   = "oic.if.baseline";
+
+    public static final String LINK_INTERFACE      = "oic.if.ll";
+
+    public static final String PREFIX_WELL_KNOWN   = ".well-known";
+
+    public static final String PREFIX_OCF          = "ocf";
+
+    public static final String PREFIX_OIC          = "oic";
+
+    public static final String RS_INTERFACE        = "if";
+
+    /* resource url for account */
+    public static final String ACCOUNT_URI         = "account";
+
+    public static final String SESSION_URI         = "session";
+
+    public static final String DEVICE_URI          = "device";
+
+    public static final String TOKEN_REFRESH_URI   = "tokenrefresh";
+
+    /* resource uri to publish, update, delete resource info */
+    public static final String RD_URI              = "rd";
+
+    /* resource uri for keep-alive */
+    public static final String KEEP_ALIVE_URI      = "ping";
+
+    /* resource uri to discover resource info */
+    public static final String WELL_KNOWN_URI      = "res";
+
+    /* resource uri for resource presence */
+    public static final String RES_PRESENCE_URI    = "ad";
+
+    /* resource uri for device presence */
+    public static final String DEVICE_PRESENCE_URI = "prs";
+
+    /* resource uri for message queue */
+    public static final String MQ_BROKER_URI       = "ps";
+    public static final String MQ_BROKER_RT        = "oic.wk.ps";
+
+    /* file path for tls communication - Modify filePath to yours */
+    public static final String ROOT_CERT_FILE      = "./rootca.crt";
+
+    public static final String CLOUD_CERT_FILE     = "./iotivitycloud.crt";
+
+    public static final String CLOUD_KEY_FILE      = "./iotivitycloud.key";
+
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/Resource.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/Resource.java
deleted file mode 100644 (file)
index 9683bff..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-
-import io.netty.channel.ChannelHandlerContext;
-
-public abstract class Resource {
-
-    public Resource() {
-    }
-
-    private String uri;
-    private String type;
-    private String rif; // resource interface
-
-    public String getUri() {
-        return uri;
-    }
-
-    public void setUri(String uri) {
-        this.uri = uri;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getRif() {
-        return rif;
-    }
-
-    public void setRif(String rif) {
-        this.rif = rif;
-    }
-
-    public abstract void onRequestReceived(ChannelHandlerContext ctx,
-            CoapRequest request);
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java
deleted file mode 100644 (file)
index c2700df..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.util.ArrayList;
-
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-@Sharable
-public class ResourceManager extends SimpleChannelInboundHandler<CoapRequest> {
-
-    private ArrayList<Resource> resources = new ArrayList<Resource>();
-
-    @Override
-    public void channelRead0(ChannelHandlerContext ctx, CoapRequest request)
-            throws Exception {
-
-        Resource res = queryResourceHandler(request.getUriPath());
-
-        if (res != null) {
-            res.onRequestReceived(ctx, request);
-        }
-    }
-
-    private Resource queryResourceHandler(String query_uri) {
-
-        Resource res = null;
-
-        for (Resource r : resources) {
-
-            String uri = r.getUri();
-            if (uri.contains(query_uri)) {
-                res = r;
-                break;
-            }
-        }
-
-        return res;
-    }
-
-    public void registerResource(Resource res) {
-
-        synchronized (this) {
-            resources.add(res);
-        }
-    }
-
-    public void unregisterResource(Resource res) {
-
-        synchronized (this) {
-            resources.remove(res);
-        }
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/ServerSystem.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/ServerSystem.java
new file mode 100644 (file)
index 0000000..2c14d69
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.iotivity.cloud.base.connector.CoapClient;
+import org.iotivity.cloud.base.device.CoapDevice;
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+import org.iotivity.cloud.base.protocols.MessageBuilder;
+import org.iotivity.cloud.base.protocols.coap.CoapMessage;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.base.resource.ResourceManager;
+import org.iotivity.cloud.base.server.CoapServer;
+import org.iotivity.cloud.base.server.HttpServer;
+import org.iotivity.cloud.base.server.Server;
+import org.iotivity.cloud.util.ErrorLogger;
+
+import io.netty.channel.ChannelDuplexHandler;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.util.AttributeKey;
+
+public class ServerSystem extends ResourceManager {
+    private List<Server>                  mServerList = new ArrayList<>();
+    protected static AttributeKey<Device> keyDevice   = AttributeKey
+            .newInstance("device");
+
+    @Sharable
+    public class PersistentPacketReceiver
+            extends SimpleChannelInboundHandler<CoapMessage> {
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) {
+
+            StringBuilder deviceId = new StringBuilder(
+                    ctx.channel().id().asLongText().substring(26));
+            deviceId.deleteCharAt(25);
+            deviceId.insert(13, '-');
+            deviceId.insert(18, '-');
+            deviceId.insert(23, '-');
+            Device device = new CoapDevice(ctx, deviceId.toString(), null);
+            ctx.channel().attr(keyDevice).set(device);
+
+            device.onConnected();
+        }
+
+        @Override
+        protected void channelRead0(ChannelHandlerContext ctx,
+                CoapMessage msg) {
+            try {
+                // Find proper device and raise event.
+                Device targetDevice = ctx.channel().attr(keyDevice).get();
+
+                if (targetDevice == null) {
+                    throw new InternalServerErrorException();
+                }
+
+                if (msg instanceof CoapRequest) {
+                    onRequestReceived(targetDevice, (CoapRequest) msg);
+                } else if (msg instanceof CoapResponse) {
+                    // TODO: Re-architecturing required
+                    IRequestChannel reqChannel = ((CoapDevice) targetDevice)
+                            .getRequestChannel();
+                    CoapClient coapClient = (CoapClient) reqChannel;
+                    coapClient.onResponseReceived(msg);
+                }
+
+            } catch (ServerException e) {
+                ctx.channel().writeAndFlush(MessageBuilder.createResponse(msg,
+                        e.getErrorResponse()));
+                ErrorLogger.write(ctx.channel(), e);
+            } catch (ClientException e) {
+                ErrorLogger.write(ctx.channel(), e);
+            } catch (Throwable t) {
+                ErrorLogger.write(ctx.channel(), t);
+                if (msg instanceof CoapRequest) {
+                    ctx.channel().writeAndFlush(MessageBuilder.createResponse(
+                            msg, ResponseStatus.INTERNAL_SERVER_ERROR));
+                    ctx.channel().close();
+                }
+            }
+        }
+
+        @Override
+        public void channelInactive(ChannelHandlerContext ctx)
+                throws Exception {
+            Device device = ctx.channel().attr(keyDevice).get();
+            device.onDisconnected();
+            ctx.channel().attr(keyDevice).remove();
+        }
+    }
+
+    @Sharable
+    public class NonPersistentPacketReceiver extends ChannelDuplexHandler {
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) throws Exception {
+            // onDeviceConnected(ctx)
+        }
+
+        @Override
+        public void channelRead(ChannelHandlerContext ctx, Object msg)
+                throws Exception {
+            // Find proper device and raise event.
+            // onRequestReceived(new Device(ctx), msg);
+        }
+    }
+
+    public void addServer(Server server) {
+        if (server instanceof CoapServer) {
+            server.addHandler(new PersistentPacketReceiver());
+        }
+
+        if (server instanceof HttpServer) {
+            server.addHandler(new NonPersistentPacketReceiver());
+        }
+        mServerList.add(server);
+    }
+
+    public void startSystem(boolean tlsMode) throws Exception {
+        for (Server server : mServerList) {
+            server.startServer(tlsMode);
+        }
+    }
+
+    public void stopSystem() throws Exception {
+        for (Server server : mServerList) {
+            server.stopServer();
+        }
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java
deleted file mode 100644 (file)
index 9b795c3..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Objects;
-
-import io.netty.channel.ChannelHandlerContext;
-
-public class SessionManager {
-
-    HashMap<String, ChannelHandlerContext> sessions = new HashMap<String, ChannelHandlerContext>();
-
-    public void addSession(String did, ChannelHandlerContext ctx) {
-        synchronized (sessions) {
-            sessions.put(did, ctx);
-        }
-    }
-
-    public void removeSession(String did) {
-
-        synchronized (sessions) {
-            sessions.remove(did);
-        }
-    }
-
-    public void removeSessionByChannel(ChannelHandlerContext ctx) {
-
-        String did = queryDid(ctx);
-        if (did != null) {
-            removeSession(did);
-        }
-    }
-
-    public ChannelHandlerContext querySession(String did) {
-        ChannelHandlerContext ctx = null;
-
-        synchronized (sessions) {
-            ctx = sessions.get(did);
-        }
-
-        return ctx;
-    }
-
-    public String queryDid(ChannelHandlerContext ctx) {
-        synchronized (sessions) {
-            for (Entry<String, ChannelHandlerContext> entry : sessions
-                    .entrySet()) {
-                if (Objects.equals(ctx, entry.getValue())) {
-                    return entry.getKey();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public List<String> getSessions() {
-        synchronized (sessions) {
-            List<String> list = new ArrayList<String>(sessions.keySet());
-            return list;
-        }
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapClient.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapClient.java
new file mode 100644 (file)
index 0000000..dc3d47b
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.connector;
+
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.device.IRequestChannel;
+import org.iotivity.cloud.base.device.IResponseEventHandler;
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.exception.ClientException.RequesterGoneException;
+import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.iotivity.cloud.base.protocols.enums.Observe;
+import org.iotivity.cloud.util.Bytes;
+import org.iotivity.cloud.util.ErrorLogger;
+
+import io.netty.channel.Channel;
+
+public class CoapClient implements IRequestChannel, IResponseEventHandler {
+
+    private class RequestInfo {
+        private byte[]                originToken     = null;
+        private IResponseEventHandler responseHandler = null;
+        private Observe               observe         = Observe.NOTHING;
+
+        public RequestInfo(byte[] originToken,
+                IResponseEventHandler responseHandler, Observe observe) {
+            this.originToken = originToken;
+            this.responseHandler = responseHandler;
+            this.observe = observe;
+        }
+    }
+
+    private HashMap<Long, RequestInfo> mTokenExchanger = new HashMap<>();
+    private Long                       mToken          = 0L;
+    private Channel                    mChannel        = null;
+
+    private HashMap<Long, Long>        mSubscription   = new HashMap<>();
+
+    public CoapClient(Channel channel) {
+        mChannel = channel;
+    }
+
+    @Override
+    public void sendRequest(IRequest request,
+            IResponseEventHandler responseEvent) {
+        // Exchange request token to internal token and
+        // add token with responseHandler to map
+        try {
+            byte[] token = null;
+            long newToken;
+            synchronized (mToken) {
+                newToken = mToken;
+            }
+
+            CoapRequest coapRequest = (CoapRequest) request;
+
+            token = coapRequest.getToken();
+
+            Observe observe = request.getObserve();
+
+            switch (request.getObserve()) {
+                case UNSUBSCRIBE:
+                    newToken = mSubscription.remove(Bytes.bytesToLong(token));
+                    break;
+
+                case SUBSCRIBE:
+                    mSubscription.put(Bytes.bytesToLong(token), newToken);
+                default:
+                    // We create temp token
+                    // TODO: temporal handling
+                    if (request.getUriPath().equals("/oic/ad")) {
+                        mSubscription.put(Bytes.bytesToLong(token), newToken);
+                        observe = Observe.SUBSCRIBE;
+                    }
+                    synchronized (mToken) {
+                        newToken = mToken++;
+                    }
+                    break;
+            }
+
+            coapRequest.setToken(Bytes.longTo8Bytes(newToken));
+            mTokenExchanger.put(newToken,
+                    new RequestInfo(token, responseEvent, observe));
+
+            mChannel.writeAndFlush(request);
+
+        } catch (Exception e) {
+            ErrorLogger.write(mChannel, e);
+        }
+    }
+
+    @Override
+    public void onResponseReceived(IResponse response) throws ClientException {
+        // Response received from this device.
+        // Exchange internal token to request token
+        // And call actual requester device
+
+        // Response is always CoapResponse
+        CoapResponse coapResponse = (CoapResponse) response;
+
+        RequestInfo reqInfo = mTokenExchanger
+                .get(Bytes.bytesToLong(coapResponse.getToken()));
+
+        if (reqInfo == null) {
+            throw new RequesterGoneException("Unable to find "
+                    + Bytes.bytesToLong(coapResponse.getToken()));
+        }
+
+        // Subscription response should stored
+        if (reqInfo.observe != Observe.SUBSCRIBE) {
+            mTokenExchanger.remove(Bytes.bytesToLong(coapResponse.getToken()));
+        }
+
+        coapResponse.setToken(reqInfo.originToken);
+        reqInfo.responseHandler.onResponseReceived(response);
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapConnector.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapConnector.java
new file mode 100644 (file)
index 0000000..bba5344
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.connector;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.net.ssl.SSLException;
+
+import org.iotivity.cloud.base.OCFConstants;
+import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
+import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
+import org.iotivity.cloud.base.protocols.coap.CoapLogHandler;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
+
+public class CoapConnector {
+
+    public CoapConnector() {
+
+        mBootstrap.group(mConnectorGroup);
+        mBootstrap.channel(NioSocketChannel.class);
+        mBootstrap.option(ChannelOption.TCP_NODELAY, true);
+        mBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
+        mBootstrap.option(ChannelOption.SO_REUSEADDR, true);
+    }
+
+    @Sharable
+    private class CoapPacketHandler
+            extends SimpleChannelInboundHandler<CoapResponse> {
+
+        @Override
+        protected void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
+                throws Exception {
+            mChannelMap.get(ctx.channel()).onResponseReceived(msg);
+        }
+    }
+
+    public static class CoapConnectorInitializer
+            extends ChannelInitializer<SocketChannel> {
+
+        private List<ChannelHandler> additionalHandlers = new ArrayList<>();
+
+        private Boolean              mTlsMode           = false;
+        InetSocketAddress            mInetSocketAddress = null;
+        String                       mRootCertFiePath   = null;
+
+        public void setTlsMode(Boolean tlsMode) {
+            this.mTlsMode = tlsMode;
+        }
+
+        public void setInetSocketAddress(InetSocketAddress address) {
+            this.mInetSocketAddress = address;
+        }
+
+        public void setRootCertFilePath(String path) {
+            this.mRootCertFiePath = path;
+        }
+
+        public void addHandler(ChannelHandler handler) {
+            additionalHandlers.add(handler);
+        }
+
+        @Override
+        public void initChannel(SocketChannel ch) {
+            ChannelPipeline p = ch.pipeline();
+
+            SslContext sslContext = null;
+
+            if (mTlsMode.equals(true)) {
+
+                File rootCert = new File(mRootCertFiePath);
+
+                try {
+                    sslContext = SslContextBuilder.forClient()
+                            .sslProvider(SslProvider.JDK).trustManager(rootCert)
+                            .build();
+                } catch (SSLException e) {
+                    e.printStackTrace();
+                }
+
+                final SslContext sslCtx = sslContext;
+                p.addLast(sslCtx.newHandler(ch.alloc(),
+                        mInetSocketAddress.getHostString(),
+                        mInetSocketAddress.getPort()));
+            }
+
+            p.addLast(new CoapDecoder());
+            p.addLast(new CoapEncoder());
+            p.addLast(new CoapLogHandler());
+            for (ChannelHandler handler : additionalHandlers) {
+                p.addLast(handler);
+            }
+        }
+    }
+
+    HashMap<Channel, CoapClient> mChannelMap     = new HashMap<>();
+
+    Bootstrap                    mBootstrap      = new Bootstrap();
+    EventLoopGroup               mConnectorGroup = new NioEventLoopGroup();
+
+    public CoapClient connect(final InetSocketAddress inetSocketAddress,
+            boolean tlsMode) throws InterruptedException {
+
+        CoapConnectorInitializer initializer = new CoapConnectorInitializer();
+
+        if (tlsMode == true) {
+            initializer.setTlsMode(true);
+            initializer.setInetSocketAddress(inetSocketAddress);
+            initializer.setRootCertFilePath(OCFConstants.ROOT_CERT_FILE);
+        }
+
+        initializer.addHandler(new CoapPacketHandler());
+        mBootstrap.handler(initializer);
+
+        ChannelFuture channelFuture = null;
+        channelFuture = mBootstrap.connect(inetSocketAddress).sync();
+
+        CoapClient coapClient = null;
+        coapClient = new CoapClient(channelFuture.channel());
+        mChannelMap.put(channelFuture.channel(), coapClient);
+
+        return coapClient;
+    }
+
+    public void disconenct() throws Exception {
+        mConnectorGroup.shutdownGracefully().await();
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/ConnectorPool.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/connector/ConnectorPool.java
new file mode 100644 (file)
index 0000000..a4f3fef
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.connector;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.device.IRequestChannel;
+
+public class ConnectorPool {
+
+    static HashMap<String, IRequestChannel> mConnection = new HashMap<>();
+
+    static CoapConnector                    mConnector  = new CoapConnector();
+
+    public ConnectorPool() {
+
+    }
+
+    public static void addConnection(String name, InetSocketAddress inetAddr,
+            boolean tlsMode) throws InterruptedException {
+        mConnection.put(name, mConnector.connect(inetAddr, tlsMode));
+    }
+
+    public static IRequestChannel getConnection(String name) {
+        return mConnection.get(name);
+    }
+}
@@ -1,24 +1,25 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
+package org.iotivity.cloud.base.connector;
 // package org.iotivity.cloud.base;
 //
 // import java.net.URI;
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/CoapDevice.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/CoapDevice.java
new file mode 100644 (file)
index 0000000..554f52d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import java.util.Date;
+
+import org.iotivity.cloud.base.connector.CoapClient;
+import org.iotivity.cloud.base.protocols.IResponse;
+import org.iotivity.cloud.util.Logger;
+
+import io.netty.channel.ChannelHandlerContext;
+
+public class CoapDevice extends Device {
+    private CoapClient mCoapClient    = null;
+    private String     mDeviceId;
+    private String     mAccessToken   = null;
+    private Date       mIssuedTime    = null;
+    private int        mExpiredPolicy = 0;
+
+    public CoapDevice(ChannelHandlerContext ctx, String deviceId,
+            String accessToken) {
+        super(ctx);
+        mDeviceId = deviceId;
+        mAccessToken = accessToken;
+    }
+
+    @Override
+    public String getDeviceId() {
+        return mDeviceId;
+    }
+
+    public String getAccessToken() {
+        return mAccessToken;
+    }
+
+    public Date getIssuedTime() {
+        return mIssuedTime;
+    }
+
+    public int getExpiredPolicy() {
+        return mExpiredPolicy;
+    }
+
+    public void setExpiredPolicy(int expiredPolicy) {
+        mIssuedTime = new Date();
+        this.mExpiredPolicy = expiredPolicy;
+    }
+
+    // This is called by cloud resource model
+    @Override
+    public void sendResponse(IResponse response) {
+        // This message must converted to CoapResponse
+        ctx.channel().writeAndFlush(response);
+    }
+
+    public IRequestChannel getRequestChannel() {
+        if (mCoapClient == null) {
+            mCoapClient = new CoapClient(ctx.channel());
+        }
+
+        return mCoapClient;
+    }
+
+    public boolean isExpiredTime() {
+
+        Date currentTime = new Date();
+        long difference = currentTime.getTime() - mIssuedTime.getTime();
+        long remainTime = mExpiredPolicy - difference / 1000;
+
+        if (remainTime < 0) {
+
+            Logger.w("accessToken is expired..");
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void onConnected() {
+    }
+
+    @Override
+    public void onDisconnected() {
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/Device.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/Device.java
new file mode 100644 (file)
index 0000000..da67851
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import org.iotivity.cloud.base.protocols.IResponse;
+
+import io.netty.channel.ChannelHandlerContext;
+
+public abstract class Device implements IResponseEventHandler {
+    protected ChannelHandlerContext ctx;
+
+    public Device(ChannelHandlerContext ctx) {
+        this.ctx = ctx;
+    }
+
+    public ChannelHandlerContext getCtx() {
+        return ctx;
+    }
+
+    @Override
+    public void onResponseReceived(IResponse response) {
+        // Response can received from other device.
+        // Simply send to source device
+        sendResponse(response);
+    }
+
+    public abstract void sendResponse(IResponse response);
+
+    public abstract void onConnected();
+
+    public abstract void onDisconnected();
+
+    public abstract String getDeviceId();
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/HttpDevice.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/HttpDevice.java
new file mode 100644 (file)
index 0000000..9702138
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import org.iotivity.cloud.base.protocols.IResponse;
+
+import io.netty.channel.ChannelHandlerContext;
+
+public class HttpDevice extends Device {
+    public HttpDevice(ChannelHandlerContext ctx) {
+        super(ctx);
+    }
+
+    @Override
+    public void sendResponse(IResponse response) {
+        // This message must converted to HttpResponse
+    }
+
+    @Override
+    public void onConnected() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void onDisconnected() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public String getDeviceId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestChannel.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestChannel.java
new file mode 100644 (file)
index 0000000..0030271
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import org.iotivity.cloud.base.protocols.IRequest;
+
+public interface IRequestChannel {
+    public void sendRequest(IRequest request,
+            IResponseEventHandler responseEvent);
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestEventHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IRequestEventHandler.java
new file mode 100644 (file)
index 0000000..23eb0bc
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.protocols.IRequest;
+
+public interface IRequestEventHandler {
+    void onRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException;
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IResponseEventHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/device/IResponseEventHandler.java
new file mode 100644 (file)
index 0000000..9256a22
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.device;
+
+import org.iotivity.cloud.base.exception.ClientException;
+import org.iotivity.cloud.base.protocols.IResponse;
+
+public interface IResponseEventHandler {
+    void onResponseReceived(IResponse response) throws ClientException;
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ClientException.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ClientException.java
new file mode 100644 (file)
index 0000000..2234957
--- /dev/null
@@ -0,0 +1,25 @@
+package org.iotivity.cloud.base.exception;
+
+public class ClientException extends Exception {
+    private static final long serialVersionUID = -1054509324241250664L;
+
+    ClientException(String msg) {
+        super(msg);
+    }
+
+    public static class RequesterGoneException extends ClientException {
+        private static final long serialVersionUID = 6205209551209108501L;
+
+        public RequesterGoneException(String msg) {
+            super(msg);
+        }
+    }
+
+    public static class BadResponseException extends ClientException {
+        private static final long serialVersionUID = 6205209551209108501L;
+
+        public BadResponseException(String msg) {
+            super(msg);
+        }
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ServerException.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/exception/ServerException.java
new file mode 100644 (file)
index 0000000..5d0309f
--- /dev/null
@@ -0,0 +1,106 @@
+package org.iotivity.cloud.base.exception;
+
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+
+public class ServerException extends RuntimeException {
+    private static final long serialVersionUID = -3650388853103279698L;
+    private ResponseStatus    mErrorResponse   = ResponseStatus.INTERNAL_SERVER_ERROR;
+
+    public ServerException(ResponseStatus errorResponse) {
+        super(errorResponse.toString());
+        mErrorResponse = errorResponse;
+    }
+
+    public ServerException(ResponseStatus errorResponse, String msg) {
+        super(errorResponse.toString() + ", " + msg);
+        mErrorResponse = errorResponse;
+    }
+
+    public ResponseStatus getErrorResponse() {
+        return mErrorResponse;
+    }
+
+    public static class BadRequestException extends ServerException {
+        private static final long serialVersionUID = -7903463045263420748L;
+
+        public BadRequestException() {
+            super(ResponseStatus.BAD_REQUEST);
+        }
+
+        public BadRequestException(String msg) {
+            super(ResponseStatus.BAD_REQUEST, msg);
+        }
+    }
+
+    public static class NotFoundException extends ServerException {
+        private static final long serialVersionUID = 775328915430229701L;
+
+        public NotFoundException() {
+            super(ResponseStatus.NOT_FOUND);
+        }
+
+        public NotFoundException(String msg) {
+            super(ResponseStatus.NOT_FOUND, msg);
+        }
+    }
+
+    public static class UnAuthorizedException extends ServerException {
+        private static final long serialVersionUID = -1413182067769946759L;
+
+        public UnAuthorizedException() {
+            super(ResponseStatus.UNAUTHORIZED);
+        }
+
+        public UnAuthorizedException(String msg) {
+            super(ResponseStatus.UNAUTHORIZED, msg);
+        }
+    }
+
+    public static class InternalServerErrorException extends ServerException {
+        private static final long serialVersionUID = -4873009823652617325L;
+
+        public InternalServerErrorException() {
+            super(ResponseStatus.INTERNAL_SERVER_ERROR);
+        }
+
+        public InternalServerErrorException(String msg) {
+            super(ResponseStatus.INTERNAL_SERVER_ERROR, msg);
+        }
+    }
+
+    public static class PreconditionFailedException extends ServerException {
+        private static final long serialVersionUID = -4139595328143251734L;
+
+        public PreconditionFailedException() {
+            super(ResponseStatus.PRECONDITION_FAILED);
+        }
+
+        public PreconditionFailedException(String msg) {
+            super(ResponseStatus.PRECONDITION_FAILED, msg);
+        }
+    }
+
+    public static class ForbiddenException extends ServerException {
+        private static final long serialVersionUID = -2217447793288515253L;
+
+        public ForbiddenException() {
+            super(ResponseStatus.FORBIDDEN);
+        }
+
+        public ForbiddenException(String msg) {
+            super(ResponseStatus.FORBIDDEN, msg);
+        }
+    }
+
+    public static class NotImplementedException extends ServerException {
+        private static final long serialVersionUID = 5699911106834702025L;
+
+        public NotImplementedException() {
+            super(ResponseStatus.NOT_IMPLEMENTED);
+        }
+
+        public NotImplementedException(String msg) {
+            super(ResponseStatus.NOT_IMPLEMENTED, msg);
+        }
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IRequest.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IRequest.java
new file mode 100644 (file)
index 0000000..7c0d849
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.protocols.enums.Observe;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+
+public interface IRequest {
+    public RequestMethod getMethod();
+
+    public List<String> getUriPathSegments();
+
+    public String getUriPath();
+
+    public String getUriQuery();
+
+    public List<String> getUriQuerySegments();
+
+    public HashMap<String, List<String>> getUriQueryMap();
+
+    public int getPayloadSize();
+
+    public byte[] getPayload();
+
+    public Observe getObserve();
+
+    public String getRequestId();
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IResponse.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/IResponse.java
new file mode 100644 (file)
index 0000000..236640f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols;
+
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+
+public interface IResponse {
+    public ResponseStatus getStatus();
+
+    public int getPayloadSize();
+
+    public byte[] getPayload();
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/Message.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/Message.java
new file mode 100644 (file)
index 0000000..91e3df8
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public abstract class Message implements IRequest, IResponse {
+    protected List<byte[]> uri_path  = null;
+    protected List<byte[]> uri_query = null;
+    protected byte[]       payload   = null;
+
+    // Message properties are intersection of HTTP and COAP with observe.
+
+    @Override
+    public List<String> getUriPathSegments() {
+        if (uri_path == null) {
+            return null;
+        }
+        List<String> segments = new ArrayList<>();
+        for (byte[] pathSegment : uri_path) {
+            segments.add(new String(pathSegment, StandardCharsets.UTF_8));
+        }
+        return segments;
+    }
+
+    @Override
+    public String getUriPath() {
+        if (uri_path == null) {
+            return null;
+        }
+        StringBuilder path = new StringBuilder("/");
+        int nItem = uri_path.size();
+        for (byte[] pathSegment : uri_path) {
+            path.append(new String(pathSegment, StandardCharsets.UTF_8));
+            if (--nItem > 0) {
+                path.append('/');
+            }
+        }
+        return path.toString();
+    }
+
+    @Override
+    public String getUriQuery() {
+        if (uri_query == null) {
+            return null;
+        }
+        StringBuilder uriQuery = new StringBuilder();
+        int nItem = uri_query.size();
+        for (byte[] querySegment : uri_query) {
+            uriQuery.append(new String(querySegment, StandardCharsets.UTF_8));
+            if (--nItem > 0) {
+                uriQuery.append('&');
+            }
+        }
+        return uriQuery.toString();
+    }
+
+    @Override
+    public List<String> getUriQuerySegments() {
+        if (uri_query == null) {
+            return null;
+        }
+        List<String> segments = new ArrayList<>();
+        for (byte[] querySegment : uri_query) {
+            segments.add(new String(querySegment, StandardCharsets.UTF_8));
+        }
+        return segments;
+    }
+
+    @Override
+    public HashMap<String, List<String>> getUriQueryMap() {
+
+        List<String> segments = getUriQuerySegments();
+        if (segments == null) {
+            return null;
+        }
+
+        HashMap<String, List<String>> queryMap = new HashMap<>();
+        for (String segment : segments) {
+            StringTokenizer keyValuePair = new StringTokenizer(segment, "=");
+            if (keyValuePair.countTokens() == 2) {
+                String key = keyValuePair.nextToken();
+                String value = keyValuePair.nextToken();
+                if (queryMap.containsKey(key) == false) {
+                    queryMap.put(key, new ArrayList<String>());
+                }
+                queryMap.get(key).add(value);
+            }
+        }
+
+        return queryMap;
+    }
+
+    @Override
+    public int getPayloadSize() {
+        return payload == null ? 0 : payload.length;
+    }
+
+    @Override
+    public byte[] getPayload() {
+        return payload;
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/MessageBuilder.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/MessageBuilder.java
new file mode 100644 (file)
index 0000000..c68954a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols;
+
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+
+public class MessageBuilder {
+
+    public static IResponse createResponse(IRequest request,
+            ResponseStatus responseStatus) {
+        return createResponse(request, responseStatus, ContentFormat.NO_CONTENT,
+                null);
+    }
+
+    public static IResponse createResponse(IRequest request,
+            ResponseStatus responseStatus, ContentFormat format,
+            byte[] payload) {
+
+        IResponse response = null;
+
+        if (request instanceof CoapRequest) {
+            CoapRequest coapRequest = (CoapRequest) request;
+            CoapResponse coapResponse = new CoapResponse(responseStatus);
+            coapResponse.setToken(coapRequest.getToken());
+            if (payload != null) {
+                coapResponse.setContentFormat(format);
+                coapResponse.setPayload(payload);
+            }
+
+            if (coapRequest.getMethod() == RequestMethod.GET
+                    && responseStatus == ResponseStatus.CONTENT) {
+                switch (coapRequest.getObserve()) {
+                    case SUBSCRIBE:
+                    case SEQUENCE_NUMBER:
+                        coapResponse.setSequenceNumber(
+                                coapRequest.getNextSequenceNumber());
+                        break;
+                    default:
+                }
+            }
+
+            response = coapResponse;
+        }
+
+        return response;
+    }
+
+    public static IRequest createRequest(RequestMethod requestMethod,
+            String uriPath, String uriQuery) {
+        return createRequest(requestMethod, uriPath, uriQuery,
+                ContentFormat.NO_CONTENT, null);
+    }
+
+    public static IRequest createRequest(RequestMethod requestMethod,
+            String uriPath, String uriQuery, ContentFormat contentFormat,
+            byte[] payload) {
+
+        CoapRequest coapRequest = null;
+
+        coapRequest = new CoapRequest(requestMethod);
+        // TODO: Random token generation required
+        coapRequest.setToken("tmptoken".getBytes());
+        coapRequest.setUriPath(uriPath);
+        if (uriQuery != null) {
+            coapRequest.setUriQuery(uriQuery);
+        }
+        if (payload != null) {
+            coapRequest.setContentFormat(contentFormat);
+            coapRequest.setPayload(payload);
+        }
+
+        return coapRequest;
+    }
+
+    public static IRequest modifyRequest(IRequest orgRequest, String uriPath,
+            String uriQuery, ContentFormat contentFormat, byte[] payload) {
+
+        CoapRequest coapRequest = (CoapRequest) orgRequest;
+
+        if (uriPath != null) {
+            coapRequest.setUriPath(uriPath);
+        }
+        if (uriQuery != null) {
+            coapRequest.setUriQuery(uriQuery);
+        }
+        if (payload != null) {
+            coapRequest.setContentFormat(contentFormat);
+            coapRequest.setPayload(payload);
+        }
+
+        return coapRequest;
+    }
+
+    public static IResponse modifyResponse(IResponse orgResponse,
+            ContentFormat contentFormat, byte[] payload) {
+
+        CoapResponse coapResponse = (CoapResponse) orgResponse;
+
+        if (payload != null) {
+            coapResponse.setContentFormat(contentFormat);
+            coapResponse.setPayload(payload);
+        }
+
+        return coapResponse;
+    }
+}
index 283d214..cf384ea 100644 (file)
@@ -1,31 +1,28 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.base.protocols.coap;
 
 import java.util.List;
 
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
@@ -46,6 +43,7 @@ public class CoapDecoder extends ByteToMessageDecoder {
     protected void decode(ChannelHandlerContext ctx, ByteBuf in,
             List<Object> out) throws Exception {
 
+        // TODO: need exceptional case handling
         while (in.isReadable(bufferToRead)) {
 
             switch (nextState) {
@@ -104,9 +102,9 @@ public class CoapDecoder extends ByteToMessageDecoder {
                     int code = in.readByte() & 0xFF;
 
                     if (code <= 31) {
-                        partialMsg = new CoapRequest(CoapMethod.valueOf(code));
+                        partialMsg = new CoapRequest(code);
                     } else {
-                        partialMsg = new CoapResponse(CoapStatus.valueOf(code));
+                        partialMsg = new CoapResponse(code);
                     }
 
                     if (tokenLength > 0) {
index 654ce1a..53c3cc4 100644 (file)
@@ -1,23 +1,23 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.base.protocols.coap;
 
@@ -83,10 +83,16 @@ public class CoapEncoder extends MessageToByteEncoder<CoapMessage> {
             byteBuf.writeByte(
                     (14 & 0x0F) << 4 | (coapMessage.getTokenLength() & 0x0F));
             byteBuf.writeShort(((int) length - 269) & 0xFFFF);
-        } else if (length < Integer.MAX_VALUE * 2) {
+        } else if (length < 4294967294L) {
             byteBuf.writeByte(
                     (15 & 0x0F) << 4 | (coapMessage.getTokenLength() & 0x0F));
-            byteBuf.writeLong((length - 65805) & 0xFFFFFFFF);
+            byte[] size = new byte[4];
+            long payload = length - 65805;
+            for (int i = 3; i > -1; i--) {
+                size[i] = (byte) (payload & 0xFF);
+                payload >>= 8;
+            }
+            byteBuf.writeBytes(size);
         } else {
             throw new IllegalArgumentException(
                     "Length must be less than 4GB " + length);
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapLogHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapLogHandler.java
new file mode 100644 (file)
index 0000000..7dbcf36
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.coap;
+
+import org.iotivity.cloud.util.Logger;
+
+import io.netty.channel.ChannelDuplexHandler;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+
+/**
+ *
+ * This class provides a set of APIs to print out logs for CoAP request and
+ * response.
+ *
+ */
+@Sharable
+public class CoapLogHandler extends ChannelDuplexHandler {
+
+    static final int MAX_LOGLEN = 100;
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        Logger.v(ctx.channel().id().asLongText().substring(26)
+                + " Connected, Address: "
+                + ctx.channel().remoteAddress().toString());
+
+        ctx.fireChannelActive();
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        ctx.fireChannelInactive();
+        Logger.v(ctx.channel().id().asLongText().substring(26)
+                + " Disconnected, Address: "
+                + ctx.channel().remoteAddress().toString());
+    }
+
+    @Override
+    public void write(ChannelHandlerContext ctx, Object msg,
+            ChannelPromise promise) {
+
+        String log = null;
+
+        if (msg instanceof CoapRequest) {
+            log = composeCoapRequest(
+                    ctx.channel().id().asLongText().substring(26),
+                    (CoapRequest) msg);
+        } else {
+            log = composeCoapResponse(
+                    ctx.channel().id().asLongText().substring(26),
+                    (CoapResponse) msg);
+        }
+
+        Logger.v(log);
+
+        ctx.writeAndFlush(msg);
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg)
+            throws Exception {
+
+        String log = null;
+
+        if (msg instanceof CoapRequest) {
+            log = composeCoapRequest(
+                    ctx.channel().id().asLongText().substring(26),
+                    (CoapRequest) msg);
+        } else {
+            log = composeCoapResponse(
+                    ctx.channel().id().asLongText().substring(26),
+                    (CoapResponse) msg);
+        }
+
+        Logger.v(log);
+
+        ctx.fireChannelRead(msg);
+    }
+
+    private String composeCoapRequest(String channelId, CoapRequest request) {
+        StringBuilder strBuilder = new StringBuilder();
+
+        strBuilder.append(channelId);
+        strBuilder.append(" " + request.getTokenString());
+
+        switch (request.getMethod()) {
+            case DELETE:
+                strBuilder.append(" DELETE ");
+                break;
+            case GET:
+                switch (request.getObserve()) {
+                    case SUBSCRIBE:
+                        strBuilder.append(" GET OBSERVE ");
+                        break;
+                    case UNSUBSCRIBE:
+                        strBuilder.append(" GET OBSERVE CANCEL ");
+                        break;
+                    default:
+                        strBuilder.append(" GET ");
+                        break;
+                }
+                break;
+            case POST:
+                strBuilder.append(" POST ");
+                break;
+            case PUT:
+                strBuilder.append(" PUT ");
+                break;
+        }
+
+        strBuilder.append(request.getUriPath());
+        String query = request.getUriQuery();
+        if (query != null) {
+            strBuilder.append("/?" + query);
+        }
+
+        if (request.getPayloadSize() > 0) {
+            strBuilder.append(" SZ:" + request.getPayloadSize() + " P:"
+                    + new String(request.getPayload(), 0,
+                            request.getPayloadSize() > MAX_LOGLEN ? MAX_LOGLEN
+                                    : request.getPayloadSize()));
+        }
+
+        return strBuilder.toString();
+    }
+
+    private String composeCoapResponse(String channelId,
+            CoapResponse response) {
+        StringBuilder strBuilder = new StringBuilder();
+
+        strBuilder.append(channelId);
+        strBuilder.append(" " + response.getTokenString());
+
+        switch (response.getStatus()) {
+            case BAD_GATEWAY:
+                strBuilder.append(" 5.02 Bad Gateway");
+                break;
+            case BAD_OPTION:
+                strBuilder.append(" 4.02 Bad Option");
+                break;
+            case BAD_REQUEST:
+                strBuilder.append(" 4.00 Bad Request");
+                break;
+            case CHANGED:
+                strBuilder.append(" 2.04 Changed");
+                break;
+            case CONTENT:
+                strBuilder.append(" 2.05 Content");
+                break;
+            case CREATED:
+                strBuilder.append(" 2.01 Created");
+                break;
+            case DELETED:
+                strBuilder.append(" 2.02 Deleted");
+                break;
+            case FORBIDDEN:
+                strBuilder.append(" 4.03 Forbidden");
+                break;
+            case GATEWAY_TIMEOUT:
+                strBuilder.append(" 5.04 Gateway Timeout");
+                break;
+            case INTERNAL_SERVER_ERROR:
+                strBuilder.append(" 5.00 Internal Server Error");
+                break;
+            case METHOD_NOT_ALLOWED:
+                strBuilder.append(" 4.05 Method Not Allowed");
+                break;
+            case NOT_ACCEPTABLE:
+                strBuilder.append(" 4.06 Not Acceptable");
+                break;
+            case NOT_FOUND:
+                strBuilder.append(" 4.04 Not Found");
+                break;
+            case NOT_IMPLEMENTED:
+                strBuilder.append(" 5.01 Not Implemented");
+                break;
+            case PRECONDITION_FAILED:
+                strBuilder.append(" 4.12 Precondition Failed");
+                break;
+            case PROXY_NOT_SUPPORTED:
+                strBuilder.append(" 5.05 Proxying Not Supported");
+                break;
+            case REQUEST_ENTITY_TOO_LARGE:
+                strBuilder.append(" 4.13 Request Entity Too Large");
+                break;
+            case SERVICE_UNAVAILABLE:
+                strBuilder.append(" 5.03 Service Unavailable");
+                break;
+            case UNAUTHORIZED:
+                strBuilder.append(" 4.01 Unauthorized");
+                break;
+            case UNSUPPORTED_CONTENT_FORMAT:
+                strBuilder.append(" 4.15 Unsupported Content-Format");
+                break;
+            case VALID:
+                strBuilder.append(" 2.03 Valid");
+                break;
+            default:
+                break;
+        }
+
+        switch (response.getObserve()) {
+            case SUBSCRIBE:
+                strBuilder.append(" OBSERVE");
+                break;
+            case UNSUBSCRIBE:
+                strBuilder.append(" OBSERVE CANCEL");
+                break;
+            case SEQUENCE_NUMBER:
+                strBuilder.append(" OBSERVE SEQ:");
+                strBuilder.append(response.getSequenceNumber());
+                break;
+            default:
+                break;
+        }
+
+        if (response.getPayloadSize() > 0) {
+            strBuilder.append(" SZ:" + response.getPayloadSize() + " P:"
+                    + new String(response.getPayload(), 0,
+                            response.getPayloadSize() > MAX_LOGLEN ? MAX_LOGLEN
+                                    : response.getPayloadSize()));
+        }
+
+        return strBuilder.toString();
+    }
+}
index e1db80c..c98afac 100644 (file)
@@ -1,43 +1,41 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.base.protocols.coap;
 
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 
-import org.iotivity.cloud.base.protocols.coap.enums.CoapOption;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.Logger;
+import org.iotivity.cloud.base.protocols.Message;
+import org.iotivity.cloud.base.protocols.enums.ContentFormat;
+import org.iotivity.cloud.base.protocols.enums.Observe;
+import org.iotivity.cloud.util.Bytes;
 
-public class CoapMessage {
+public abstract class CoapMessage extends Message {
 
-    private int            tokenLength    = 0;
-    protected int          code           = 0;
-    private byte[]         token          = null;
-
-    private byte[]         payload        = null;
+    protected byte[]       mToken         = null;
+    protected int          mObserve       = -1;
 
     // Option fields
     protected List<byte[]> if_match       = null;
@@ -46,55 +44,26 @@ public class CoapMessage {
     protected boolean      if_none_match  = false;
     protected byte[]       uri_port       = null;
     protected List<byte[]> location_path  = null;
-    protected List<byte[]> uri_path       = null;
-    protected byte[]       content_format = null;
+
     protected byte[]       max_age        = null;
-    protected List<byte[]> uri_query      = null;
     protected byte[]       accept         = null;
     protected List<byte[]> location_query = null;
     protected byte[]       proxy_uri      = null;
     protected byte[]       proxy_scheme   = null;
     protected byte[]       size1          = null;
-    protected byte[]       observe        = null;
+    protected byte[]       content_format = null;
 
     public CoapMessage() {
     }
 
-    public int getTokenLength() {
-        return this.tokenLength;
-    }
-
-    public int getCode() {
-        return code;
-    }
-
-    public byte[] getToken() {
-        return token;
-    }
-
-    public void setToken(byte[] token) {
-        this.token = token;
-        this.tokenLength = token.length;
-    }
-
-    public int getPayloadSize() {
-        return payload == null ? 0 : payload.length;
-    }
-
-    public byte[] getPayload() {
-        return payload;
-    }
-
-    public void setPayload(byte[] payload) {
-        this.payload = payload;
-    }
+    public abstract int getCode();
 
     public void addOption(int optnum, byte[] value) {
         switch (optnum) {
             // IF_MATCH
             case 1:
                 if (if_match == null) {
-                    if_match = new ArrayList<byte[]>();
+                    if_match = new ArrayList<>();
                 }
                 if_match.add(value);
                 break;
@@ -107,7 +76,7 @@ public class CoapMessage {
             // ETAG
             case 4:
                 if (etag == null) {
-                    etag = new ArrayList<byte[]>();
+                    etag = new ArrayList<>();
                 }
                 etag.add(value);
                 break;
@@ -125,7 +94,7 @@ public class CoapMessage {
             // LOCATION_PATH
             case 8:
                 if (location_path == null) {
-                    location_path = new ArrayList<byte[]>();
+                    location_path = new ArrayList<>();
                 }
                 location_path.add(value);
                 break;
@@ -133,7 +102,7 @@ public class CoapMessage {
             // URI_PATH
             case 11:
                 if (uri_path == null) {
-                    uri_path = new ArrayList<byte[]>();
+                    uri_path = new ArrayList<>();
                 }
                 uri_path.add(value);
                 break;
@@ -151,7 +120,7 @@ public class CoapMessage {
             // URI_QUERY
             case 15:
                 if (uri_query == null) {
-                    uri_query = new ArrayList<byte[]>();
+                    uri_query = new ArrayList<>();
                 }
                 uri_query.add(value);
                 break;
@@ -164,7 +133,7 @@ public class CoapMessage {
             // LOCATION_QUERY
             case 20:
                 if (location_query == null) {
-                    location_query = new ArrayList<byte[]>();
+                    location_query = new ArrayList<>();
                 }
                 location_query.add(value);
                 break;
@@ -186,7 +155,7 @@ public class CoapMessage {
 
             // OBSERVE
             case 6:
-                observe = value;
+                mObserve = Bytes.bytesToInt(value);
                 break;
         }
     }
@@ -257,32 +226,55 @@ public class CoapMessage {
 
             // OBSERVE
             case 6:
-                return observe != null ? Arrays.asList(observe) : null;
+                return mObserve != -1
+                        ? Arrays.asList(Bytes.intToMax4Bytes(mObserve)) : null;
         }
 
         return null;
     }
 
-    public String getTokenString() {
-        StringBuffer strBuffer = new StringBuffer(token == null ? "null" : "");
-        if (token != null)
-            for (byte b : token)
-                strBuffer.append(String.format("%02x", b & 0xff)); // hexadecimal(16)
-        return strBuffer.toString();
+    public void setPayload(byte[] payload) {
+        this.payload = payload;
     }
 
-    public String getContentFormatString() {
-        List<byte[]> contentFormatList = getOption(
-                CoapOption.CONTENT_FORMAT.getvalue());
-        byte[] contentFormat = null;
-        if (contentFormatList != null && !contentFormatList.isEmpty())
-            contentFormat = contentFormatList.get(0);
-        StringBuffer strBuffer = new StringBuffer(
-                contentFormat == null ? "null" : "");
-        if (contentFormat != null)
-            for (byte b : contentFormat)
-                strBuffer.append(String.format("%02d", b & 0xff)); // decimal(10)
-        return strBuffer.toString();
+    public void setUriPath(String path) {
+        if (uri_path == null) {
+            uri_path = new ArrayList<>();
+        } else {
+            uri_path.clear();
+        }
+
+        if (path == null || path.length() == 0) {
+            uri_path.clear();
+            uri_path = null;
+            return;
+        }
+
+        String[] pathSegments = path.split("/");
+        for (String pathSegment : pathSegments) {
+            if (pathSegment.length() == 0)
+                continue;
+            uri_path.add(pathSegment.getBytes(StandardCharsets.UTF_8));
+        }
+    }
+
+    public void setUriQuery(String query) {
+        if (uri_query == null) {
+            uri_query = new ArrayList<>();
+        } else {
+            uri_query.clear();
+        }
+
+        if (query == null || query.length() == 0) {
+            uri_query.clear();
+            uri_query = null;
+            return;
+        }
+
+        String[] querySegments = query.split("&");
+        for (String querySegment : querySegments) {
+            uri_query.add(querySegment.getBytes(StandardCharsets.UTF_8));
+        }
     }
 
     public String getPayloadString() {
@@ -291,31 +283,135 @@ public class CoapMessage {
         return new String(payload, Charset.forName("UTF-8"));
     }
 
-    public String decodeDeviceId() {
-        Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
-        ArrayList<Object> decodedPayload = null;
+    public void setToken(byte[] token) {
+        mToken = token;
+    }
+
+    public byte[] getToken() {
+        return mToken;
+    }
+
+    public int getTokenLength() {
+        return mToken == null ? 0 : mToken.length;
+    }
+
+    public String getTokenString() {
+        StringBuffer strBuffer = new StringBuffer(mToken == null ? "null" : "");
+        if (mToken != null)
+            for (byte b : mToken)
+                strBuffer.append(String.format("%02x", b & 0xff)); // hexadecimal(16)
+        return strBuffer.toString();
+    }
+
+    public String getRequestId() {
+        return getTokenString();
+    }
+
+    public void setSequenceNumber(int seqNumber) {
+        mObserve = seqNumber;
+    }
+
+    public int getSequenceNumber() {
+        return mObserve;
+    }
+
+    public int getNextSequenceNumber() {
+        int ret = mObserve++;
 
-        if (payload == null) {
-            throw new IllegalArgumentException("payload is null");
+        if (mObserve == 1 || mObserve == 16777216) {
+            mObserve = 2;
         }
 
-        else {
-            decodedPayload = cbor.parsePayloadFromCbor(payload,
-                    ArrayList.class);
-            String deviceId = null;
-            if (decodedPayload != null) {
-                HashMap<Object, Object> tags = (HashMap<Object, Object>) decodedPayload
-                        .get(0);
+        return ret;
+    }
 
-                deviceId = tags.get("di").toString();
+    public void setObserve(Observe observe) {
+        switch (observe) {
+            case SUBSCRIBE:
+                mObserve = 0;
+                break;
 
-                if (deviceId == null) {
-                    throw new IllegalArgumentException("deviceId is null");
-                }
+            case UNSUBSCRIBE:
+                mObserve = 1;
+                break;
+
+            case NOTHING:
+                mObserve = -1;
+                break;
+
+            default:
+        }
+    }
+
+    @Override
+    public Observe getObserve() {
+        switch (mObserve) {
+            case -1:
+                return Observe.NOTHING;
+
+            case 0:
+                return Observe.SUBSCRIBE;
+
+            case 1:
+                return Observe.UNSUBSCRIBE;
+        }
+
+        return Observe.SEQUENCE_NUMBER;
+    }
+
+    public void setContentFormat(ContentFormat format) {
+        byte value = 0;
+        switch (format) {
+            case NO_CONTENT:
+                break;
+            case APPLICATION_LINK_FORMAT:
+                value = 40;
+                break;
+            case APPLICATION_XML:
+                value = 41;
+                break;
+            case APPLICATION_OCTET_STREAM:
+                value = 42;
+                break;
+            case APPLICATION_EXI:
+                value = 47;
+                break;
+            case APPLICATION_JSON:
+                value = 50;
+                break;
+            case APPLICATION_CBOR:
+                value = 60;
+                break;
+        }
+        content_format = new byte[] { value };
+    }
+
+    public ContentFormat getContentFormat() {
+
+        if (content_format == null) {
+            return ContentFormat.NO_CONTENT;
+        }
+
+        switch (content_format[0]) {
+            case 40:
+                return ContentFormat.APPLICATION_LINK_FORMAT;
 
-                Logger.i("deviceId : " + deviceId);
-            }
-            return deviceId;
+            case 41:
+                return ContentFormat.APPLICATION_XML;
+
+            case 42:
+                return ContentFormat.APPLICATION_OCTET_STREAM;
+
+            case 47:
+                return ContentFormat.APPLICATION_EXI;
+
+            case 50:
+                return ContentFormat.APPLICATION_JSON;
+
+            case 60:
+                return ContentFormat.APPLICATION_CBOR;
         }
+
+        return ContentFormat.NO_CONTENT;
     }
 }
@@ -1,4 +1,25 @@
-package org.iotivity.cloud.base.protocols.coap.enums;
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.coap;
 
 public enum CoapOption {
     IF_MATCH(1), URI_HOST(3), ETAG(4), IF_NONE_MATCH(5), URI_PORT(
index 4f80e4e..4f0ff7b 100644 (file)
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.base.protocols.coap;
 
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 
 public class CoapRequest extends CoapMessage {
-    public CoapRequest(CoapMethod method) {
-        this.code = method.getCode();
-    }
+    private RequestMethod mRequestMethod;
 
-    public CoapMethod getRequestMethod() {
-        return CoapMethod.valueOf(code);
+    public CoapRequest(RequestMethod requestMethod) {
+        mRequestMethod = requestMethod;
     }
 
-    public void setUriPath(String path) {
-        if (uri_path == null) {
-            uri_path = new ArrayList<byte[]>();
-        }
-        clearUriPath();
-
-        String[] pathSegments = path.split("/");
-        for (String pathSegment : pathSegments) {
-            if (pathSegment.length() == 0)
-                continue;
-            uri_path.add(pathSegment.getBytes(StandardCharsets.UTF_8));
+    public CoapRequest(int code) {
+        switch (code) {
+            case 1:
+                mRequestMethod = RequestMethod.GET;
+                break;
+            case 2:
+                mRequestMethod = RequestMethod.POST;
+                break;
+            case 3:
+                mRequestMethod = RequestMethod.PUT;
+                break;
+            case 4:
+                mRequestMethod = RequestMethod.DELETE;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid CoapRequest code");
         }
     }
 
-    public String getUriPath() {
-        if (uri_path == null) {
-            return null;
-        }
-        StringBuilder path = new StringBuilder();
-        int nItem = uri_path.size();
-        for (byte[] pathSegment : uri_path) {
-            path.append(new String(pathSegment, StandardCharsets.UTF_8));
-            if (--nItem > 0) {
-                path.append('/');
-            }
-        }
-        return path.toString();
-    }
+    @Override
+    public int getCode() {
+        switch (mRequestMethod) {
+            case GET:
+                return 1;
+            case POST:
+                return 2;
+            case PUT:
+                return 3;
+            case DELETE:
+                return 4;
+            default:
+                break;
 
-    public List<String> getUriPathSegments() {
-        if (uri_path == null) {
-            return null;
-        }
-        List<String> segments = new ArrayList<String>();
-        for (byte[] pathSegment : uri_path) {
-            segments.add(new String(pathSegment, StandardCharsets.UTF_8));
         }
-        return segments;
+        return 0;
     }
 
-    public void setUriQuery(String query) {
-        if (uri_query == null) {
-            uri_query = new ArrayList<byte[]>();
-        }
-        String[] querySegments = query.split("&");
-        for (String querySegment : querySegments) {
-            uri_query.add(querySegment.getBytes(StandardCharsets.UTF_8));
-        }
+    @Override
+    public RequestMethod getMethod() {
+        return mRequestMethod;
     }
 
-    public String getUriQuery() {
-        if (uri_query == null) {
-            return null;
-        }
-        StringBuilder uriQuery = new StringBuilder();
-        int nItem = uri_query.size();
-        for (byte[] querySegment : uri_query) {
-            uriQuery.append(new String(querySegment, StandardCharsets.UTF_8));
-            if (--nItem > 0) {
-                uriQuery.append('&');
-            }
-        }
-        return uriQuery.toString();
-    }
-
-    public List<String> getUriQuerySegments() {
-        if (uri_query == null) {
-            return null;
-        }
-        List<String> segments = new ArrayList<String>();
-        for (byte[] querySegment : uri_query) {
-            segments.add(new String(querySegment, StandardCharsets.UTF_8));
-        }
-        return segments;
-    }
-
-    public void clearUriPath() {
-        if (uri_path != null) {
-            uri_path.clear();
-        }
+    // This request object does not support response status
+    @Override
+    public ResponseStatus getStatus() {
+        return ResponseStatus.METHOD_NOT_ALLOWED;
     }
-}
+}
\ No newline at end of file
index 8d970d6..cfab952 100644 (file)
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.base.protocols.coap;
 
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
+import org.iotivity.cloud.base.protocols.enums.RequestMethod;
+import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 
 public class CoapResponse extends CoapMessage {
-    public CoapResponse(CoapStatus status) {
-        this.code = status.getCode();
+    private ResponseStatus mResponseStatus;
+
+    public CoapResponse(ResponseStatus responseStatus) {
+        mResponseStatus = responseStatus;
+    }
+
+    public CoapResponse(int code) {
+        switch (code) {
+            case 65:
+                mResponseStatus = ResponseStatus.CREATED;
+                break;
+            case 66:
+                mResponseStatus = ResponseStatus.DELETED;
+                break;
+            case 67:
+                mResponseStatus = ResponseStatus.VALID;
+                break;
+            case 68:
+                mResponseStatus = ResponseStatus.CHANGED;
+                break;
+            case 69:
+                mResponseStatus = ResponseStatus.CONTENT;
+                break;
+            case 128:
+                mResponseStatus = ResponseStatus.BAD_REQUEST;
+                break;
+            case 129:
+                mResponseStatus = ResponseStatus.UNAUTHORIZED;
+                break;
+            case 130:
+                mResponseStatus = ResponseStatus.BAD_OPTION;
+                break;
+            case 131:
+                mResponseStatus = ResponseStatus.FORBIDDEN;
+                break;
+            case 132:
+                mResponseStatus = ResponseStatus.NOT_FOUND;
+                break;
+            case 133:
+                mResponseStatus = ResponseStatus.METHOD_NOT_ALLOWED;
+                break;
+            case 134:
+                mResponseStatus = ResponseStatus.NOT_ACCEPTABLE;
+                break;
+            case 140:
+                mResponseStatus = ResponseStatus.PRECONDITION_FAILED;
+                break;
+            case 141:
+                mResponseStatus = ResponseStatus.REQUEST_ENTITY_TOO_LARGE;
+                break;
+            case 143:
+                mResponseStatus = ResponseStatus.UNSUPPORTED_CONTENT_FORMAT;
+                break;
+            case 160:
+                mResponseStatus = ResponseStatus.INTERNAL_SERVER_ERROR;
+                break;
+            case 161:
+                mResponseStatus = ResponseStatus.NOT_IMPLEMENTED;
+                break;
+            case 162:
+                mResponseStatus = ResponseStatus.BAD_GATEWAY;
+                break;
+            case 163:
+                mResponseStatus = ResponseStatus.SERVICE_UNAVAILABLE;
+                break;
+            case 164:
+                mResponseStatus = ResponseStatus.GATEWAY_TIMEOUT;
+                break;
+            case 165:
+                mResponseStatus = ResponseStatus.PROXY_NOT_SUPPORTED;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid CoapResponse code");
+        }
+    }
+
+    @Override
+    public int getCode() {
+        // TODO Auto-generated method stub
+        switch (mResponseStatus) {
+            case BAD_GATEWAY:
+                return 162;
+            case BAD_OPTION:
+                return 130;
+            case BAD_REQUEST:
+                return 128;
+            case CHANGED:
+                return 68;
+            case CONTENT:
+                return 69;
+            case CREATED:
+                return 65;
+            case DELETED:
+                return 66;
+            case FORBIDDEN:
+                return 131;
+            case GATEWAY_TIMEOUT:
+                return 164;
+            case INTERNAL_SERVER_ERROR:
+                return 160;
+            case METHOD_NOT_ALLOWED:
+                return 133;
+            case NOT_ACCEPTABLE:
+                return 134;
+            case NOT_FOUND:
+                return 132;
+            case NOT_IMPLEMENTED:
+                return 161;
+            case PRECONDITION_FAILED:
+                return 140;
+            case PROXY_NOT_SUPPORTED:
+                return 165;
+            case REQUEST_ENTITY_TOO_LARGE:
+                return 141;
+            case SERVICE_UNAVAILABLE:
+                return 163;
+            case UNAUTHORIZED:
+                return 129;
+            case UNSUPPORTED_CONTENT_FORMAT:
+                return 143;
+            case VALID:
+                return 67;
+            default:
+                break;
+        }
+        return 0;
+    }
+
+    // This response object does not support request method
+    @Override
+    public RequestMethod getMethod() {
+        return RequestMethod.GET;
     }
 
-    public CoapStatus getResponseCode() {
-        return CoapStatus.valueOf(code);
+    @Override
+    public ResponseStatus getStatus() {
+        return mResponseStatus;
     }
 }
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapMethod.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapMethod.java
deleted file mode 100644 (file)
index 90b99da..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.iotivity.cloud.base.protocols.coap.enums;
-
-public enum CoapMethod {
-    GET(1), POST(2), PUT(3), DELETE(4);
-
-    public static CoapMethod valueOf(int code) {
-        switch (code) {
-            case 1:
-                return CoapMethod.GET;
-
-            case 2:
-                return CoapMethod.POST;
-
-            case 3:
-                return CoapMethod.PUT;
-
-            case 4:
-                return CoapMethod.DELETE;
-        }
-
-        throw new IllegalArgumentException("Invalid Method value");
-    }
-
-    private final int code;
-
-    private CoapMethod(int code) {
-        this.code = code;
-    }
-
-    public int getCode() {
-        return code;
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapStatus.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/enums/CoapStatus.java
deleted file mode 100644 (file)
index a687ad3..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.iotivity.cloud.base.protocols.coap.enums;
-
-public enum CoapStatus {
-    // Success 2.xx
-    CREATED(65), DELETED(66), VALID(67), CHANGED(68), CONTENT(69),
-    // Client Error 4.xx
-    BAD_REQUEST(128), UNAUTHORIZED(129), BAD_OPTION(130), FORBIDDEN(131),
-    //
-    NOT_FOUND(132), METHOD_NOT_ALLOWED(133), NOT_ACCEPTABLE(134),
-    //
-    PRECONDITION_FAILED(140), REQUEST_ENTITY_TOO_LARGE(141),
-    //
-    UNSUPPORTED_CONTENT_FORMAT(143),
-    // Server Error 5.xx
-    INTERNAL_SERVER_ERROR(160), NOT_IMPLEMENTED(161), BAD_GATEWAY(162),
-    //
-    SERVICE_UNAVAILABLE(163), GATEWAY_TIMEOUT(164), PROXY_NOT_SUPPORTED(165);
-
-    public static CoapStatus valueOf(int code) {
-        switch (code) {
-            case 65:
-                return CoapStatus.CREATED;
-
-            case 66:
-                return CoapStatus.DELETED;
-
-            case 67:
-                return CoapStatus.VALID;
-
-            case 68:
-                return CoapStatus.CHANGED;
-
-            case 69:
-                return CoapStatus.CONTENT;
-
-            case 128:
-                return CoapStatus.BAD_REQUEST;
-
-            case 129:
-                return CoapStatus.UNAUTHORIZED;
-
-            case 130:
-                return CoapStatus.BAD_OPTION;
-
-            case 131:
-                return CoapStatus.FORBIDDEN;
-
-            case 132:
-                return CoapStatus.NOT_FOUND;
-
-            case 133:
-                return CoapStatus.METHOD_NOT_ALLOWED;
-
-            case 134:
-                return CoapStatus.NOT_ACCEPTABLE;
-
-            case 140:
-                return CoapStatus.PRECONDITION_FAILED;
-
-            case 141:
-                return CoapStatus.REQUEST_ENTITY_TOO_LARGE;
-
-            case 143:
-                return CoapStatus.UNSUPPORTED_CONTENT_FORMAT;
-
-            case 160:
-                return CoapStatus.INTERNAL_SERVER_ERROR;
-
-            case 161:
-                return CoapStatus.NOT_IMPLEMENTED;
-
-            case 162:
-                return CoapStatus.BAD_GATEWAY;
-
-            case 163:
-                return CoapStatus.SERVICE_UNAVAILABLE;
-
-            case 164:
-                return CoapStatus.GATEWAY_TIMEOUT;
-
-            case 165:
-                return CoapStatus.PROXY_NOT_SUPPORTED;
-        }
-
-        throw new IllegalArgumentException("Invalid Status value");
-    }
-
-    private final int code;
-
-    private CoapStatus(int code) {
-        this.code = code;
-    }
-
-    public int getCode() {
-        return code;
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ContentFormat.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ContentFormat.java
new file mode 100644 (file)
index 0000000..d691947
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.enums;
+
+public enum ContentFormat {
+    NO_CONTENT, APPLICATION_LINK_FORMAT, APPLICATION_XML, APPLICATION_OCTET_STREAM, APPLICATION_EXI, APPLICATION_JSON, APPLICATION_CBOR
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/Observe.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/Observe.java
new file mode 100644 (file)
index 0000000..9c98f7c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.enums;
+
+public enum Observe {
+    NOTHING, SUBSCRIBE, UNSUBSCRIBE, SEQUENCE_NUMBER
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/RequestMethod.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/RequestMethod.java
new file mode 100644 (file)
index 0000000..2f3652d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.enums;
+
+public enum RequestMethod {
+    GET, POST, PUT, DELETE
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ResponseStatus.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/enums/ResponseStatus.java
new file mode 100644 (file)
index 0000000..602c005
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.enums;
+
+public enum ResponseStatus {
+    // Success 2.xx
+    CREATED, DELETED, VALID, CHANGED, CONTENT,
+    // Client Error 4.xx
+    BAD_REQUEST, UNAUTHORIZED, BAD_OPTION, FORBIDDEN,
+    //
+    NOT_FOUND, METHOD_NOT_ALLOWED, NOT_ACCEPTABLE,
+    //
+    PRECONDITION_FAILED, REQUEST_ENTITY_TOO_LARGE,
+    //
+    UNSUPPORTED_CONTENT_FORMAT,
+    // Server Error 5.xx
+    INTERNAL_SERVER_ERROR, NOT_IMPLEMENTED, BAD_GATEWAY,
+    //
+    SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, PROXY_NOT_SUPPORTED;
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/http/HttpMessage.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/http/HttpMessage.java
new file mode 100644 (file)
index 0000000..74e69ba
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.protocols.http;
+
+public class HttpMessage {
+
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java
deleted file mode 100644 (file)
index bdc1282..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-// package org.iotivity.cloud.base.protocols.proxy;
-//
-// import java.nio.charset.StandardCharsets;
-// import java.util.HashMap;
-// import java.util.List;
-// import java.util.Map.Entry;
-//
-// import org.iotivity.cloud.base.SessionManager;
-// import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-// import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-// import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-// import org.iotivity.cloud.util.Cbor;
-// import org.iotivity.cloud.util.Logger;
-//
-// import io.netty.buffer.Unpooled;
-// import io.netty.channel.ChannelDuplexHandler;
-// import io.netty.channel.ChannelFutureListener;
-// import io.netty.channel.ChannelHandler.Sharable;
-// import io.netty.channel.ChannelHandlerContext;
-// import io.netty.handler.codec.http.DefaultFullHttpResponse;
-// import io.netty.handler.codec.http.HttpHeaders;
-// import io.netty.handler.codec.http.HttpMethod;
-// import io.netty.handler.codec.http.HttpRequest;
-// import io.netty.handler.codec.http.HttpResponse;
-// import io.netty.handler.codec.http.HttpResponseStatus;
-// import io.netty.handler.codec.http.HttpVersion;
-// import io.netty.handler.codec.http.QueryStringDecoder;
-// import io.netty.util.AttributeKey;
-// import io.netty.util.CharsetUtil;
-//
-// @Sharable
-// public class CoapHttpProxyHandler extends ChannelDuplexHandler {
-//
-// // Proxy converts http request to coaprequest and coapresponse to
-// // httpresponse
-// private SessionManager sessionManager = null;
-//
-// private static final AttributeKey<ChannelHandlerContext> keyHttpCtx =
-// AttributeKey
-// .newInstance("httpCtx");
-//
-// public CoapHttpProxyHandler(SessionManager sessionManager) {
-// this.sessionManager = sessionManager;
-// }
-//
-// @Override
-// public void channelRead(ChannelHandlerContext ctx, Object msg)
-// throws Exception {
-//
-// // in case of Receive Request from http
-// if (msg instanceof HttpRequest) {
-// // Check uri query param that contains coap device uuid
-// // then search those and create coapRequest and send
-// HttpRequest httpRequest = (HttpRequest) msg;
-// QueryStringDecoder queryStringDecoder = new QueryStringDecoder(
-// httpRequest.getUri());
-//
-// List<String> didList = queryStringDecoder.parameters().get("di");
-//
-// if (didList != null) {
-// ChannelHandlerContext coapClient = sessionManager
-// .querySession(didList.get(0));
-//
-// if (coapClient != null) {
-// List<String> uriList = queryStringDecoder.parameters()
-// .get("href");
-// if (uriList != null) {
-// coapClient.channel().attr(keyHttpCtx).set(ctx);
-// coapClient.writeAndFlush(httpRequestToCoAPRequest(
-// uriList.get(0), (HttpRequest) msg));
-//
-// return;
-// }
-// } else {
-// Logger.d("Unable to find session: " + didList.get(0));
-// }
-// }
-//
-// // Prints available sessions to html
-//
-// ctx.writeAndFlush(printsAvailableSessions())
-// .addListener(ChannelFutureListener.CLOSE);
-// return;
-// }
-//
-// if (msg instanceof CoapResponse) {
-// ctx.channel().attr(keyHttpCtx).get()
-// .writeAndFlush(
-// coapResponseToHttpResponse((CoapResponse) msg))
-// .addListener(ChannelFutureListener.CLOSE);
-// return;
-// }
-//
-// // Pass to upper-layer
-// super.channelRead(ctx, msg);
-// }
-//
-// @Override
-// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
-// cause.printStackTrace();
-// ctx.close();
-// }
-//
-// HttpResponse printsAvailableSessions() {
-//
-// StringBuilder strBuilder = new StringBuilder();
-// List<String> sessions = sessionManager.getSessions();
-//
-// strBuilder.append("<html>");
-// strBuilder.append("<b>Available sessions</b><br>");
-//
-// for (String session : sessions) {
-// strBuilder.append(session);
-// strBuilder.append("<br>");
-// }
-//
-// strBuilder.append("</html>");
-//
-// HttpResponse response = new DefaultFullHttpResponse(
-// HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
-// Unpooled.copiedBuffer(strBuilder.toString(),
-// CharsetUtil.UTF_8));
-// response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
-// "text/html; charset=UTF-8");
-//
-// return response;
-// }
-//
-// HttpResponse httpRequestToSendError() {
-// HttpResponse response = new DefaultFullHttpResponse(
-// HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND,
-// Unpooled.copiedBuffer(
-// "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n",
-// CharsetUtil.UTF_8));
-// response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
-// "text/html; charset=UTF-8");
-//
-// return response;
-// }
-//
-// CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) {
-// CoapRequest coapRequest;
-//
-// // TODO: coapRequest converter required
-// // coapRequest.getOptions().setUriQuery();
-// if (httpRequest.getMethod() == HttpMethod.GET) {
-// coapRequest = new CoapRequest(CoapMethod.GET);
-// } else if (httpRequest.getMethod() == HttpMethod.PUT) {
-// coapRequest = new CoapRequest(CoapMethod.PUT);
-// } else if (httpRequest.getMethod() == HttpMethod.POST) {
-// coapRequest = new CoapRequest(CoapMethod.POST);
-// } else if (httpRequest.getMethod() == HttpMethod.DELETE) {
-// coapRequest = new CoapRequest(CoapMethod.DELETE);
-// } else {
-// throw new IllegalArgumentException();
-// }
-//
-// coapRequest.setUriPath(uri);
-//
-// return coapRequest;
-// }
-//
-// HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) {
-//
-// Cbor<HashMap<String, Object>> cbor = new Cbor<HashMap<String, Object>>();
-//
-// HashMap<String, Object> rep = cbor
-// .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class);
-//
-// StringBuilder strBuilder = new StringBuilder();
-//
-// for (Entry<String, Object> entry : rep.entrySet()) {
-// String key = entry.getKey();
-// String value = entry.getValue().toString();
-// strBuilder.append("Key: " + key + " Value: " + value + "<br>");
-// }
-//
-// HttpResponse httpResponse = new DefaultFullHttpResponse(
-// HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
-// Unpooled.wrappedBuffer(strBuilder.toString()
-// .getBytes(StandardCharsets.UTF_8)));
-//
-// httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE,
-// "text/html; charset=UTF-8");
-//
-// // TODO: httpResponse converter required
-//
-// return httpResponse;
-// }
-// }
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/Resource.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/Resource.java
new file mode 100644 (file)
index 0000000..5feea5f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.resource;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestEventHandler;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.NotFoundException;
+import org.iotivity.cloud.base.protocols.IRequest;
+
+public class Resource implements IRequestEventHandler {
+
+    private List<String> mPathSegments;
+
+    public interface Functional {
+        void queryHandler(Device srcDevice, IRequest request)
+                throws ServerException;
+    }
+
+    private HashMap<List<String>, Functional> mQuerySetList = new HashMap<>();
+
+    public void addQueryHandler(List<String> querySet,
+            Functional queryHandler) {
+        mQuerySetList.put(querySet, queryHandler);
+    }
+
+    public List<String> getUriPathSegments() {
+        return mPathSegments;
+    }
+
+    public Resource(List<String> pathSegments) {
+        mPathSegments = pathSegments;
+    }
+
+    @Override
+    final public void onRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // Handle pre-registered handlers
+        List<String> reqQuerySet = request.getUriQuerySegments();
+
+        if (reqQuerySet != null && mQuerySetList.size() > 0) {
+            for (Entry<List<String>, Functional> entry : mQuerySetList
+                    .entrySet()) {
+                if (reqQuerySet.retainAll(entry.getKey()) == false) {
+                    entry.getValue().queryHandler(srcDevice, request);
+                    return;
+                }
+            }
+        }
+
+        // No packet handler found, pass to default handler
+        onDefaultRequestReceived(srcDevice, request);
+    }
+
+    public void onDefaultRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // No default handlers registered, send error
+        throw new NotFoundException("No handlers registered");
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/ResourceManager.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/ResourceManager.java
new file mode 100644 (file)
index 0000000..a67d1d5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.resource;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.device.IRequestEventHandler;
+import org.iotivity.cloud.base.exception.ServerException;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+import org.iotivity.cloud.base.protocols.IRequest;
+
+public class ResourceManager implements IRequestEventHandler {
+
+    private URIPathNode mPathList = new URIPathNode();
+
+    public void addResource(Resource resource) {
+        mPathList.addHandler(resource.getUriPathSegments(), resource);
+    }
+
+    @Override
+    public void onRequestReceived(Device srcDevice, IRequest request)
+            throws ServerException {
+        // get path and forward to relevant handler
+        IRequestEventHandler requestHandler = null;
+
+        requestHandler = mPathList
+                .findPathHandler(request.getUriPathSegments());
+
+        if (requestHandler == null)
+            throw new InternalServerErrorException("Unsupport URI");
+
+        // Allocate new token and forward to other handler.
+        // Only some handlers required to have new token.
+        requestHandler.onRequestReceived(srcDevice, request);
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/URIPathNode.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/resource/URIPathNode.java
new file mode 100644 (file)
index 0000000..ac31557
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.resource;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.IRequestEventHandler;
+
+public class URIPathNode {
+
+    private HashMap<String, URIPathNode> mChildren       = new HashMap<>();
+    private IRequestEventHandler         mRequestHandler = null;
+
+    public URIPathNode addHandler(List<String> pathSegments,
+            IRequestEventHandler requestHandler) {
+        URIPathNode edgeNode = this;
+        for (String pathSegment : pathSegments) {
+            URIPathNode node = edgeNode.mChildren.get(pathSegment);
+            if (node == null) {
+                node = new URIPathNode();
+                edgeNode.mChildren.put(pathSegment, node);
+            }
+            edgeNode = node;
+        }
+        edgeNode.mRequestHandler = requestHandler;
+        return edgeNode;
+    }
+
+    // if searched return last node or last found middle node
+    public IRequestEventHandler findPathHandler(List<String> pathSegments) {
+        URIPathNode edgeNode = this;
+        URIPathNode childNode = null;
+        for (String pathSegment : pathSegments) {
+            childNode = edgeNode.mChildren.get(pathSegment);
+
+            if (childNode == null)
+                return edgeNode.mRequestHandler;
+
+            edgeNode = childNode;
+        }
+
+        return edgeNode.mRequestHandler;
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/server/CoapServer.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/server/CoapServer.java
new file mode 100644 (file)
index 0000000..2ff5832
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.server;
+
+import java.net.InetSocketAddress;
+
+import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
+import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
+import org.iotivity.cloud.base.protocols.coap.CoapLogHandler;
+
+import io.netty.channel.ChannelHandler;
+
+public class CoapServer extends Server {
+
+    public CoapServer(InetSocketAddress inetSocketAddress) {
+        super(inetSocketAddress);
+    }
+
+    @Override
+    protected ChannelHandler[] onQueryDefaultHandler() {
+        return new ChannelHandler[] { new CoapDecoder(), new CoapEncoder(),
+                new CoapLogHandler() };
+    }
+}
\ No newline at end of file
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/server/HttpServer.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/server/HttpServer.java
new file mode 100644 (file)
index 0000000..88a0d81
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.server;
+
+import java.net.InetSocketAddress;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
+
+public class HttpServer extends Server {
+
+    public HttpServer(InetSocketAddress inetSocketAddress) {
+        super(inetSocketAddress);
+    }
+
+    @Override
+    protected ChannelHandler[] onQueryDefaultHandler() {
+        return new ChannelHandler[] { new HttpRequestDecoder(),
+                new HttpResponseEncoder() };
+    }
+}
\ No newline at end of file
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/server/Server.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/server/Server.java
new file mode 100644 (file)
index 0000000..4f4ea70
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.base.server;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.SSLException;
+
+import org.iotivity.cloud.base.OCFConstants;
+import org.iotivity.cloud.util.Logger;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+
+public abstract class Server {
+
+    EventLoopGroup    acceptorGroup      = new NioEventLoopGroup(1);
+
+    EventLoopGroup    workerGroup        = new NioEventLoopGroup();
+
+    ServerInitializer mServerInitializer = new ServerInitializer();
+
+    InetSocketAddress mInetSocketAddress = null;
+
+    SslContext        mSslContext        = null;
+
+    private class ServerInitializer extends ChannelInitializer<SocketChannel> {
+        private List<ChannelHandler> additionalHandlers = new ArrayList<>();
+
+        public ServerInitializer() {
+        }
+
+        public void addHandler(ChannelHandler handler) {
+            additionalHandlers.add(handler);
+        }
+
+        @Override
+        public void initChannel(SocketChannel ch) {
+            ChannelPipeline p = ch.pipeline();
+
+            if (mSslContext != null) {
+                p.addLast(mSslContext.newHandler(ch.alloc()));
+            }
+
+            p.addLast(onQueryDefaultHandler());
+
+            for (ChannelHandler handler : additionalHandlers) {
+                p.addLast(handler);
+            }
+        }
+    }
+
+    public Server(InetSocketAddress inetSocketAddress) {
+        mInetSocketAddress = inetSocketAddress;
+    }
+
+    public void startServer(boolean tlsMode)
+            throws CertificateException, SSLException, InterruptedException {
+
+        try {
+            Logger.i("[CoapServer]startServer with tlsMode! mode= " + tlsMode);
+
+            if (tlsMode == true) {
+
+                File serverCert = new File(OCFConstants.CLOUD_CERT_FILE);
+
+                File serverKey = new File(OCFConstants.CLOUD_KEY_FILE);
+
+                mSslContext = SslContextBuilder.forServer(serverCert, serverKey)
+                        .build();
+            }
+
+            ServerBootstrap b = new ServerBootstrap();
+            b.group(acceptorGroup, workerGroup);
+            b.channel(NioServerSocketChannel.class);
+            b.handler(new LoggingHandler(LogLevel.INFO));
+
+            b.childHandler(mServerInitializer);
+
+            b.bind(mInetSocketAddress).sync();
+        } finally {
+        }
+    }
+
+    public void stopServer() throws Exception {
+        acceptorGroup.shutdownGracefully().await();
+        workerGroup.shutdownGracefully().await();
+    }
+
+    public void addHandler(ChannelHandler handler) {
+        mServerInitializer.addHandler(handler);
+    }
+
+    abstract protected ChannelHandler[] onQueryDefaultHandler();
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/util/Bytes.java b/cloud/stack/src/main/java/org/iotivity/cloud/util/Bytes.java
new file mode 100644 (file)
index 0000000..4dd9b23
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.util;
+
+import java.nio.ByteBuffer;
+
+public class Bytes {
+    public static byte[] longTo8Bytes(long l) {
+        ByteBuffer buffer = ByteBuffer.allocate(8);
+        buffer.putLong(l);
+        return buffer.array();
+    }
+
+    public static long bytesToLong(byte[] bytes) {
+        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
+        if (bytes.length < Long.BYTES) {
+            buffer.put(new byte[Long.BYTES - bytes.length]);
+        }
+        buffer.put(bytes);
+        buffer.flip();
+        return buffer.getLong();
+    }
+
+    public static int bytesToInt(byte[] bytes) {
+        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
+        if (bytes.length < Integer.BYTES) {
+            buffer.put(new byte[Integer.BYTES - bytes.length]);
+        }
+        buffer.put(bytes);
+        buffer.flip();
+        return buffer.getInt();
+    }
+
+    public static byte[] intToMax4Bytes(int i) {
+        ByteBuffer buffer = ByteBuffer.allocate(4);
+        buffer.putInt(i);
+        buffer.flip();
+        if (buffer.get(0) != 0) {
+            return buffer.array();
+        }
+
+        if (buffer.get(1) != 0) {
+            byte b[] = new byte[3];
+            buffer.get();
+            buffer.get(b);
+            return b;
+        }
+
+        if (buffer.get(2) != 0) {
+            byte b[] = new byte[2];
+            buffer.get();
+            buffer.get();
+            buffer.get(b);
+            return b;
+        }
+
+        return new byte[] { buffer.get(3) };
+    }
+}
\ No newline at end of file
index 9fdfc74..94c8e8b 100644 (file)
@@ -1,31 +1,34 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.util;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
 
 public class Cbor<T> {
     private CBORFactory  f;
@@ -60,4 +63,31 @@ public class Cbor<T> {
         }
         return cborData;
     }
-}
+
+    public String decodeDeviceId(byte[] payload) {
+        Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
+        ArrayList<Object> decodedPayload = null;
+
+        if (payload == null) {
+            throw new PreconditionFailedException("payload is null");
+        }
+
+        else {
+            decodedPayload = cbor.parsePayloadFromCbor(payload,
+                    ArrayList.class);
+
+            HashMap<Object, Object> tags = (HashMap<Object, Object>) decodedPayload
+                    .get(0);
+
+            String deviceId = tags.get("di").toString();
+
+            if (deviceId == null) {
+                throw new PreconditionFailedException("deviceId is null");
+            }
+
+            Logger.i("deviceId : " + deviceId);
+
+            return deviceId;
+        }
+    }
+}
\ No newline at end of file
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java
deleted file mode 100644 (file)
index 56633a0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.util;
-
-import java.nio.charset.StandardCharsets;
-
-import org.iotivity.cloud.base.protocols.coap.CoapMessage;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-
-/**
- *
- * This class provides a set of APIs to print out logs for CoAP request and
- * response.
- *
- */
-@Sharable
-public class CoapLogHandler extends ChannelDuplexHandler {
-
-    @Override
-    public void write(ChannelHandlerContext ctx, Object msg,
-            ChannelPromise promise) {
-
-        if (msg instanceof CoapMessage) {
-
-            CoapMessage coapMessage = (CoapMessage) msg;
-
-            StringBuilder strBuilder = new StringBuilder();
-            strBuilder.append(getStringCtx(ctx));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            strBuilder.append(getStringCoapMessage(coapMessage));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            Logger.d(strBuilder.toString());
-
-        } else if (msg instanceof String) {
-
-            String message = (String) msg;
-
-            StringBuilder strBuilder = new StringBuilder();
-            strBuilder.append(getStringCtx(ctx));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            strBuilder.append(message);
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            Logger.d(strBuilder.toString());
-
-            ByteBuf outByteBuf = ctx.alloc().buffer();
-            outByteBuf.writeBytes(message.getBytes(StandardCharsets.UTF_8));
-        }
-
-        ctx.write(msg);
-    }
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg)
-            throws Exception {
-
-        if (msg instanceof CoapMessage) {
-
-            CoapMessage coapMessage = (CoapMessage) msg;
-
-            StringBuilder strBuilder = new StringBuilder();
-            strBuilder.append(getStringCtx(ctx));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            strBuilder.append(getStringCoapMessage(coapMessage));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            Logger.d(strBuilder.toString());
-
-        } else if (msg instanceof ByteBuf) {
-
-            ByteBuf inByteBuf = (ByteBuf) msg;
-
-            String message = null;
-            StringBuffer strBuffer = new StringBuffer();
-            while (inByteBuf.isReadable()) {
-                strBuffer.append((char) inByteBuf.readByte());
-            }
-            message = strBuffer.toString();
-
-            StringBuilder strBuilder = new StringBuilder();
-            strBuilder.append(getStringCtx(ctx));
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            strBuilder.append(message);
-            strBuilder.append(
-                    "\n/******************************************************************************/\n");
-            Logger.d(strBuilder.toString());
-        }
-
-        ctx.fireChannelRead(msg);
-    }
-
-    private String getStringCtx(ChannelHandlerContext ctx) {
-
-        StringBuilder strBuilder = new StringBuilder();
-
-        strBuilder.append("\n");
-        strBuilder.append("Local Address: ");
-        strBuilder.append(ctx.channel().localAddress().toString());
-
-        strBuilder.append("\n");
-        strBuilder.append("Remote Address: ");
-        strBuilder.append(ctx.channel().remoteAddress().toString());
-
-        return strBuilder.toString();
-    }
-
-    private String getStringCoapMessage(CoapMessage coapMessage) {
-
-        StringBuilder strBuilder = new StringBuilder();
-
-        strBuilder.append("Code: ");
-        strBuilder.append(coapMessage.getCode());
-        strBuilder.append("\n");
-
-        strBuilder.append("Token Length: ");
-        strBuilder.append(coapMessage.getTokenLength());
-        strBuilder.append("\n");
-
-        strBuilder.append("Token Data: ");
-        strBuilder.append(coapMessage.getTokenString());
-        strBuilder.append("\n");
-
-        if (coapMessage instanceof CoapRequest) {
-
-            CoapRequest coapRequest = (CoapRequest) coapMessage;
-
-            strBuilder.append("Option URI_PATH: ");
-            strBuilder.append(coapRequest.getUriPath());
-            strBuilder.append("\n");
-
-            strBuilder.append("Option URI_QUERY: ");
-            strBuilder.append(coapRequest.getUriQuery());
-            strBuilder.append("\n");
-        }
-
-        strBuilder.append("Option CONTENT_FORMAT: ");
-        strBuilder.append(coapMessage.getContentFormatString());
-        strBuilder.append("\n");
-
-        strBuilder.append("Payload Length: ");
-        strBuilder.append(coapMessage.getPayloadSize());
-
-        strBuilder.append("\n");
-        strBuilder.append("Payload Data: ");
-        strBuilder.append(coapMessage.getPayloadString());
-
-        return strBuilder.toString();
-    }
-}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/util/ErrorLogger.java b/cloud/stack/src/main/java/org/iotivity/cloud/util/ErrorLogger.java
new file mode 100644 (file)
index 0000000..af173e4
--- /dev/null
@@ -0,0 +1,41 @@
+package org.iotivity.cloud.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import io.netty.channel.Channel;
+
+public class ErrorLogger extends Logger {
+
+    private static FileOutputStream fos = null;
+    private static PrintStream      ps  = null;
+
+    static public void Init() throws FileNotFoundException {
+        File dir = new File("..//errLog//");
+        if (!dir.isDirectory()) {
+            System.out.println("Is Not Folder");
+            dir.mkdirs();
+        }
+        fos = new FileOutputStream("../errLog/[" + getDate() + "] error.log",
+                true);
+        ps = new PrintStream(fos);
+    }
+
+    static public void write(Channel channel, Throwable t) {
+        String log = channel.id().asLongText().substring(26) + " "
+                + t.getMessage();
+        ps.println(getTime() + " " + log);
+        t.printStackTrace(ps);
+        Logger.v(log);
+    }
+
+    protected static String getDate() {
+        Calendar calendar = Calendar.getInstance();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        return dateFormat.format(calendar.getTime());
+    }
+}
diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/util/FileLogger.java b/cloud/stack/src/main/java/org/iotivity/cloud/util/FileLogger.java
new file mode 100644 (file)
index 0000000..2c9a9d4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.util;
+
+import java.io.PrintStream;
+
+import org.apache.log4j.Logger;
+
+public class FileLogger {
+    private final static Logger logger = Logger.getLogger(FileLogger.class);
+
+    public static PrintStream createLoggingProxy(
+            final PrintStream realPrintStream) {
+        // TODO Auto-generated method stub
+        return new PrintStream(realPrintStream) {
+            public void print(final String string) {
+                realPrintStream.print(string);
+                logger.fatal(string);
+            }
+        };
+    }
+
+}
index 2e99157..a1aace5 100644 (file)
@@ -1,34 +1,30 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.util;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 /**
@@ -37,79 +33,59 @@ import com.fasterxml.jackson.databind.ObjectMapper;
  * JSON string.
  * 
  */
-public class JSONUtil {
+public class JSONUtil<T> {
 
     private static ObjectMapper mapper = new ObjectMapper();
 
-    public static String parseJSON(String jsonString, String key) {
+    @SuppressWarnings("unchecked")
+    public T parseJSON(byte[] data, Class<? extends Object> class1) {
 
-        if (jsonString == null || jsonString.equals(""))
+        if (data == null)
             return null;
 
-        String value = null;
+        T parsedData = null;
 
         try {
-            @SuppressWarnings("unchecked")
-            Map<String, String> jsonMap = mapper.readValue(jsonString,
-                    Map.class);
-            value = jsonMap.get(key);
+            parsedData = (T) mapper.readValue(data, class1);
+
         } catch (IOException ioe) {
             ioe.printStackTrace();
         }
 
-        return value;
+        return parsedData;
     }
-    
-    public static ArrayList<String> parseJSON(byte[] payload, String key) {
 
-        if (payload == null)
+    public T parseJSON(String data, Class<? extends Object> class1) {
+
+        if (data == null || data.equals(""))
             return null;
 
-        ArrayList<String> value = null;
+        T parsedData = null;
 
         try {
-            @SuppressWarnings("unchecked")
-            Map<String, ArrayList<String>> jsonMap = mapper.readValue(payload,
-                    Map.class);
-            value = jsonMap.get(key);
-        } catch (IOException ioe) {
-            ioe.printStackTrace();
-        }
+            parsedData = (T) mapper.readValue(data, class1);
 
-        return value;
-    }
-
-    public static Map<String, String> parseJSON(String jsonString)
-            throws JsonParseException, JsonMappingException, IOException {
-
-        Map<String, String> map = null;
-
-        try {
-            @SuppressWarnings("unchecked")
-            Map<String, String> jsonMap = mapper.readValue(jsonString,
-                    Map.class);
-            map = jsonMap;
         } catch (IOException ioe) {
             ioe.printStackTrace();
         }
 
-        return map;
+        return parsedData;
     }
 
-    public static String writeJSON(HashMap<Object, Object> data) {
+    public T writeJSON(HashMap<Object, Object> data) {
         if (data == null)
             return null;
 
-        String json = null;
+        T json = null;
         try {
-            json = mapper.writeValueAsString(data);
+            json = (T) mapper.writeValueAsString(data);
         } catch (JsonProcessingException e) {
             e.printStackTrace();
         }
 
         if (json == null)
-            json = "{}";
+            json = (T) "{}";
 
         return json;
     }
-}
+}
\ No newline at end of file
index f34816b..35e8565 100644 (file)
@@ -1,23 +1,23 @@
 /*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  */
 package org.iotivity.cloud.util;
 
@@ -26,13 +26,13 @@ import java.util.Calendar;
 
 public class Logger {
 
-    public static final int VERBOSE = 0;
-    public static final int DEBUG   = 1;
-    public static final int INFO    = 2;
-    public static final int WARNING = 3;
-    public static final int ERROR   = 4;
+    public static final int VERBOSE  = 0;
+    public static final int DEBUG    = 1;
+    public static final int INFO     = 2;
+    public static final int WARNING  = 3;
+    public static final int ERROR    = 4;
 
-    private static int logLevel = DEBUG;
+    private static int      logLevel = VERBOSE;
 
     public static void setLogLevel(int level) {
         logLevel = level;
@@ -110,9 +110,10 @@ public class Logger {
         return res;
     }
 
-    private static String getTime() {
+    protected static String getTime() {
         Calendar calendar = Calendar.getInstance();
-        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSS");
+        SimpleDateFormat dateFormat = new SimpleDateFormat(
+                "yyyy-MM-dd HH:mm:ss:SSS");
 
         return dateFormat.format(calendar.getTime());
     }
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java
deleted file mode 100644 (file)
index 6aa7b6f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.util.CoapLogHandler;
-import org.junit.Test;
-
-public class CoapClientTest {
-    @Test
-    public void testAddHandler() throws Exception {
-        CoapServer coapServer = new CoapServer();
-        coapServer.startServer(new InetSocketAddress(5683));
-        CoapClient coapClient = new CoapClient();
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-        coapClient.addHandler(new CoapLogHandler());
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testAddHandlerSendRequest() throws Exception {
-        CoapServer coapServer = new CoapServer();
-        coapServer.startServer(new InetSocketAddress(5683));
-
-        CoapClient coapClient = new CoapClient();
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-        coapClient.addHandler(new CoapLogHandler());
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        coapClient.sendRequest(request);
-
-        CoapRequest request2 = new CoapRequest(CoapMethod.GET);
-        request2.setToken("1234".getBytes(StandardCharsets.UTF_8));
-        coapClient.sendRequest(request2);
-
-        CoapRequest request3 = new CoapRequest(CoapMethod.GET);
-        request3.setPayload("sample1".getBytes(StandardCharsets.UTF_8));
-        coapClient.sendRequest(request3);
-
-        CoapRequest request4 = new CoapRequest(CoapMethod.GET);
-        request4.setToken("5576".getBytes(StandardCharsets.UTF_8));
-        request4.setPayload("sample2".getBytes(StandardCharsets.UTF_8));
-        coapClient.sendRequest(request4);
-
-        CoapRequest request5 = new CoapRequest(CoapMethod.GET);
-        request5.setToken("565761".getBytes(StandardCharsets.UTF_8));
-        coapClient.sendRequest(request5);
-
-        CoapRequest request6 = new CoapRequest(CoapMethod.GET);
-        coapClient.sendRequest(request6);
-
-        CoapRequest request7 = new CoapRequest(CoapMethod.GET);
-        coapClient.sendRequest(request7);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testStartStopClient() throws Exception {
-        CoapServer coapServer = new CoapServer();
-        coapServer.startServer(new InetSocketAddress(5683));
-        CoapClient coapClient = new CoapClient();
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testSendRequest() throws Exception {
-        CoapServer coapServer = new CoapServer();
-        coapServer.startServer(new InetSocketAddress(5683));
-        CoapClient coapClient = new CoapClient();
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        coapClient.sendRequest(request);
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java
deleted file mode 100644 (file)
index 3e9876a..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-
-import org.iotivity.cloud.util.CoapLogHandler;
-import org.junit.Test;
-
-public class CoapServerTest {
-    @Test
-    public void testAddHandler() throws Exception {
-        CoapServer server = new CoapServer();
-        server.startServer(new InetSocketAddress(5683));
-        server.addHandler(new CoapLogHandler());
-        server.stopServer();
-    }
-
-    @Test
-    public void testStartStopServer() throws Exception {
-        CoapServer server = new CoapServer();
-        server.startServer(new InetSocketAddress(5683));
-        server.stopServer();
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java
deleted file mode 100644 (file)
index c5c6a8c..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-
-import org.iotivity.cloud.base.SessionManagerTest.CoapClientHandler;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.junit.Test;
-
-import io.netty.channel.ChannelHandlerContext;
-
-public class ResourceManagerTest {
-
-    private static class SampleResource extends Resource {
-
-        public SampleResource() {
-            setUri("sampleUri");
-        }
-
-        @Override
-        public void onRequestReceived(ChannelHandlerContext ctx,
-                CoapRequest request) {
-            // TODO Auto-generated method stub
-        }
-    }
-
-    @Test
-    public void testChannelRead0ChannelHandlerContextCoapRequest()
-            throws Exception {
-
-        ResourceManager resourceManager = new ResourceManager();
-
-        resourceManager.registerResource(new SampleResource());
-
-        CoapServer coapServer = new CoapServer();
-        CoapClient coapClient = new CoapClient();
-        CoapClientHandler coapClientHandler = new CoapClientHandler();
-        coapServer.startServer(new InetSocketAddress(5683));
-        coapClient.addHandler(coapClientHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath("sampleUri");
-
-        resourceManager.channelRead0(coapClientHandler.connectCtx, request);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testRegisterResource() {
-        ResourceManager resourceManager = new ResourceManager();
-
-        resourceManager.registerResource(new SampleResource());
-    }
-
-    @Test
-    public void testUnregisterResource() {
-        SampleResource sampleResource = new SampleResource();
-        ResourceManager resourceManager = new ResourceManager();
-
-        resourceManager.registerResource(sampleResource);
-        resourceManager.unregisterResource(sampleResource);
-    }
-}
\ No newline at end of file
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java
deleted file mode 100644 (file)
index 6e38855..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.iotivity.cloud.base;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.junit.Test;
-
-import io.netty.channel.ChannelHandlerContext;
-
-public class ResourceTest {
-
-    private static class SampleResource extends Resource {
-
-        public SampleResource() {
-            setUri("sampleUri");
-        }
-
-        @Override
-        public void onRequestReceived(ChannelHandlerContext ctx,
-                CoapRequest request) {
-            // TODO Auto-generated method stub
-        }
-    }
-
-    @Test
-    public void testGetSetUri() {
-        SampleResource sampleResource = new SampleResource();
-        assertEquals(sampleResource.getUri(), "sampleUri");
-        sampleResource.setUri("sampleUri2");
-        assertEquals(sampleResource.getUri(), "sampleUri2");
-    }
-
-    @Test
-    public void testGetSetType() {
-        SampleResource sampleResource = new SampleResource();
-        assertNull(sampleResource.getType());
-        sampleResource.setType("sampleType");
-        assertEquals(sampleResource.getType(), "sampleType");
-    }
-
-    @Test
-    public void testGetSetRif() {
-        SampleResource sampleResource = new SampleResource();
-        assertNull(sampleResource.getRif());
-        sampleResource.setRif("sampleRif");
-        assertEquals(sampleResource.getRif(), "sampleRif");
-    }
-
-    @Test
-    public void testOnRequestReceived() {
-
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java
deleted file mode 100644 (file)
index 30df055..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.iotivity.cloud.base;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.net.InetSocketAddress;
-
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.junit.Test;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-public class SessionManagerTest {
-
-    static class CoapClientHandler
-            extends SimpleChannelInboundHandler<CoapResponse> {
-
-        ChannelHandlerContext connectCtx = null;
-
-        @Override
-        public void channelActive(ChannelHandlerContext ctx) throws Exception {
-            connectCtx = ctx;
-        }
-
-        @Override
-        protected void channelRead0(ChannelHandlerContext arg0,
-                CoapResponse arg1) throws Exception {
-            // TODO Auto-generated method stub
-
-        }
-    }
-
-    @Test
-    public void testAddSession() throws Exception {
-        SessionManager sessionManager = new SessionManager();
-        CoapServer coapServer = new CoapServer();
-        CoapClient coapClient = new CoapClient();
-        CoapClientHandler coapClientHandler = new CoapClientHandler();
-        coapServer.startServer(new InetSocketAddress(5683));
-        coapClient.addHandler(coapClientHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testRemoveSession() throws Exception {
-        SessionManager sessionManager = new SessionManager();
-        CoapServer coapServer = new CoapServer();
-        CoapClient coapClient = new CoapClient();
-        CoapClientHandler coapClientHandler = new CoapClientHandler();
-        coapServer.startServer(new InetSocketAddress(5683));
-        coapClient.addHandler(coapClientHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
-        sessionManager.removeSession("sampleDid");
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testRemoveSessionByChannel() throws Exception {
-        SessionManager sessionManager = new SessionManager();
-        CoapServer coapServer = new CoapServer();
-        CoapClient coapClient = new CoapClient();
-        CoapClientHandler coapClientHandler = new CoapClientHandler();
-        coapServer.startServer(new InetSocketAddress(5683));
-        coapClient.addHandler(coapClientHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
-        sessionManager.removeSessionByChannel(coapClientHandler.connectCtx);
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-
-    @Test
-    public void testQuerySession() throws Exception {
-        SessionManager sessionManager = new SessionManager();
-        CoapServer coapServer = new CoapServer();
-        CoapClient coapClient = new CoapClient();
-        CoapClientHandler coapClientHandler = new CoapClientHandler();
-        coapServer.startServer(new InetSocketAddress(5683));
-        coapClient.addHandler(coapClientHandler);
-        coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
-        assertNotNull(sessionManager.querySession("sampleDid"));
-
-        coapClient.stopClient();
-        coapServer.stopServer();
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java
deleted file mode 100644 (file)
index 0dbe337..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.iotivity.cloud.base.protocols.coap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.List;
-
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.junit.Test;
-
-public class CoapRequestTest {
-
-    @Test
-    public void testCoapRequest() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNotNull(request);
-    }
-
-    @Test
-    public void testGetRequestMethod() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertEquals(request.getRequestMethod(), CoapMethod.GET);
-    }
-
-    @Test
-    public void testSetUriPath() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriPath("sample");
-    }
-
-    @Test
-    public void testGetUriPath() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNull(request.getUriPath());
-        request.setUriPath("sample");
-        assertEquals(request.getUriPath(), "sample");
-    }
-
-    @Test
-    public void testGetUriPathSegments() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNull(request.getUriPathSegments());
-        request.setUriPath("parent/child");
-        List<String> list = request.getUriPathSegments();
-        if (list != null) {
-            assertEquals(list.size(), 2);
-        }
-    }
-
-    @Test
-    public void testSetUriQuery() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        request.setUriQuery("sample=sample");
-    }
-
-    @Test
-    public void testGetUriQuery() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNull(request.getUriQuery());
-        request.setUriQuery("sample=sample");
-        assertEquals(request.getUriQuery(), "sample=sample");
-    }
-
-    @Test
-    public void testGetUriQuerySegments() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNull(request.getUriQuerySegments());
-        request.setUriQuery("sample=samplle&sample2=sample2");
-        List<String> list = request.getUriQuerySegments();
-        if (list != null) {
-            assertEquals(list.size(), 2);
-        }
-    }
-
-    @Test
-    public void testClearUriPath() {
-        CoapRequest request = new CoapRequest(CoapMethod.GET);
-        assertNull(request.getUriPathSegments());
-        request.setUriPath("sample");
-        List<String> list = request.getUriPathSegments();
-        if (list != null) {
-            assertEquals(list.size(), 1);
-        }
-        request.clearUriPath();
-        list = request.getUriPathSegments();
-        if (list != null) {
-            assertEquals(list.size(), 0);
-        }
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java
deleted file mode 100644 (file)
index 5aaf4d5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.iotivity.cloud.base.protocols.coap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
-import org.junit.Test;
-
-public class CoapResponseTest {
-    @Test
-    public void testCoapResponse() throws Exception {
-        CoapResponse response = new CoapResponse(CoapStatus.VALID);
-        assertNotNull(response);
-    }
-
-    @Test
-    public void testGetResponseCode() throws Exception {
-        CoapResponse response = new CoapResponse(CoapStatus.VALID);
-        assertEquals(response.getResponseCode(), CoapStatus.VALID);
-    }
-}
diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/util/UtilTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/util/UtilTest.java
deleted file mode 100644 (file)
index a2f44b1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.iotivity.cloud.util;
-
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-
-import org.iotivity.cloud.base.CoapClient;
-import org.iotivity.cloud.base.CoapServer;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.junit.Test;
-
-public class UtilTest {
-
-    @Test
-    public void testCbor() {
-        HashMap<String, String> setpayloadData = new HashMap<String, String>();
-        setpayloadData.put("test", "test");
-    }
-
-    @Test
-    public void testCoapLogHandler() throws Exception {
-        CoapServer server = new CoapServer();
-        server.startServer(new InetSocketAddress(5683));
-        server.addHandler(new CoapLogHandler());
-
-        CoapClient client = new CoapClient();
-        client.addHandler(new CoapLogHandler());
-        client.startClient(new InetSocketAddress("127.0.0.1", 5683));
-
-        CoapRequest request = new CoapRequest(CoapMethod.PUT);
-        client.sendRequest(request);
-
-        client.stopClient();
-        server.stopServer();
-    }
-
-    @Test
-    public void testJSONUtil() throws Exception {
-        HashMap<Object, Object> setpayloadData = new HashMap<Object, Object>();
-        setpayloadData.put("test", "test");
-
-        String msg = JSONUtil.writeJSON(setpayloadData);
-        JSONUtil.parseJSON(msg, "test");
-        JSONUtil.parseJSON(msg);
-    }
-
-    @Test
-    public void testLogger() throws Exception {
-        Logger.v("VERBOSE test");
-        Logger.d("DEBUG test");
-        Logger.i("INFO test");
-        Logger.e("ERROR test");
-        Logger.w("WARNING test");
-    }
-}