Merge 1.2-rel cloud project into master
authorJee Hyeok Kim <jihyeok13.kim@samsung.com>
Thu, 20 Oct 2016 09:00:19 +0000 (18:00 +0900)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Fri, 21 Oct 2016 00:59:27 +0000 (00:59 +0000)
1. Overwrite 1.2-rel cloud project into master

Change-Id: I9271607595166fce4bda9011f028a40514908fec
Signed-off-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/13487
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Yeonghun Nam <yeonghun.nam@samsung.com>
93 files changed:
cloud/account/README
cloud/account/properties/config.properties
cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.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/GroupTable.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/InviteTable.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/TokenTable.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/UserTable.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateConstants.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateStorage.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/crl/CrlManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/crl/CrlResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CSRParser.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CertificateBuilder.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CertificateExtension.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/crl/CrlIssuer.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/AccountResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/credprov/cert/CertificateResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/credprov/crl/CrlResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/session/SessionResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/tokenrefresh/TokenRefreshResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/group/GroupResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/DeviceServerSystem.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/DiResource.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/Account.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/AccountSession.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/Acl.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/AclGroup.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/AclInvite.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/Certificate.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/mq/MessageQueue.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/DevicePresence.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceDirectory.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceFind.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourcePresence.java
cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/proxy/rd/DevicePresenceTest.java
cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceFindTest.java
cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourcePresenceTest.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/MessageQueueUtils.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaCommonWrapper.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaConsumerWrapper.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/kafka/KafkaProducerWrapper.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/resources/MQBrokerResource.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/Topic.java
cloud/messagequeue/src/main/java/org/iotivity/cloud/mqserver/topic/TopicManager.java
cloud/messagequeue/src/test/java/org/iotivity/cloud/mqserver/resources/MQBrokerResourceTest.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/Constants.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/ResourceDirectoryServer.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/DBManager.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/db/MongoDB.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/PayloadManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/RDManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/InsManager.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishLinks.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishPayload.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/PublishTags.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/ResourceDirectoryResource.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryLinks.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryPayload.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryResource.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/res/DiscoveryTags.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/PresenceManager.java [new file with mode: 0644]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/ResPresenceManager.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DevicePresenceResource.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/device/DeviceState.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresencePayload.java [deleted file]
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/resource/ResPresenceResource.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/util/TypeCastingManager.java [deleted file]
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/DevicePresenceResourceTest.java
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/DiscoveryResourceTest.java
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTestUtils.java
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/ResourceDirectoryResourceTest.java
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/ResourcePresenceResourceTest.java
cloud/samples/client/SConscript
cloud/samples/client/airconditioner/aircon_controller.cpp
cloud/samples/client/group_invite/group_invite.cpp
cloud/samples/client/group_invite/group_light_share.cpp [new file with mode: 0644]
cloud/samples/client/messagequeue/mq_publisher.cpp
cloud/samples/client/messagequeue/mq_subscriber.cpp
cloud/samples/client/thin_light/thin_room_light.cpp
cloud/stack/src/main/java/org/iotivity/cloud/base/connector/CoapClient.java
cloud/stack/src/main/java/org/iotivity/cloud/base/device/CoapDevice.java

index 37d1215..c5cd318 100644 (file)
@@ -18,7 +18,9 @@ Build and Run
 
        - The CloudAccount-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder
 
-4) Run .jar file
+4) Copy the "properties" folder to inside the "target" folder
+
+5) Run .jar file
 
        go to "target" folder
        $ java -jar CloudAccount-0.0.1-SNAPSHOT.jar arg1(AccountServer CoAP Server Port) arg2(TLS mode required)
@@ -31,3 +33,6 @@ Build and Run
        - Before you run a Accout server, You need to set up following steps.
           1) Install MongoDB
           2) Install Github certificates for github.com and *.github.com.
+5) Please download: file from http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html: Java Cryptography Extension
+         1.Extract files from zip. 
+         2.Place local_policy.jar and US_export_policy.jar files in/usr/lib/jvm/PATH_TO_JDK/jre/lib/security 
index 73d9aaa..9e82e75 100644 (file)
@@ -1,17 +1,18 @@
 #New Serial number
-#Wed Sep 07 17:08:34 EEST 2016
+#Tue Sep 27 16:11:46 EEST 2016
 keyGeneratorAlgorithm=ECDSA
 notAfterInterval=20
 securityProvider=BC
 ellipticCurve=secp256r1
+keystoreDir=keystore
 keyStoreLocation=keystore{0}certificateStorage.jks
+keystoreType=BKS
 nextUpdateInterval=1
 signatureAlgorithm=SHA256withECDSA
-keystoreType=BKS
 rootOU=OCF Sub CA
-serialNumber=515
+serialNumber=0
 rootO=Samsung
-caAlias=uuid\:31313131-3131-3131-3131-313131313131
 subjectName=uuid\:31313131-3131-3131-3131-313131313131
+caAlias=uuid\:31313131-3131-3131-3131-313131313131
 password=PASSWORD
 rootC=KR
index b7fe164..f2830e5 100644 (file)
@@ -74,10 +74,6 @@ public class AccountServer {
 
         serverSystem.addResource(new AclResource());
 
-        serverSystem.addResource(new CrlResource());
-
-        serverSystem.addResource(new AclResource());
-
         serverSystem.addResource(new InviteResource());
 
         serverSystem.addServer(new CoapServer(
index 092de7e..67fac58 100644 (file)
  */
 package org.iotivity.cloud.accountserver;
 
-import org.iotivity.cloud.base.OICConstants;
-
 import java.io.File;
 
+import org.iotivity.cloud.base.OICConstants;
+
 public class Constants extends OICConstants {
 
-    public static final String PROPERTIES_FILE_NAME  = "properties"
+    public static final String PROPERTIES_FILE_NAME       = "properties"
             + File.separator + "config.properties";
 
     // Database name
 
-    public static final String DB_NAME               = "ACCOUNTSERVER_DB";
+    public static final String DB_NAME                    = "ACCOUNTSERVER_DB";
 
     // Database table
 
-    public static final String CRL_TABLE             = "CRL_TABLE";
+    public static final String CRL_TABLE                  = "CRL_TABLE";
 
-    public static final String CERTIFICATE_TABLE     = "CERTIFICATE_TABLE";
+    public static final String CERTIFICATE_TABLE          = "CERTIFICATE_TABLE";
 
-    public static final String USER_TABLE            = "USER_TABLE";
+    public static final String USER_TABLE                 = "USER_TABLE";
 
-    public static final String TOKEN_TABLE           = "TOKEN_TABLE";
+    public static final String TOKEN_TABLE                = "TOKEN_TABLE";
 
-    public static final String GROUP_TABLE           = "GROUP_TABLE";
+    public static final String GROUP_TABLE                = "GROUP_TABLE";
 
-    public static final String INVITE_TABLE          = "INVITE_TABLE";
+    public static final String INVITE_TABLE               = "INVITE_TABLE";
 
-    public static final String DEVICE_TABLE          = "DEVICE_TABLE";
+    public static final String DEVICE_TABLE               = "DEVICE_TABLE";
 
-    public static final String ACL_TABLE             = "ACL_TABLE";
+    public static final String ACL_TABLE                  = "ACL_TABLE";
 
-    public static final String ACLTEMPLATE_TABLE     = "ACLTEMPLATE_TABLE";
+    public static final String ACLTEMPLATE_TABLE          = "ACLTEMPLATE_TABLE";
 
     // Database table key
 
-    public static final String KEYFIELD_SN           = "serialNumber";
+    public static final String KEYFIELD_SN                = "serialNumber";
 
-    public static final String KEYFIELD_NA           = "notAfter";
+    public static final String KEYFIELD_NA                = "notAfter";
 
-    public static final String KEYFIELD_NB           = "notBefore";
+    public static final String KEYFIELD_NB                = "notBefore";
 
-    public static final String KEYFIELD_REVOKED      = "revoked";
+    public static final String KEYFIELD_REVOKED           = "revoked";
 
-    public static final String KEYFIELD_UUID         = "uuid";
+    public static final String KEYFIELD_UUID              = "uuid";
 
-    public static final String KEYFIELD_ACCESSTOKEN  = "accesstoken";
+    public static final String KEYFIELD_ACCESSTOKEN       = "accesstoken";
 
-    public static final String KEYFIELD_GID          = "gid";
+    public static final String KEYFIELD_GID               = "gid";
 
-    public static final String KEYFIELD_DID          = "did";
+    public static final String KEYFIELD_DID               = "did";
 
-    public static final String KEYFIELD_ACLID        = "aclid";
+    public static final String KEYFIELD_ACLID             = "aclid";
 
-    public static final String KEYFIELD_DI           = "di";
+    public static final String KEYFIELD_DI                = "di";
 
-    public static final String KEYFIELD_GTYPE        = "gtype";
+    public static final String KEYFIELD_GTYPE             = "gtype";
 
-    public static final String KEYFIELD_GIDLIST      = "gidlist";
+    public static final String KEYFIELD_GIDLIST           = "gidlist";
 
-    public static final String KEYFIELD_MIDLIST      = "midlist";
+    public static final String KEYFIELD_MIDLIST           = "midlist";
 
-    public static final String KEYFIELD_GACL         = "gacl";
+    public static final String KEYFIELD_GACL              = "gacl";
 
-    public static final String KEYFIELD_USERID       = "userid";
+    public static final String KEYFIELD_USERID            = "userid";
 
-    public static final String KEYFIELD_PROVIDER     = "provider";
+    public static final String KEYFIELD_PROVIDER          = "provider";
 
-    public static final String KEYFIELD_ISSUED_TIME  = "issuedtime";
+    public static final String KEYFIELD_ISSUED_TIME       = "issuedtime";
 
-    public static final String KEYFIELD_EXPIRED_TIME = "expiredtime";
+    public static final String KEYFIELD_EXPIRED_TIME      = "expiredtime";
 
-    public static final String KEYFIELD_INVITE_USER  = "inviteUser";
+    public static final String KEYFIELD_INVITE_USER       = "inviteUser";
 
-    public static final String KEYFIELD_INVITED_USER = "invitedUser";
+    public static final String KEYFIELD_INVITED_USER      = "invitedUser";
 
-    public static final String KEYFIELD_ACE_SUBJECT_ID = "subjectuuid";
+    public static final String KEYFIELD_ACE_SUBJECT_ID    = "subjectuuid";
 
-    public static final String KEYFIELD_ACE_SUBJECT_TYPE = "stype";
+    public static final String KEYFIELD_ACE_SUBJECT_TYPE  = "stype";
 
-    public static final String KEYFIELD_ACE_RESOURCE= "resources";
+    public static final String KEYFIELD_ACE_RESOURCE      = "resources";
 
-    public static final String KEYFIELD_ACE_VALIDITY = "validity";
+    public static final String KEYFIELD_ACE_VALIDITY      = "validity";
 
-    public static final String KEYFIELD_ACE_PERMISSION = "permission";
+    public static final String KEYFIELD_ACE_PERMISSION    = "permission";
 
     public static final String KEYFIELD_ACE_RESOURCE_HREF = "href";
 
-    public static final String KEYFIELD_ACE_RESOURCE_RT = "rt";
+    public static final String KEYFIELD_ACE_RESOURCE_RT   = "rt";
 
-    public static final String KEYFIELD_ACE_RESOURCE_IF = "if";
+    public static final String KEYFIELD_ACE_RESOURCE_IF   = "if";
 
     // Request payload key
 
-    public static final String REQ_DEVICE_ID         = "di";
+    public static final String REQ_DEVICE_ID              = "di";
 
-    public static final String REQ_DEVICE_ID_LIST    = "dilist";
+    public static final String REQ_DEVICE_ID_LIST         = "dilist";
 
-    public static final String REQ_UUID_ID           = "uid";
+    public static final String REQ_UUID_ID                = "uid";
 
-    public static final String REQ_ACE_ID            = "aceid";
+    public static final String REQ_ACE_ID                 = "aceid";
 
-    public static final String REQ_ACL_ID            = "aclid";
+    public static final String REQ_ACL_ID                 = "aclid";
 
-    public static final String REQ_ROWNER_ID         = "rowneruuid";
+    public static final String REQ_ROWNER_ID              = "rowneruuid";
 
-    public static final String REQ_ACL_LIST          = "aclist";
+    public static final String REQ_ACL_LIST               = "aclist";
 
-    public static final String REQ_OWNER_ID          = "oid";
+    public static final String REQ_OWNER_ID               = "oid";
 
-    public static final String REQ_AUTH_CODE         = "authcode";
+    public static final String REQ_AUTH_CODE              = "authcode";
 
-    public static final String REQ_AUTH_PROVIDER     = "authprovider";
+    public static final String REQ_AUTH_PROVIDER          = "authprovider";
 
-    public static final String REQ_ACCESS_TOKEN      = "accesstoken";
+    public static final String REQ_ACCESS_TOKEN           = "accesstoken";
 
-    public static final String REQ_LOGIN             = "login";
+    public static final String REQ_LOGIN                  = "login";
 
-    public static final String REQ_REFRESH_TOKEN     = "refreshtoken";
+    public static final String REQ_REFRESH_TOKEN          = "refreshtoken";
 
-    public static final String REQ_GRANT_TYPE        = "granttype";
+    public static final String REQ_GRANT_TYPE             = "granttype";
 
-    public static final String REQ_AUTH_OPTIONS      = "options";
+    public static final String REQ_AUTH_OPTIONS           = "options";
 
-    public static final String REQ_REQUEST_METHOD    = "rm";
+    public static final String REQ_REQUEST_METHOD         = "rm";
 
-    public static final String REQ_REQUEST_URI       = "uri";
+    public static final String REQ_REQUEST_URI            = "uri";
 
-    public static final String REQ_SEARCH_USER_ID    = "sid";
+    public static final String REQ_SEARCH_USER_ID         = "sid";
 
-    public static final String REQ_SEARCH_CRITERIA   = "search";
+    public static final String REQ_SEARCH_CRITERIA        = "search";
 
-    public static final String REQ_GROUP_ID          = "gid";
+    public static final String REQ_GROUP_ID               = "gid";
 
-    public static final String REQ_GROUP_MASTER_ID   = "gmid";
+    public static final String REQ_GROUP_MASTER_ID        = "gmid";
 
-    public static final String REQ_GROUP_TYPE        = "gtype";
+    public static final String REQ_GROUP_TYPE             = "gtype";
 
-    public static final String REQ_MEMBER            = "mid";
+    public static final String REQ_MEMBER                 = "mid";
 
-    public static final String REQ_LAST_UPDATE       = "lu";
+    public static final String REQ_LAST_UPDATE            = "lu";
 
-    public static final String REQ_THIS_UPDATE       = "tu";
+    public static final String REQ_THIS_UPDATE            = "tu";
 
-    public static final String REQ_NEXT_UPDATE       = "nu";
+    public static final String REQ_NEXT_UPDATE            = "nu";
 
-    public static final String REQ_CRL               = "crl";
+    public static final String REQ_CRL                    = "crl";
 
-    public static final String REQ_SERIAL_NUMBER     = "rcsn";
+    public static final String REQ_SERIAL_NUMBER          = "rcsn";
 
-    public static final String REQ_MEMBER_LIST       = "midlist";
+    public static final String REQ_MEMBER_LIST            = "midlist";
 
-    public static final String REQ_GTYPE_PRIVATE     = "Private";
+    public static final String REQ_GTYPE_PRIVATE          = "Private";
 
-    public static final String REQ_GTYPE_PUBLIC      = "Public";
+    public static final String REQ_GTYPE_PUBLIC           = "Public";
 
-    public static final String REQ_CSR               = "csr";
+    public static final String REQ_CSR                    = "csr";
 
-    public static final String REQ_INVITE            = "invite";
+    public static final String REQ_INVITE                 = "invite";
 
     // Response payload key
 
-    public static final String RESP_ACCESS_TOKEN     = "accesstoken";
+    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_REDIRECT_URI          = "redirecturi";
+
+    public static final String RESP_CERTIFICATE           = "certificate";
 
-    public static final String RESP_REFRESH_TOKEN    = "refreshtoken";
+    public static final String RESP_SERVER_ID             = "sid";
 
-    public static final String RESP_TOKEN_TYPE       = "tokentype";
+    public static final String RESP_DEVICES               = "devices";
 
-    public static final String RESP_EXPIRES_IN       = "expiresin";
+    public static final String RESP_UUID                  = "uid";
 
-    public static final String RESP_REDIRECT_URI     = "redirecturi";
+    public static final String RESP_USER_INFO             = "uinfo";
 
-    public static final String RESP_CERTIFICATE      = "certificate";
+    public static final String RESP_USER_LIST             = "ulist";
 
-    public static final String RESP_SERVER_ID        = "sid";
+    public static final String RESP_DEVICE_ID             = "di";
 
-    public static final String RESP_DEVICES          = "devices";
+    public static final String RESP_CERT                  = "cert";
 
-    public static final String RESP_UUID             = "uid";
+    public static final String RESP_CACERT                = "cacert";
 
-    public static final String RESP_USER_INFO        = "uinfo";
+    public static final String RESP_INVITE                = "invite";
 
-    public static final String RESP_USER_LIST        = "ulist";
+    public static final String RESP_INVITED               = "invited";
 
-    public static final String RESP_DEVICE_ID        = "di";
+    public static final String RESP_ACL_ALLOWED           = "Allowed";
 
-    public static final String RESP_CERT             = "cert";
+    public static final String RESP_ACL_DENIED            = "Denied";
 
-    public static final String RESP_CACERT           = "cacert";
+    public static final String ENCODING                   = "encoding";
 
-    public static final String RESP_INVITE           = "invite";
+    public static final String DATA                       = "data";
 
-    public static final String RESP_INVITED          = "invited";
+    public static final String CERT                       = "cert";
 
-    public static final String ENCODING = "encoding";
+    public static final String CERT_CHAIN                 = "certchain";
 
-    public static final String DATA = "data";
+    // query parameter key
 
-    public static final String CERT = "cert";
+    public static final String REQ_INVITE_ACCEPT          = "accept";
 
-    public static final String CERT_CHAIN = "certchain";
+    // constants
 
-    public static final String RESP_ACL_ALLOWED      = "Allowed";
+    public static final String INVITE_ACCEPT              = "1";
 
-    public static final String RESP_ACL_DENIED       = "Denied";
+    public static final String INVITE_DENY                = "0";
 
     // static token type
 
-    public static final String TOKEN_TYPE_BEARER     = "bearer";
+    public static final String TOKEN_TYPE_BEARER          = "bearer";
 
-    public static final int    TOKEN_INFINITE        = -1;
+    public static final int    TOKEN_INFINITE             = -1;
 
     // auth servers
 
-    public static final String GITHUB                = "Github";
+    public static final String GITHUB                     = "Github";
 
-    public static final String SAMSUNG               = "Samsung";
+    public static final String SAMSUNG                    = "Samsung";
 
-    public static final String GOOGLE                = "Google";
+    public static final String GOOGLE                     = "Google";
 }
index 275d1bb..b88c1a1 100644 (file)
@@ -137,6 +137,11 @@ public class AccountDBManager {
 
     }
 
+    /**
+     * API to implement singleton pattern based DB manager
+     * 
+     * @return account DB manager
+     */
     public static AccountDBManager getInstance() {
 
         return accoutDBManager;
@@ -148,7 +153,7 @@ public class AccountDBManager {
      * 
      * @param tableName
      *            table name to be inserted
-     * @param insert
+     * @param record
      *            record to be inserted
      */
     public void insertRecord(String tableName, HashMap<String, Object> insert) {
@@ -219,7 +224,7 @@ public class AccountDBManager {
 
         if (!_updateRecord(tableName, replace))
             throw new InternalServerErrorException(
-                    "Database record updateX509CRL failed");
+                    "Database record update failed");
 
     }
 
index 0f89773..8cdc6a5 100644 (file)
@@ -33,6 +33,22 @@ public class GroupTable {
     public GroupTable() {
     }
 
+    /**
+     * API to initialize group table instance
+     * 
+     * @param gid
+     *            group ID
+     * @param midlist
+     *            member ID list as a form of array
+     * @param dilist
+     *            device ID list as a form of array
+     * @param gmid
+     *            group master ID
+     * @param gacl
+     *            group ACL
+     * @param gtype
+     *            group type
+     */
     public GroupTable(String gid, Object midlist, Object dilist, String gmid,
             String gacl, String gtype) {
         this.gid = gid;
@@ -43,50 +59,116 @@ public class GroupTable {
         this.gtype = gtype;
     }
 
+    /**
+     * API to get group ID
+     * 
+     * @return group ID
+     */
     public String getGid() {
         return gid;
     }
 
+    /**
+     * API to set group ID
+     * 
+     * @param gid
+     *            group ID to be set
+     */
     public void setGid(Object gid) {
         this.gid = gid.toString();
     }
 
+    /**
+     * API to get member ID list of the group
+     * 
+     * @return member ID list
+     */
     public Object getMidlist() {
         return midlist;
     }
 
+    /**
+     * API to set member ID list of the group
+     * 
+     * @param midlist
+     *            member ID list to be set
+     */
     public void setMidlist(Object midlist) {
         this.midlist = midlist;
     }
 
+    /**
+     * API to get device ID list of the group
+     * 
+     * @return device ID list
+     */
     public Object getDilist() {
         return dilist;
     }
 
+    /**
+     * API to set device ID list of the group
+     * 
+     * @param dilist
+     *            device ID list to be set
+     */
     public void setDilist(Object dilist) {
         this.dilist = dilist;
     }
 
+    /**
+     * API to get the group master ID
+     * 
+     * @return group master ID
+     */
     public String getGmid() {
         return gmid;
     }
 
+    /**
+     * API to set the master ID of the group
+     * 
+     * @param gmid
+     *            group master ID to be set
+     */
     public void setGmid(Object gmid) {
         this.gmid = gmid.toString();
     }
 
+    /**
+     * API to get group ACL
+     * 
+     * @return group ACL
+     */
     public String getGacl() {
         return gacl;
     }
 
+    /**
+     * API to set group ACL of the group
+     * 
+     * @param gacl
+     *            group ACL to be set
+     */
     public void setGacl(Object gacl) {
         this.gacl = gacl.toString();
     }
 
+    /**
+     * API to get group type
+     * 
+     * @return group type
+     */
     public String getGtype() {
         return gtype;
     }
 
+    /**
+     * API to set group type
+     * 
+     * @param gtype
+     *            group type to be set
+     */
     public void setGtype(Object gtype) {
         this.gtype = gtype.toString();
     }
index 151c56f..b8451d3 100644 (file)
@@ -30,28 +30,66 @@ public class InviteTable {
     public InviteTable() {
     }
 
+    /**
+     * API to initialize an instance of the group invitation table
+     * 
+     * @param inviteUser
+     *            user ID who requests the group invitation for the
+     *            "invitedUser"
+     * @param gid
+     *            group ID to be invited
+     * @param invitedUser
+     *            invited user ID
+     */
     public InviteTable(String inviteUser, String gid, String invitedUser) {
         this.inviteUser = inviteUser;
         this.gid = gid;
         this.invitedUser = invitedUser;
     }
 
+    /**
+     * API to get the group ID to be invited
+     * 
+     * @return group ID
+     */
     public String getGid() {
         return gid;
     }
 
+    /**
+     * API to set the group ID to invite
+     * 
+     * @param gid
+     *            group ID
+     */
     public void setGid(String gid) {
         this.gid = gid;
     }
 
+    /**
+     * API to get the user ID who requests the group invitation
+     * 
+     * @return user ID
+     */
     public String getInviteUser() {
         return inviteUser;
     }
 
+    /**
+     * API to set the user ID to be invited
+     * 
+     * @param inviteUser
+     *            user ID to be invited
+     */
     public void setInviteUser(String inviteUser) {
         this.inviteUser = inviteUser;
     }
 
+    /**
+     * API to get the user Id to be invited
+     * 
+     * @return user ID to be invited
+     */
     public String getInvitedUser() {
         return invitedUser;
     }
index 7ae794f..7cfc6ae 100644 (file)
@@ -25,11 +25,10 @@ import org.iotivity.cloud.accountserver.Constants;
 
 /**
  *
- * This class provides a set of APIs storing session information of authorized
- * user.
+ * This class provides a set of APIs to store session information of authorized
+ * users.
  *
  */
-
 public class TokenTable {
 
     private String uuid         = null;
@@ -40,62 +39,139 @@ public class TokenTable {
     private long   expiredtime  = Constants.TOKEN_INFINITE;
     private String issuedtime   = null;
 
+    /**
+     * API to get user ID
+     * 
+     * @return user ID
+     */
     public String getUuid() {
         return uuid;
     }
 
+    /**
+     * API to set user ID
+     * 
+     * @param uuid
+     *            user ID to be registered
+     */
     public void setUuid(Object uuid) {
         this.uuid = uuid.toString();
     }
 
+    /**
+     * API to get device ID
+     * 
+     * @return device ID
+     */
     public String getDid() {
         return did;
     }
 
+    /**
+     * API to set device ID
+     * 
+     * @param did
+     *            device ID to be registered
+     */
     public void setDid(String did) {
         this.did = did;
     }
 
+    /**
+     * API to get access token
+     * 
+     * @return access token
+     */
     public String getAccesstoken() {
         return accesstoken;
     }
 
+    /**
+     * API to set the access token to the DB
+     * 
+     * @param accesstoken
+     *            access token to be registered
+     */
     public void setAccesstoken(Object accesstoken) {
         if (accesstoken != null)
             this.accesstoken = accesstoken.toString();
     }
 
+    /**
+     * API to get the refresh token from the DB
+     * 
+     * @return refresh token
+     */
     public String getRefreshtoken() {
         return refreshtoken;
     }
 
+    /**
+     * API to set the refresh token to the DB
+     * 
+     * @param refreshtoken
+     *            refresh token to be registered
+     */
     public void setRefreshtoken(Object refreshtoken) {
         if (refreshtoken != null)
             this.refreshtoken = refreshtoken.toString();
     }
 
+    /**
+     * API to get the auth provider name
+     * 
+     * @return auth provider name
+     */
     public String getProvider() {
         return provider;
     }
 
+    /**
+     * API to set the auth provider name to the DB
+     * 
+     * @param provider
+     *            auth provider name to be registered
+     */
     public void setProvider(Object provider) {
         if (provider != null)
             this.provider = provider.toString();
     }
 
+    /**
+     * API to get the expiration time of the access token
+     * 
+     * @return time remain
+     */
     public long getExpiredtime() {
         return expiredtime;
     }
 
+    /**
+     * API to set the expiration time of the access token
+     * 
+     * @param expiredtime
+     *            expiration time of the access token
+     */
     public void setExpiredtime(Object expiredtime) {
         if (expiredtime != null)
             this.expiredtime = Long.valueOf(expiredtime.toString());
     }
 
+    /**
+     * API to get the issued time of the token
+     * 
+     * @return issued time
+     */
     public String getIssuedtime() {
         return issuedtime;
     }
 
+    /**
+     * API to get the issued time of the token
+     * 
+     * @param issuedtime
+     *            issued time to be registered
+     */
     public void setIssuedtime(Object issuedtime) {
         if (issuedtime != null)
             this.issuedtime = issuedtime.toString();
index bdb9f33..b653c29 100644 (file)
@@ -1,5 +1,10 @@
 package org.iotivity.cloud.accountserver.db;
 
+/**
+ * This class provides a set of APIs to store user information of authorized
+ * users.
+ *
+ */
 public class UserTable {
     private String uuid     = null;
     private String userid   = null;
@@ -7,46 +12,101 @@ public class UserTable {
     private String email    = null;
     private String phone    = null;
 
+    /**
+     * API to get user ID
+     * 
+     * @return user ID as a form of UUID
+     */
     public String getUuid() {
         return uuid;
     }
 
+    /**
+     * API to set user ID
+     * 
+     * @param uuid
+     *            user ID to be registered as a form of UUID
+     */
     public void setUuid(Object uuid) {
         if (uuid != null)
             this.uuid = uuid.toString();
     }
 
+    /**
+     * API to get user ID
+     * 
+     * @return user ID
+     */
     public String getUserid() {
         return userid;
     }
 
+    /**
+     * API to set user ID
+     * 
+     * @param userid
+     *            user ID to be registered
+     */
     public void setUserid(Object userid) {
         if (userid != null)
             this.userid = userid.toString();
     }
 
+    /**
+     * API to get the auth provider name
+     * 
+     * @return auth provider name
+     */
     public String getProvider() {
         return provider;
     }
 
+    /**
+     * API to set the auth provider name to the DB
+     * 
+     * @param provider
+     *            auth provider name to be registered
+     */
     public void setProvider(Object provider) {
         if (provider != null)
             this.provider = provider.toString();
     }
 
+    /**
+     * API to get the e-mail address of the user
+     * 
+     * @return e-mail address
+     */
     public String getEmail() {
         return email;
     }
 
+    /**
+     * API to set the e-mail address of the user
+     * 
+     * @param email
+     *            e-mail address to be registered
+     */
     public void setEmail(Object email) {
         if (email != null)
             this.email = email.toString();
     }
 
+    /**
+     * API to get the phone number of the user
+     * 
+     * @return phone number
+     */
     public String getPhone() {
         return phone;
     }
 
+    /**
+     * API to set the phone number of the user
+     * 
+     * @param phone
+     *            phone number to be registered
+     */
     public void setPhone(Object phone) {
         if (phone != null)
             this.phone = phone.toString();
index 1adb63a..62dfc3e 100644 (file)
@@ -148,32 +148,84 @@ public class Acl {
 
     @SuppressWarnings("unchecked")
 
-    public void addACE(List<HashMap<String, Object>> aclist) {
+        public List<HashMap<String, Object>> addACE(List<HashMap<String, Object>> aclist) {
+            Log.v("IN addACE");
+            HashMap<String, Object> hashmap = AccountDBManager.getInstance()
+                .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+            if (hashmap == null) {
+                throw new BadRequestException("aclid is invalid");
+            }
+            List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
+                .get(Constants.REQ_ACL_LIST);
+
+
+            ListIterator<HashMap<String, Object>> iterator = aclist.listIterator();
+            while (iterator.hasNext()) {
+                HashMap<String, Object> aceMap = iterator.next();
+                if (aceMap.get(Constants.KEYFIELD_ACE_SUBJECT_ID)
+                        .equals(hashmap.get(Constants.REQ_OWNER_ID))) {
+                    // remove current iterator
+                    iterator.remove();
+                    continue;
+                }
+                aceMap.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
+            }
+
+            List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
+                    aclist);
 
+            if (aclDbList != null) {
+                newAcList.addAll(aclDbList);
+            }
+            hashmap.put(Constants.REQ_ACL_LIST, newAcList);
+            AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
+                    hashmap);
+            notifyToSubscriber(getResponsePayload(true));
+            Log.v("OUT addACE");
+            return aclist;
+        }
+
+    public HashMap<String, Object> getACE(String aceid) {
         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+        if (hashmap == null) {
+            throw new BadRequestException("aclid is invalid");
+        }
 
         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
             .get(Constants.REQ_ACL_LIST);
-
-
-        for(HashMap<String, Object> ace : aclist) {
-            ace.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
+        ListIterator<HashMap<String, Object>> iterator = aclDbList
+            .listIterator();
+        while (iterator.hasNext()) {
+            HashMap<String, Object> aceMap = iterator.next();
+            if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
+                // Return the current element from the iterator
+                return aceMap;
+            }
+        }
+        throw new BadRequestException("aceid is invalid");
+    }
+    public boolean isValidAceId(String aceid) {
+        HashMap<String, Object> hashmap = AccountDBManager.getInstance()
+            .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+        if (hashmap == null) {
+            return false;
         }
 
-        List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
-                aclist);
-
-        if (aclDbList != null) {
-            newAcList.addAll(aclDbList);
+        List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
+            .get(Constants.REQ_ACL_LIST);
+        ListIterator<HashMap<String, Object>> iterator = aclDbList
+            .listIterator();
+        while (iterator.hasNext()) {
+            HashMap<String, Object> aceMap = iterator.next();
+            if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
+                return true;
+            }
         }
-        hashmap.put(Constants.REQ_ACL_LIST, newAcList);
-        AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
-                hashmap);
-        notifyToSubscriber(getResponsePayload(true));
+        return false;
     }
-
     public void updateACE(String aceid, HashMap<String, Object> ace) {
+        Log.v("IN updateACE");
 
         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
             .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
@@ -195,6 +247,8 @@ public class Acl {
         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, hashmap);
         notifyToSubscriber(getResponsePayload(true));
+        Log.v("OUT updateACE");
+
     }
 
     public void deleteACE(String aceid) {
index f974aaf..081315f 100644 (file)
@@ -87,16 +87,34 @@ public class AclManager {
         mAcls.remove(aclid);
     }
 
-    public void addAclACE(String aclid, List<HashMap<String, Object>> aclist) {
-        getAcl(aclid).addACE(aclist);
+    public List<HashMap<String, Object>> addAclACE(String aclid, List<HashMap<String, Object>> aclist) {
+        return getAcl(aclid).addACE(aclist);
+    }
+
+    public HashMap<String, Object> getAclACE(String aclid, String aceid) {
+        return getAcl(aclid).getACE(aceid);
     }
 
     public void updateACE(String aclid, String aceid, HashMap<String, Object> ace) {
-        getAcl(aclid).updateACE(aceid, ace);
+        if(getAcl(aclid).isValidAceId(aceid))
+        {
+            getAcl(aclid).updateACE(aceid, ace);
+        }
+        else
+        {
+            throw new BadRequestException("Invalid parameters");
+        }
     }
 
     public void deleteAclACE(String aclid, String aceid) {
-        getAcl(aclid).deleteACE(aceid);
+        if(getAcl(aclid).isValidAceId(aceid))
+        {
+            getAcl(aclid).deleteACE(aceid);
+        }
+        else
+        {
+            throw new BadRequestException("Invalid parameters");
+        }
     }
     public void deleteAclAclist(String aclid) {
         getAcl(aclid).deleteAclist();
index c9f9c51..7ad3516 100644 (file)
@@ -4,7 +4,6 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
-
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.base.device.Device;
 import org.iotivity.cloud.base.exception.ServerException;
@@ -20,12 +19,12 @@ import org.iotivity.cloud.util.Cbor;
 
 public class AclResource extends Resource {
 
-    private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
-    private static AclManager           mAclManager = new AclManager();
+    private Cbor<HashMap<String, Object>> mCbor       = new Cbor<>();
+    private static AclManager             mAclManager = new AclManager();
 
     public AclResource() {
-        super(Arrays.asList(Constants.PREFIX_OIC,
-                Constants.ACL_URI, Constants.ID_URI));
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.ACL_URI,
+                Constants.ID_URI));
     }
 
     public static AclManager getInstance() {
@@ -68,15 +67,18 @@ public class AclResource extends Resource {
             throws ServerException {
 
         if (getUriPathSegments().containsAll(request.getUriPathSegments())) {
-            String oid = request.getUriQueryMap().get(Constants.REQ_OWNER_ID).get(0);
-            String di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0);
+            String oid = request.getUriQueryMap().get(Constants.REQ_OWNER_ID)
+                    .get(0);
+            String di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID)
+                    .get(0);
             if (mAclManager.getAclid(di) == null) {
                 return MessageBuilder.createResponse(request,
-                    ResponseStatus.CREATED, ContentFormat.APPLICATION_CBOR,
-                    mCbor.encodingPayloadToCbor(
-                        mAclManager.createAcl(oid, di)));
+                        ResponseStatus.CREATED, ContentFormat.APPLICATION_CBOR,
+                        mCbor.encodingPayloadToCbor(
+                                mAclManager.createAcl(oid, di)));
             } else {
-                throw new BadRequestException("aclid already exists for the given di");
+                throw new BadRequestException(
+                        "aclid already exists for the given di");
             }
         }
 
@@ -84,33 +86,37 @@ public class AclResource extends Resource {
     }
 
     private IResponse handlePostRequest(IRequest request)
-            throws ServerException {
+        throws ServerException {
 
-        HashMap<String, Object> payloadData = mCbor
+            HashMap<String, Object> payloadData = mCbor
                 .parsePayloadFromCbor(request.getPayload(), HashMap.class);
 
-        if (!getUriPathSegments().containsAll(request.getUriPathSegments())) {
-            String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
-
-            List<HashMap<String, Object>> aclist = null;
-            if (!payloadData.containsKey(Constants.REQ_ACL_LIST)) {
-                throw new BadRequestException("aclist not included in payload");
+            if (null !=request.getUriQueryMap()) {
+                String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
+                String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0);
+                List<HashMap<String, Object>> aclist = (List<HashMap<String, Object>>) payloadData
+                    .get(Constants.REQ_ACL_LIST);
+                mAclManager.updateACE(aclid, aceid, aclist.get(0));
+                return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
             }
+            else if (!getUriPathSegments().containsAll(request.getUriPathSegments())) {
+                String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
+
+                List<HashMap<String, Object>> aclist = null;
+                if (!payloadData.containsKey(Constants.REQ_ACL_LIST)) {
+                    throw new BadRequestException("aclist not included in payload");
+                }
                 aclist = (List<HashMap<String, Object>>) payloadData
-                        .get(Constants.REQ_ACL_LIST);
-            mAclManager.addAclACE(aclid, aclist);
-            return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-        }else if (getUriPathSegments().containsAll(request.getUriPathSegments())) {
-            String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
-            String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0);
-            HashMap<String, Object> ace = (HashMap<String, Object>) payloadData.get(Constants.REQ_ACL_LIST);
-            mAclManager.updateACE(aclid, aceid, ace);
-            return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
+                    .get(Constants.REQ_ACL_LIST);
+                aclist= mAclManager.addAclACE(aclid, aclist);
+                payloadData.put(Constants.REQ_ACL_LIST, aclist);
+                return MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                        ContentFormat.APPLICATION_CBOR,
+                        mCbor.encodingPayloadToCbor(payloadData));
+            }
+            throw new BadRequestException("uriPath is invalid");
         }
 
-        throw new BadRequestException("uriPath is invalid");
-
-    }
 
     @SuppressWarnings("unchecked")
 
@@ -127,19 +133,23 @@ public class AclResource extends Resource {
             }
             responsePayload = mAclManager.getAclid(di);
         } else {
-            String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
-            switch(request.getObserve()) {
+            String aclid = request.getUriPathSegments()
+                    .get(getUriPathSegments().size());
+            switch (request.getObserve()) {
                 case NOTHING:
                     responsePayload = mAclManager.getAclInfo(aclid);
                     break;
                 case SUBSCRIBE:
-                    di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0);
+                    di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID)
+                            .get(0);
                     responsePayload = mAclManager.addAclSubscriber(aclid, di,
-                        srcDevice, request);
+                            srcDevice, request);
                     break;
                 case UNSUBSCRIBE:
-                    di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID).get(0);
-                    responsePayload = mAclManager.removeAclSubscriber(aclid, di);
+                    di = request.getUriQueryMap().get(Constants.REQ_DEVICE_ID)
+                            .get(0);
+                    responsePayload = mAclManager.removeAclSubscriber(aclid,
+                            di);
                     break;
                 default:
                     throw new BadRequestException(request.getObserve()
@@ -160,21 +170,28 @@ public class AclResource extends Resource {
         String aclid = null;
 
         if (getUriPathSegments().containsAll(request.getUriPathSegments())) {
-            aclid = request.getUriQueryMap().get(Constants.REQ_ACL_ID)
-                .get(0);
+            aclid = request.getUriQueryMap().get(Constants.REQ_ACL_ID).get(0);
             if (aclid == null) {
-                throw new PreconditionFailedException(
-                    "aclid is invalid");
+                throw new PreconditionFailedException("aclid is invalid");
             }
             mAclManager.deleteAcl(aclid);
         } else {
-            aclid = request.getUriPathSegments().get(getUriPathSegments().size());
-            String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0);
-            if (aceid == null) {
+            aclid = request.getUriPathSegments()
+                    .get(getUriPathSegments().size());
+
+            if (request.getUriQueryMap() == null)
+            {
                 mAclManager.deleteAclAclist(aclid);
-            } else {
+            }
+            else if (request.getUriQueryMap()
+                    .containsKey(Constants.REQ_ACE_ID)) {
+                String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID)
+                        .get(0);
                 mAclManager.deleteAclACE(aclid, aceid);
             }
+            else {
+                throw new BadRequestException("uriPath is invalid");
+            }
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
index ca64b12..27bd56c 100644 (file)
@@ -23,11 +23,13 @@ package org.iotivity.cloud.accountserver.resources.acl.invite;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.InviteTable;
+import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.base.device.Device;
 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
@@ -42,7 +44,6 @@ import org.iotivity.cloud.util.Cbor;
  * This class provides a set of APIs to invite a user to a group
  *
  */
-
 public class InviteManager {
 
     private TypeCastingManager<InviteTable> mTypeInvite = new TypeCastingManager<>();
@@ -57,8 +58,19 @@ public class InviteManager {
         public IRequest mRequest;
     }
 
-    private HashMap<String, InviteSubscriber> mSubscribers = new HashMap<>();
-
+    // <uid, subscriber list>
+    private HashMap<String, ArrayList<InviteSubscriber>> mSubscribers = new HashMap<>();
+
+    /**
+     * API to add invitation
+     * 
+     * @param uid
+     *            id of user who sent invitation
+     * @param gid
+     *            id of group to invite member to
+     * @param mid
+     *            id of invited user
+     */
     public void addInvitation(String uid, String gid, String mid) {
 
         // create invitation table
@@ -78,7 +90,17 @@ public class InviteManager {
         }
     }
 
-    public void deleteInvitation(String mid, String gid) {
+    /**
+     * API to delete invitation by invited user
+     * 
+     * @param mid
+     *            id of invited user
+     * @param gid
+     *            id of group which the user was invited to
+     * @param accepted
+     *            value of invitation accept or deny
+     */
+    public void deleteInvitation(String mid, String gid, boolean accepted) {
         HashMap<String, Object> condition = new HashMap<>();
         condition.put(Constants.REQ_GROUP_ID, gid);
         condition.put(Constants.KEYFIELD_INVITED_USER, mid);
@@ -98,12 +120,31 @@ public class InviteManager {
         AccountDBManager.getInstance().deleteRecord(Constants.INVITE_TABLE,
                 condition);
 
+        /* add user into group */
+        if (accepted) {
+
+            HashSet<String> midlist = new HashSet<String>();
+            midlist.add(mid);
+
+            GroupManager.getInstance().addGroupMember(gid, midlist);
+        }
+
         notifyToSubscriber(mid);
         for (String uid : uidList) {
             notifyToSubscriber(uid);
         }
     }
 
+    /**
+     * API to cancel invitation by user who invited member
+     * 
+     * @param uid
+     *            id of user who sent invitation
+     * @param gid
+     *            id of group to invite member to
+     * @param mid
+     *            id of invited user
+     */
     public void cancelInvitation(String uid, String gid, String mid) {
 
         HashMap<String, Object> condition = new HashMap<>();
@@ -119,6 +160,14 @@ public class InviteManager {
         notifyToSubscriber(mid);
     }
 
+    /**
+     * API to get invitation information
+     * 
+     * @param uid
+     *            user id
+     * 
+     * @return returns invite and invited information of the user
+     */
     public HashMap<String, Object> getInvitationInfo(String uid) {
         HashMap<String, Object> responsePayload = new HashMap<>();
 
@@ -157,20 +206,57 @@ public class InviteManager {
         return responsePayload;
     }
 
+    /**
+     * API to add subscriber of invite resource
+     * 
+     * @param uid
+     *            user id
+     * @param subscriber
+     *            device that sent request for subscription
+     * @param request
+     *            received request for subscription
+     * 
+     * @return returns invite and invited information of the user
+     */
     public HashMap<String, Object> addSubscriber(String uid, Device subscriber,
             IRequest request) {
 
         InviteSubscriber newSubscriber = new InviteSubscriber(subscriber,
                 request);
-        mSubscribers.put(uid, newSubscriber);
+
+        synchronized (mSubscribers) {
+            ArrayList<InviteSubscriber> subscriberList = mSubscribers.get(uid);
+
+            if (subscriberList == null) {
+                subscriberList = new ArrayList<>();
+            }
+
+            subscriberList.add(newSubscriber);
+            mSubscribers.put(uid, subscriberList);
+        }
 
         return getInvitationInfo(uid);
     }
 
-    public HashMap<String, Object> removeSubscriber(String uid) {
+    /**
+     * API to remove subscriber of invite resource
+     * 
+     * @param uid
+     *            user id
+     * @param request
+     *            received request for unsubscription
+     * 
+     * @return returns invite and invited information of the user
+     */
+    public HashMap<String, Object> removeSubscriber(String uid,
+            IRequest request) {
+
+        synchronized (mSubscribers) {
+            if (mSubscribers.containsKey(uid)) {
 
-        if (mSubscribers.containsKey(uid)) {
-            mSubscribers.remove(uid);
+                mSubscribers.get(uid).removeIf(subscriber -> subscriber.mRequest
+                        .getRequestId().equals(request.getRequestId()));
+            }
         }
 
         return getInvitationInfo(uid);
@@ -182,12 +268,17 @@ public class InviteManager {
             if (!mSubscribers.containsKey(id)) {
                 return;
             }
+
             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
-            mSubscribers.get(id).mSubscriber.sendResponse(
-                    MessageBuilder.createResponse(mSubscribers.get(id).mRequest,
-                            ResponseStatus.CONTENT,
-                            ContentFormat.APPLICATION_CBOR,
-                            cbor.encodingPayloadToCbor(getInvitationInfo(id))));
+            byte[] payload = cbor.encodingPayloadToCbor(getInvitationInfo(id));
+
+            for (InviteSubscriber subscriber : mSubscribers.get(id)) {
+
+                subscriber.mSubscriber.sendResponse(
+                        MessageBuilder.createResponse(subscriber.mRequest,
+                                ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR, payload));
+            }
         }
     }
 
@@ -213,4 +304,4 @@ public class InviteManager {
 
     }
 
-}
+}
\ No newline at end of file
index 080e685..d018924 100644 (file)
@@ -39,12 +39,21 @@ import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ * 
+ * This class provides a set of APIs to handle requests to Invite resource.
+ *
+ */
 public class InviteResource extends Resource {
 
     private InviteManager                 mInviteManager = new InviteManager();
 
     private Cbor<HashMap<String, Object>> mCbor          = new Cbor<>();
 
+    private enum ReqType {
+        NONE, CANCEL_INVITATION, DELETE_INVITATION
+    };
+
     public InviteResource() {
         super(Arrays.asList(Constants.PREFIX_OIC, Constants.ACL_URI,
                 Constants.INVITE_URI));
@@ -92,7 +101,7 @@ public class InviteResource extends Resource {
                         request);
                 break;
             case UNSUBSCRIBE:
-                responsePayload = mInviteManager.removeSubscriber(uid);
+                responsePayload = mInviteManager.removeSubscriber(uid, request);
                 break;
             default:
                 break;
@@ -149,11 +158,32 @@ public class InviteResource extends Resource {
         String gid = queryParams.get(Constants.REQ_GROUP_ID).get(0);
         String uid = queryParams.get(Constants.REQ_UUID_ID).get(0);
 
+        ReqType reqType = ReqType.NONE;
         if (queryParams.get(Constants.REQ_MEMBER) == null) {
-            mInviteManager.deleteInvitation(uid, gid);
+            reqType = ReqType.DELETE_INVITATION;
         } else {
+            reqType = ReqType.CANCEL_INVITATION;
+        }
+
+        if (reqType.equals(ReqType.DELETE_INVITATION)) {
+
+            String acceptStr = queryParams.get(Constants.REQ_INVITE_ACCEPT)
+                    .get(0);
+            boolean accepted = false;
+            if (acceptStr.equals(Constants.INVITE_ACCEPT)) {
+                accepted = true;
+            }
+
+            mInviteManager.deleteInvitation(uid, gid, accepted);
+
+        } else if (reqType.equals(ReqType.CANCEL_INVITATION)) {
+
             String mid = queryParams.get(Constants.REQ_MEMBER).get(0);
             mInviteManager.cancelInvitation(uid, gid, mid);
+
+        } else {
+
+            throw new BadRequestException("queryData is not enough");
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
index 87cb960..0ad3011 100644 (file)
@@ -72,7 +72,7 @@ public class AclVerifyResource extends Resource {
     private boolean checkResourceUri(List<AceResource> aceResources, String uri)
         throws ServerException {
             for (AceResource aceResource : aceResources) {
-                if (aceResource.getHref().equals(uri)) {
+                if (aceResource.getHref().trim().equals("*") || aceResource.getHref().equals(uri)) {
                     return true;
                 }
             }
@@ -97,12 +97,13 @@ public class AclVerifyResource extends Resource {
             for (HashMap<String, Object> eachAclMap : aclResult) {
 
                 AclTable aclTable = Acl.convertMaptoAclObject(eachAclMap);
-                if (aclTable.getAclist() == null) {
-                    return false;
-                }
                 if (aclTable.getOid().equals(sid)) {
                     return true;
                 }
+                if (aclTable.getAclist() == null) {
+                    return false;
+                }
+
                 for (Ace ace : aclTable.getAclist()) {
                     if (ace.getSubjectuuid().equals(sid)) {
                         // check permission matches
index 68d6fb3..4ba157a 100644 (file)
@@ -45,46 +45,96 @@ import static java.security.cert.CertificateFactory.getInstance;
  */
 public final class CertificateConstants {
 
+    /**
+     * Properties object is used for loading pre-defined configurations: algorithm names and so on.
+     */
     public static final Properties PROPERTIES = new Properties();
 
     /**
      * Load properties from specified properties file.
      */
     static {
-        try {
-            PROPERTIES.load(new FileInputStream(Constants.PROPERTIES_FILE_NAME));
+        try (FileInputStream inputStream = new FileInputStream(Constants.PROPERTIES_FILE_NAME)) {
+            PROPERTIES.load(inputStream);
         } catch (IOException e) {
             Log.e(e.getMessage());
         }
     }
 
+    /**
+     * Base 64 encoding constant for comparing request encoding.
+     */
     public static final String BASE_64 = "oic.sec.encoding.base64";
 
+    /**
+     * Der encoding constant for comparing request encoding.
+     */
     public static final String DER = "oic.sec.encoding.der";
 
+    /**
+     * Name of security provider, load from properties.
+     */
     public static final String SECURITY_PROVIDER = PROPERTIES.getProperty("securityProvider");
 
+    /**
+     * Not after interval for X509Certificate generation, load from properties.
+     */
     public static final String NOT_AFTER_INTERVAL = PROPERTIES.getProperty("notAfterInterval");
 
+    /**
+     * Next Update interval. is used for generation X509CRL, load from properties.
+     */
     public static final String NEXT_UPDATE_INTERVAL = PROPERTIES.getProperty("nextUpdateInterval");
 
+    /**
+     * Signature algorithm, is used for signing certificates and CRLs, load from properties.
+     */
     public static final String SIGNATURE_ALGORITHM = PROPERTIES.getProperty("signatureAlgorithm");
 
+    /**
+     * KeyStore type, is used for private key storage and for root certificate storage
+     */
     static final String KEYSTORE_TYPE = PROPERTIES.getProperty("keystoreType");
 
+    /**
+     * CA Alias name, is used for storing ca certificate to key storage.
+     */
     static final String CA_ALIAS = PROPERTIES.getProperty("caAlias");
 
+    /**
+     * Curve name, is used in signing algorithm for X509 certificate generation.
+     */
     static final String CURVE = PROPERTIES.getProperty("ellipticCurve");
 
+    /**
+     * Key generation algorithm is used for generation private and public keys.
+     */
     static final String KEY_GENERATOR_ALGORITHM = PROPERTIES.getProperty("keyGeneratorAlgorithm");
 
+    /**
+     * Date format, is used to parse date with UTC TIME format for certificate and CRL generation.
+     */
     public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
 
+    /**
+     * String constant is used to create keystore directory.
+     */
+    public static final String KEYSTORE_DIR = PROPERTIES.getProperty("keystoreDir");
+
+    /**
+     * X500Name for ca issuer, is used for issuing personal certificates and CRLs.
+     */
     public static final X500Name CA_ISSUER = Utility.getName(PROPERTIES.getProperty("subjectName"),
             PROPERTIES.getProperty("rootC"), PROPERTIES.getProperty("rootO"), PROPERTIES.getProperty("rootOU"));
 
+    /**
+     * Shared AccountDBManager to get rid of repeatable links on the same object.
+     */
     public static final AccountDBManager ACCOUNT_DB_MANAGER = AccountDBManager.getInstance();
 
+    /**
+     * Certificate factory is used during certificate generation process.
+     */
     public static CertificateFactory CERTIFICATE_FACTORY;
 
     static {
@@ -96,25 +146,29 @@ public final class CertificateConstants {
     }
 
     /**
-     * Path to keystore file
+     * Path to keystore file, retrieved from properties file.
      */
     public static final File KEYSTORE_FILE = new File(MessageFormat.
             format(PROPERTIES.getProperty("keyStoreLocation"), File.separator));
 
     /**
      * Set specified value for specified property.
+     *
      * @param property specified property
-     * @param value specified property value.
+     * @param value    specified property value.
      */
     public static void set(String property, String value) {
         PROPERTIES.setProperty(property, value);
-        try {
-            PROPERTIES.store(new FileOutputStream(Constants.PROPERTIES_FILE_NAME), "New Serial number");
+        try (FileOutputStream outputStream = new FileOutputStream(Constants.PROPERTIES_FILE_NAME)) {
+            PROPERTIES.store(outputStream, "New Serial number");
         } catch (IOException e) {
             Log.e(e.getMessage());
         }
     }
 
+    /**
+     * Private constructor makes class non-instantiable utility class.
+     */
     private CertificateConstants() {
         throw new AssertionError();
     }
index bb36946..8bb7d53 100644 (file)
@@ -31,17 +31,15 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static org.iotivity.cloud.accountserver.Constants.CERTIFICATE_TABLE;
-import static org.iotivity.cloud.accountserver.Constants.KEYFIELD_DID;
-import static org.iotivity.cloud.accountserver.Constants.KEYFIELD_REVOKED;
+import static org.iotivity.cloud.accountserver.Constants.*;
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.ACCOUNT_DB_MANAGER;
 
 
 /**
  * This class is used as DB manager for CertificateTable.
  * With help of this class we can save certificate info to DB,
- * retrieve it from DB by specified in constructor device id,
- * updateX509CRL certificate, also it helps us get user Id from Token
+ * retrieve it from DB by specified device id,
+ * update X509 certificate, also it helps us to get user Id from Token
  * Table by specified device id.
  */
 final class CertificateManager {
@@ -63,7 +61,9 @@ final class CertificateManager {
     private final String deviceId;
 
     /**
-     * Constructs certificateMananger with specified device id.
+     * Constructs certificateMananger with specified device id. Initialize payload
+     * as new hash map instance.
+     *
      * @param deviceId specified device identifier for this CertificateManager.
      */
     CertificateManager(String deviceId) {
@@ -79,33 +79,34 @@ final class CertificateManager {
     }
 
     /**
-     * Puts for specified key, specified value to
-     * object payload;
-     * @param key specified key value
-     * @param value specified value
+     * Puts specified value for specified key to payload;
+     *
+     * @param key   specified String key value
+     * @param value specified Object value
      */
     public void put(String key, Object value) {
         payLoad.put(key, value);
     }
 
     /**
-     * Saves new certificate to DB with specified columns.
+     * Saves certificate information: serial number, not after, to DB with specified columns.
      *
      * @param serialNumber specified certificate serial number
-     * @param notAfter validation date not after
-     * @param notBefore validation date not before
+     * @param notAfter     validation date not after
+     * @param notBefore    validation date not before
      */
     void save(BigInteger serialNumber, Date notAfter, Date notBefore) {
         ACCOUNT_DB_MANAGER.insertRecord(CERTIFICATE_TABLE,
                 CERTIFICATE_TABLE_TYPE_CASTING_MANAGER.convertObjectToMap(
                         new CertificateTable(serialNumber.toString(), notAfter,
-                        notBefore, deviceId, Utility.getUserID(deviceId), false)));
+                                notBefore, deviceId, Utility.getUserID(deviceId), false)));
     }
 
     /**
-     * Updates certificate table with specified revoked column.
+     * Updates certificate table by revoked column.
+     *
      * @param certificateTable certificate to be updated.
-     * @param revoked specified value for revoke
+     * @param revoked          specified value for revoke
      */
     void update(CertificateTable certificateTable, boolean revoked) {
         certificateTable.setRevoked(revoked);
@@ -114,8 +115,8 @@ final class CertificateManager {
     }
 
     /**
-     * Returns certificate from database, according to specified
-     * device id
+     * Returns certificate from database for specified in constructor
+     * device id.
      */
     public CertificateTable getCertificate() {
         HashMap<String, Object> condition = new HashMap<>();
@@ -123,7 +124,7 @@ final class CertificateManager {
         condition.put(KEYFIELD_REVOKED, false);
         List<HashMap<String, Object>> listMap = ACCOUNT_DB_MANAGER.selectRecord(
                 CERTIFICATE_TABLE, condition);
-        if (!listMap.isEmpty()) {
+        if (listMap != null && !listMap.isEmpty()) {
             return CERTIFICATE_TABLE_TYPE_CASTING_MANAGER
                     .convertMaptoObject(
                             listMap.get(0),
@@ -132,4 +133,4 @@ final class CertificateManager {
             return null;
         }
     }
-}
+}
\ No newline at end of file
index e7113d5..13bf1d5 100644 (file)
@@ -49,6 +49,7 @@ import org.iotivity.cloud.util.Log;
 
 import java.io.IOException;
 import java.security.GeneralSecurityException;
+import java.security.PublicKey;
 import java.security.Security;
 import java.security.cert.CRLException;
 import java.security.cert.X509Certificate;
@@ -77,15 +78,8 @@ public class CertificateResource extends Resource {
     private static final Cbor<Map<String, Object>> MAP_CBOR = new Cbor<>();
 
     /**
-     * Constructs certificate resourcewith specified prefixes
-     */
-    public CertificateResource() {
-        super(Arrays.asList(PREFIX_OIC, CREDPROV_URI, CERT_URI));
-    }
-
-    /**
-     * Insert BouncyCastleProvider into 0 position in security provider list.
-     * Init KeyStore, Generate CA certificate and save it to keyStore.
+     * Inserts BouncyCastleProvider into 0 position in security provider list,
+     * inits KeyStore, generates CA certificate and saves it to keyStore.
      */
     static {
         Security.insertProviderAt(new BouncyCastleProvider(), 0);
@@ -100,6 +94,13 @@ public class CertificateResource extends Resource {
         }
     }
 
+    /**
+     * Constructs certificate resource with specified prefixes.
+     */
+    public CertificateResource() {
+        super(Arrays.asList(PREFIX_OIC, CREDPROV_URI, CERT_URI));
+    }
+
     @Override
     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
             throws ServerException {
@@ -115,70 +116,106 @@ public class CertificateResource extends Resource {
     }
 
     /**
-     * Handles post requests to this resource
+     * Handles post requests to Certificate Resource.
+     * Request should be with specified format
+     * POST /oic/credprov/cert
+     * {
+     *      “di” : “11-22-xx”,
+     *      “csr” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CSR Binary>”
+     *      }
+     * }
+     * Method checks encoding, and decodes data by specified encoding if needed.
+     *
+     * Method issus a certificate including User UUID in extension field,
+     * stores issuing information (serial number, validity, device uuid, user uuid) for management (e.g. re-issue).
+     * Response should be in next format for example:
+     * 2.04 CHANGED
+     * {
+     *      “di” : “1111-22-xx”,
+     *      “cert” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded Cert. Binary>”
+     *       },
+     *      “certchain” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CA Cert. chain>”
+     *       }
+     * }
+     * or returns BAD_REQUEST: 4.0.1 if any exceptions occured.
+     *
      * @param request request with payload information.
      * @throws ServerException
      */
     private IResponse handlePostRequest(IRequest request)
             throws ServerException {
-        Map<String, Object> payloadData = MAP_CBOR
-                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+        byte[] requestPayload = request.getPayload();
         IResponse response = MessageBuilder.createResponse(request, ResponseStatus.BAD_REQUEST);
-        Object csr = payloadData.get(Constants.REQ_CSR);
-        if (csr != null && csr instanceof Map) {
-            Object encoding =((Map<String, Object>)csr).get(ENCODING);
-            Object data = ((Map<String, Object>)csr).get(DATA);
-            if (encoding != null && encoding instanceof String && data != null && data instanceof byte[]) {
-                byte[] csrData = (byte[]) data;
-                if (encoding.equals(BASE_64)) {
-                    csrData = Base64.decode(csrData);
-                }
-                try {
-                    CSRParser parser = new CSRParser(csrData);
-                    String commonName = parser.getCommonName();
-                    String pattern = "^uuid:(.*)$";
-                    Pattern r = Pattern.compile(pattern);
-                    Matcher m = r.matcher(commonName);
-                    String deviceId = (String) payloadData.get(RESP_DEVICE_ID);
-                    if (m.find() && m.group(1).equals(deviceId) && parser.isSignatureValid()) {
-                        CertificateManager certificateManager = new CertificateManager(deviceId);
-                        CertificateTable certificateTable = certificateManager.getCertificate();
-                        if (certificateTable != null) {
-                            try {
-                                CrlManager.CRL_MANAGER.revoke(certificateTable.getSerialNumber());
-                            } catch (CRLException | OperatorCreationException e) {
-                                Log.e(e.getMessage() + e.getClass());
-                            }
-                            certificateManager.update(certificateTable, true);
+        if (requestPayload != null) {
+            Map<String, Object> payloadData = MAP_CBOR
+                    .parsePayloadFromCbor(requestPayload, HashMap.class);
+            if (payloadData != null) {
+                Object csr = payloadData.get(Constants.REQ_CSR);
+                if (csr != null && csr instanceof Map) {
+                    Object encoding = ((Map<String, Object>) csr).get(ENCODING);
+                    Object data = ((Map<String, Object>) csr).get(DATA);
+                    if (encoding != null && encoding instanceof String && data != null && data instanceof byte[]) {
+                        byte[] csrData = (byte[]) data;
+                        if (encoding.equals(BASE_64)) {
+                            csrData = Base64.decode(csrData);
                         }
-                        CertificateExtension extension = new CertificateExtension(Extension.subjectAlternativeName,
-                                false, new DERSequence(new ASN1Encodable[]
-                                {new GeneralName(GeneralName.dNSName, Constants.KEYFIELD_USERID + ":" +
-                                        Utility.getUserID(deviceId))}));
-                        CertificateBuilder certBuilder = new CertificateBuilder(parser.getSubject(),
-                                parser.getPublicKey(), extension );
                         try {
-                            X509Certificate personal = certBuilder.build();
-                            byte[] encodedCert = personal.getEncoded();
-                            byte[] encodedCa = CertificateStorage.ROOT_CERTIFICATE.getEncoded();
-                            if (encoding.equals(CertificateConstants.BASE_64)) {
-                                encodedCert = Base64.encode(encodedCert);
-                                encodedCa =  Base64.encode(encodedCa);
+                            CSRParser parser = new CSRParser(csrData);
+                            String commonName = parser.getCommonName();
+                            String pattern = "^uuid:(.*)$";
+                            Pattern r = Pattern.compile(pattern);
+                            Matcher m = r.matcher(commonName);
+                            String deviceId = (String) payloadData.get(RESP_DEVICE_ID);
+                            if (m.find() && m.group(1).equals(deviceId) && parser.isSignatureValid()) {
+                                CertificateManager certificateManager = new CertificateManager(deviceId);
+                                CertificateTable certificateTable = certificateManager.getCertificate();
+                                if (certificateTable != null) {
+                                    try {
+                                        CrlManager.CRL_MANAGER.revoke(certificateTable.getSerialNumber());
+                                    } catch (CRLException | OperatorCreationException e) {
+                                        Log.e(e.getMessage() + e.getClass());
+                                    }
+                                    certificateManager.update(certificateTable, true);
+                                }
+                                PublicKey publicKey = parser.getPublicKey();
+                                if (publicKey != null) {
+                                    CertificateExtension extension = new CertificateExtension(Extension.subjectAlternativeName,
+                                            false, new DERSequence(new ASN1Encodable[]
+                                            {new GeneralName(GeneralName.dNSName, Constants.KEYFIELD_USERID + ":" +
+                                                    Utility.getUserID(deviceId))}));
+                                    CertificateBuilder certBuilder = new CertificateBuilder(parser.getSubject(),
+                                            publicKey, extension);
+                                    try {
+                                        X509Certificate personal = certBuilder.build();
+                                        byte[] encodedCert = personal.getEncoded();
+                                        byte[] encodedCa = CertificateStorage.ROOT_CERTIFICATE.getEncoded();
+                                        if (encoding.equals(CertificateConstants.BASE_64)) {
+                                            encodedCert = Base64.encode(encodedCert);
+                                            encodedCa = Base64.encode(encodedCa);
+                                        }
+                                        certificateManager.put(Constants.RESP_DEVICE_ID, deviceId);
+                                        certificateManager.put(Constants.CERT, new CSR(encoding.toString(), encodedCert));
+                                        certificateManager.put(Constants.CERT_CHAIN, new CSR(encoding.toString(), encodedCa));
+                                        certificateManager.save(personal.getSerialNumber(), personal.getNotAfter(),
+                                                personal.getNotBefore());
+                                        response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                                                ContentFormat.APPLICATION_CBOR,
+                                                MAP_CBOR.encodingPayloadToCbor(certificateManager.getPayLoad()));
+                                    } catch (GeneralSecurityException | OperatorCreationException | CertIOException e) {
+                                        Log.e(e.getMessage());
+                                    }
+                                }
                             }
-                            certificateManager.put(Constants.RESP_DEVICE_ID, deviceId);
-                            certificateManager.put(Constants.CERT, new CSR(encoding.toString(), encodedCert));
-                            certificateManager.put(Constants.CERT_CHAIN,  new CSR(encoding.toString(), encodedCa));
-                            certificateManager.save(personal.getSerialNumber(), personal.getNotBefore(),
-                                    personal.getNotAfter());
-                            response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
-                                    ContentFormat.APPLICATION_CBOR,
-                                    MAP_CBOR.encodingPayloadToCbor(certificateManager.getPayLoad()));
-                        } catch (GeneralSecurityException | OperatorCreationException | CertIOException e) {
+                        } catch (IOException e) {
                             Log.e(e.getMessage());
                         }
                     }
-                } catch (IOException e) {
-                    Log.e(e.getMessage());
                 }
             }
         }
@@ -186,7 +223,7 @@ public class CertificateResource extends Resource {
     }
 
     /**
-     * This class is used for response
+     * Response utility class.
      */
     private static final class CSR {
 
@@ -199,10 +236,16 @@ public class CertificateResource extends Resource {
             this.data = data;
         }
 
+        /**
+         * Return encoding.
+         */
         public String getEncoding() {
             return encoding;
         }
 
+        /**
+         * Retrieves data.
+         */
         public byte[] getData() {
             return data;
         }
index f632a20..9363549 100644 (file)
@@ -23,12 +23,11 @@ package org.iotivity.cloud.accountserver.resources.credprov.cert;
 
 import org.bouncycastle.asn1.x509.BasicConstraints;
 import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.cert.CertIOException;
 import org.bouncycastle.jce.ECNamedCurveTable;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.operator.OperatorCreationException;
 import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
 import org.iotivity.cloud.accountserver.x509.cert.CertificateExtension;
+import org.iotivity.cloud.util.Log;
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -42,6 +41,10 @@ import java.security.cert.X509Certificate;
 
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
 
+/**
+ * This class is used for loading and storing key store.
+ * Also it generates CA certificate and puts it to keystore.
+ */
 public final class CertificateStorage {
 
     /**
@@ -51,78 +54,62 @@ public final class CertificateStorage {
     private static final String PASSWORD = PROPERTIES.getProperty("password");
 
     /**
-     * Keystore object for save, get data from keystore.
+     * Root private key is used for signing certificates ans CRLs.
      */
-    private static KeyStore keyStore;
-
     public static PrivateKey ROOT_PRIVATE_KEY;
 
-    public static X509Certificate ROOT_CERTIFICATE;
-
-    private CertificateStorage() {
-        throw new AssertionError();
-    }
-
     /**
-     * Init KeyStore. If it does not exists, create it and push to KEYSTORE_FILE.
+     * Root certificate, is used for isssuing low level certificates.
      */
-    static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
-        Files.createDirectories(Paths.get("keystore"));
-        keyStore = load(null, null);
-        store();
-        CertificateStorage.generateCACertificate();
-        CertificateStorage.saveCertificatePrivateKey();
-    }
+    public static X509Certificate ROOT_CERTIFICATE;
 
     /**
-     * Load KeyStore with default keystore file and password.
-     *
-     * @return KeyStore instance.
+     * Keystore object to save, retrieve ca private key and ca certificate from keystore.
      */
-    public static void load() throws GeneralSecurityException, IOException {
-        keyStore = load(new FileInputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
-        initRoot();
-    }
+    private static KeyStore keyStore;
 
     /**
-     * Loads KeyStore with defined inputStream object and password.
-     *
-     * @param is       specified inputStream which contains keystore bytes.
-     * @param password specified password for opening keystore.
-     * @return KeyStore instance.
+     * Private contructor to make this class non-instantiable.
      */
-    private static KeyStore load(InputStream is, char[] password) throws IOException, GeneralSecurityException {
-        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
-        keyStore.load(is, password);
-        return keyStore;
+    private CertificateStorage() {
+        throw new AssertionError();
     }
 
-
     /**
-     * Stores keyStore to default file KEYSTORE_FILE with default password.
+     * Loads keystore with null paramaters.
+     * Stores it empty version. Generates CA certificate and private key and
+     * saves it to key storage.
      */
-    static void store() throws IOException, GeneralSecurityException {
-        store(keyStore, new FileOutputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
+    static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
+        Files.createDirectories(Paths.get(KEYSTORE_DIR));
+        keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
+        keyStore.load(null, null);
+        generate();
     }
 
     /**
-     * Stores KeyStore to file outputstream with specifie password.
+     * Loads KeyStore intance from created keystore file and with default password.
      *
-     * @param keyStore
+     * @return KeyStore instance.
      */
-    private static void store(KeyStore keyStore, FileOutputStream out, char[] password) throws GeneralSecurityException,
-            IOException {
-        keyStore.store(out, password);
-        out.close();
+    static void load() throws GeneralSecurityException, IOException {
+        keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
+        try (InputStream inputStream = new FileInputStream(KEYSTORE_FILE)) {
+            keyStore.load(inputStream, PASSWORD.toCharArray());
+        } catch (IOException ioException) {
+            Log.e(ioException.getMessage());
+        }
+        ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
+        ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
     }
 
     /**
-     * Generates X509Certificate  with PublicKey and PrivateKey
+     * Generates CA X509Certificate and private key and stores it to key storage.
      *
      * @return certificate and private key
      */
-    private static void generateCACertificate() throws GeneralSecurityException,
-            OperatorCreationException, CertIOException {
+    private static void generate() throws GeneralSecurityException,
+            OperatorCreationException, IOException {
         if (ROOT_PRIVATE_KEY == null) {
             KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, SECURITY_PROVIDER);
             g.initialize(ECNamedCurveTable.getParameterSpec(CURVE), new SecureRandom());
@@ -131,21 +118,21 @@ public final class CertificateStorage {
             ROOT_CERTIFICATE = new CertificateBuilder(CA_ISSUER, pair.getPublic(),
                     new CertificateExtension(Extension.basicConstraints, false,
                             new BasicConstraints(true))).build();
+            keyStore.setCertificateEntry(CA_ALIAS, ROOT_CERTIFICATE);
+            keyStore.setKeyEntry(CA_ALIAS, ROOT_PRIVATE_KEY, PASSWORD.toCharArray(),
+                    new Certificate[]{ROOT_CERTIFICATE});
+            store();
         }
     }
 
     /**
-     * Stores certificate and private key to keystore.
+     * Stores keyStore instance to default keystore file with default password.
      */
-    private static void saveCertificatePrivateKey() throws GeneralSecurityException, IOException {
-        keyStore.setCertificateEntry(CA_ALIAS, ROOT_CERTIFICATE);
-        keyStore.setKeyEntry(CA_ALIAS, ROOT_PRIVATE_KEY, PASSWORD.toCharArray(),
-                new Certificate[]{ROOT_CERTIFICATE});
-        store();
-    }
-
-    private static void initRoot() throws GeneralSecurityException {
-        ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
-        ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
+    private static void store() throws IOException, GeneralSecurityException {
+        try (FileOutputStream out = new FileOutputStream(KEYSTORE_FILE)) {
+            keyStore.store(out, PASSWORD.toCharArray());
+        } catch (IOException ioException) {
+            Log.e(ioException.getMessage());
+        }
     }
 }
index d6d0f6a..ca61263 100644 (file)
@@ -40,55 +40,80 @@ import static org.iotivity.cloud.accountserver.resources.credprov.cert.Certifica
 import static org.iotivity.cloud.accountserver.x509.crl.CrlIssuer.CRL_ISSUER;
 
 /**
- * Class is used for managing CRLs(creation, revoke, update)
+ * Class is used to manage CRLs. It helps to create,
+ * update CRLS, revoke certificates.
  */
 public final class CrlManager {
 
     /**
-     * Static manager for CRLs.
-     */
-    public static CrlManager CRL_MANAGER;
-    /**
      * Casting manager for working with CRLTable in mongo db
      */
     private static TypeCastingManager<CRLTable> castingManager = new TypeCastingManager<>();
 
-    static {
-        try {
-            CRL_MANAGER = new CrlManager();
-            CRL_MANAGER.init();
-        } catch (CRLException | IOException | OperatorCreationException e) {
-            Log.e(e.getMessage());
-        }
-    }
-
     /**
      * X509 CRL presentation.
      */
     private X509CRL x509CRL;
 
+    /**
+     * Static manager for CRLs.
+     */
+    public static final CrlManager CRL_MANAGER = new CrlManager();
+
+    /**
+     * Private constructor to make this class non-instantiable.
+     */
     private CrlManager() {
+        try {
+            Calendar calendar = Calendar.getInstance();
+            Date thisUpdate = calendar.getTime();
+            calendar.add(Calendar.DAY_OF_MONTH,
+                    Integer.parseInt(NEXT_UPDATE_INTERVAL));
+            byte[] data = CRL_ISSUER.generate(thisUpdate, calendar.getTime(), Collections.emptyList());
+            ACCOUNT_DB_MANAGER.insertRecord(Constants.CRL_TABLE,
+                    castingManager.convertObjectToMap(new CRLTable(thisUpdate, new Binary(data))));
+            setX509CRL(data);
+        } catch (CRLException | IOException | OperatorCreationException e) {
+            Log.e(e.getMessage());
+        }
     }
 
     /**
-     * Revokes specified serial numbers.
+     * Revokes specified serial numbers. Puts them to database.
      *
-     * @param serialNumber specified var args serial numbers from 0.
+     * @param serialNumbers specified var args serial numbers from 0.
      */
-    public void revoke(String... serialNumber) throws CRLException, IOException, OperatorCreationException {
+    public void revoke(String... serialNumbers) throws CRLException, IOException, OperatorCreationException {
         if (x509CRL != null) {
             update(x509CRL.getThisUpdate(),
                     CRL_ISSUER.generate(x509CRL.getThisUpdate(), x509CRL.getNextUpdate(),
-                            x509CRL.getRevokedCertificates(), serialNumber));
+                            x509CRL.getRevokedCertificates(), serialNumbers));
         }
     }
 
     /**
-     * Check if last update is before CRL this update.
+     * Checks last update less than crl this update and returns response payload,
+     * including this update, next update, and CRL in DER encoding.
+     */
+    Map<String, Object> getPayload(String lastUpdate) throws ServerException.PreconditionFailedException, CRLException {
+        if (checkLastUpdate(lastUpdate) && x509CRL != null) {
+            Map<String, Object> responsePayload = new HashMap<>();
+            responsePayload.put(Constants.REQ_THIS_UPDATE, DATE_FORMAT.format(x509CRL.getThisUpdate()));
+            responsePayload.put(Constants.REQ_NEXT_UPDATE, DATE_FORMAT.format(x509CRL.getNextUpdate()));
+            responsePayload.put(Constants.REQ_CRL, new CRL(DER, x509CRL.getEncoded()));
+            return responsePayload;
+        }
+        return Collections.emptyMap();
+    }
+
+
+    /**
+     * Checks if last update is before CRL this update.
+     *
      * @param lastUpdate specified last update;
      * @return true if before and false - otherwise.
      */
-    boolean checkLastUpdate(String lastUpdate) {
+    private boolean checkLastUpdate(String lastUpdate) {
         boolean checkCondition = false;
         try {
             if (x509CRL != null) {
@@ -100,44 +125,20 @@ public final class CrlManager {
         return checkCondition;
     }
 
-    /**
-     * Returns response payload, including this update, next update, and CRL in DER encoding.
-     */
-    Map<String, Object> getPayload() throws ServerException.PreconditionFailedException, CRLException {
-        if (x509CRL != null) {
-            Map<String, Object> responsePayload = new HashMap<>();
-            responsePayload.put(Constants.REQ_THIS_UPDATE, DATE_FORMAT.format(x509CRL.getThisUpdate()));
-            responsePayload.put(Constants.REQ_NEXT_UPDATE, DATE_FORMAT.format(x509CRL.getNextUpdate()));
-            responsePayload.put(Constants.REQ_CRL, new CRL(DER, x509CRL.getEncoded()));
-            return responsePayload;
-        }
-        return Collections.emptyMap();
-    }
 
     /**
      * Updates CRLTable with specified this update and binary CRL data.
      */
     void update(Date thisUpdate, byte[] data) throws CRLException {
-        CRLTable crlTable = castingManager.convertMaptoObject(
-                ACCOUNT_DB_MANAGER.selectRecord(Constants.CRL_TABLE, new HashMap<>()).get(0), new CRLTable());
-        crlTable.setThisUpdate(thisUpdate);
-        crlTable.setBinaryData(new Binary(data));
-        ACCOUNT_DB_MANAGER.updateRecord(Constants.CRL_TABLE, castingManager.convertObjectToMap(crlTable));
-        setX509CRL(data);
-    }
-
-    /**
-     * Create CRL with default options;
-     */
-    private void init() throws CRLException, IOException, OperatorCreationException {
-        Calendar calendar = Calendar.getInstance();
-        Date thisUpdate = calendar.getTime();
-        calendar.add(Calendar.DAY_OF_MONTH,
-                Integer.parseInt(NEXT_UPDATE_INTERVAL));
-        byte[] data = CRL_ISSUER.generate(thisUpdate, calendar.getTime(), Collections.emptyList());
-        ACCOUNT_DB_MANAGER.insertRecord(Constants.CRL_TABLE,
-                castingManager.convertObjectToMap(new CRLTable(thisUpdate, new Binary(data))));
-        setX509CRL(data);
+        ArrayList<HashMap<String, Object>> crlList = ACCOUNT_DB_MANAGER.selectRecord(Constants.CRL_TABLE,
+                new HashMap<>());
+        if (crlList != null && !crlList.isEmpty()) {
+            CRLTable crlTable = castingManager.convertMaptoObject(crlList.get(0), new CRLTable());
+            crlTable.setThisUpdate(thisUpdate);
+            crlTable.setBinaryData(new Binary(data));
+            ACCOUNT_DB_MANAGER.updateRecord(Constants.CRL_TABLE, castingManager.convertObjectToMap(crlTable));
+            setX509CRL(data);
+        }
     }
 
     /**
@@ -148,7 +149,7 @@ public final class CrlManager {
     }
 
     /**
-     * Static inner class for CBOR Crl presentation.
+     * Utility class for CBOR Crl presentation.
      */
     private static final class CRL {
 
@@ -156,7 +157,7 @@ public final class CrlManager {
 
         private final byte[] data;
 
-        public CRL(String encoding, byte[] data) {
+        CRL(String encoding, byte[] data) {
             this.encoding = encoding;
             this.data = data;
         }
@@ -169,5 +170,4 @@ public final class CrlManager {
             return data;
         }
     }
-
 }
index a274784..13a51a2 100644 (file)
@@ -47,7 +47,8 @@ import static org.iotivity.cloud.accountserver.resources.credprov.cert.Certifica
 import static org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager.CRL_MANAGER;
 
 /**
- * Class is responsible for handling requests GET and POST for CRL data.
+ * Class is used working with POST and GET requests and
+ * handles CRL requests.
  */
 public class CrlResource extends Resource {
 
@@ -83,7 +84,20 @@ public class CrlResource extends Resource {
     }
 
     /**
-     * Handles GET request and sends response back to the client.
+     * Method handles GET requests with specified format:
+     * GET /oic/credprov/crl?lu=20170701000000
+     * Checks if “lu” value is not after the latest update.
+     * If so, response with the latest CRL, otherwise response error (e.g. 4.04 Not Found)
+     * And response of next format:
+     * 2.05 CONTENTS
+     * {
+     *      “tu” : “20160711000000”,
+     *      “nu” : “20161011000000”,
+     *      “crl” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CRL Binary>”
+     *       }
+     * }
      */
     private IResponse handleGetRequest(IRequest request)
             throws ServerException {
@@ -91,11 +105,13 @@ public class CrlResource extends Resource {
         IResponse iResponse = MessageBuilder.createResponse(request, ResponseStatus.NOT_FOUND);
         if (queryData != null) {
             List<String> lastUpdateList = queryData.get(Constants.REQ_LAST_UPDATE);
-            if (lastUpdateList != null && !lastUpdateList.isEmpty() &&
-                    CRL_MANAGER.checkLastUpdate(lastUpdateList.get(0))) {
+            if (lastUpdateList != null && !lastUpdateList.isEmpty()) {
                 try {
-                    iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
-                            ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(CRL_MANAGER.getPayload()));
+                    Map<String, Object> payload = CRL_MANAGER.getPayload(lastUpdateList.get(0));
+                    if (!payload.isEmpty()) {
+                        iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(payload));
+                    }
                 } catch (CRLException e) {
                     Log.e(e.getMessage());
                 }
@@ -105,42 +121,63 @@ public class CrlResource extends Resource {
     }
 
     /**
-     * Handles POST requests and sends back CRL data in response.
+     * Handles POST requests of next formats:
+     * POST /oic/credprov/crl
+     * {
+     *      “tu” : “20160727000000”,
+     *      “nu” : “20161027000000”,
+     *      “rcsn” : “123456”
+     * }
+     * AND
+     * POST /oic/credprov/crl
+     * {
+     *      “tu” : “20160727000000”,
+     *      “nu” : “20161027000000”,
+     *      “crl” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded New CRL Binary>”
+     *       }
+     * }
+     * And responds back with 2.04 CHANGED if everything is ok, and PRECONDITION_FAILED - otherwise
      */
     private IResponse handlePostRequest(IRequest request)
             throws ServerException {
-        Map<String, Object> payloadData = MAP_CBOR
-                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
-        Object thisUpdate = payloadData.get(Constants.REQ_THIS_UPDATE);
-        Object nextUpdate = payloadData.get(Constants.REQ_NEXT_UPDATE);
+        byte[] requestPayload = request.getPayload();
         IResponse response = MessageBuilder.createResponse(request, ResponseStatus.PRECONDITION_FAILED);
-        if (thisUpdate != null && thisUpdate instanceof String && nextUpdate != null && nextUpdate instanceof String) {
-            Date thisUpdateDate;
-            try {
-                thisUpdateDate = DATE_FORMAT.parse(thisUpdate.toString());
-                DATE_FORMAT.parse(nextUpdate.toString());
-                Object reqSerialNumber = payloadData.get(Constants.REQ_SERIAL_NUMBER);
-                Object crl = payloadData.get(Constants.REQ_CRL);
-                if (reqSerialNumber != null && reqSerialNumber instanceof List) {
-                    CRL_MANAGER.revoke(((List<String>) reqSerialNumber).toArray(new String[]{}));
-                    response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-                } else if (crl != null && crl instanceof Map) {
-                    Object encoding = ((Map<String, Object>) crl).get(Constants.ENCODING);
-                    Object crlData = ((Map<String, Object>) crl).get(Constants.DATA);
-                    if (encoding != null && encoding instanceof String && crlData != null && crlData instanceof byte[]) {
-                        try {
-                            if (encoding.equals(BASE_64)) {
-                                crlData = Base64.decode((byte[]) crlData);
-                            }
-                            CRL_MANAGER.update(thisUpdateDate, (byte[]) crlData);
+        if (requestPayload != null) {
+            Map<String, Object> payloadData = MAP_CBOR
+                    .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+            if (payloadData != null) {
+                Object thisUpdate = payloadData.get(Constants.REQ_THIS_UPDATE);
+                Object nextUpdate = payloadData.get(Constants.REQ_NEXT_UPDATE);
+                if (thisUpdate != null && thisUpdate instanceof String && nextUpdate != null && nextUpdate instanceof String) {
+                    Date thisUpdateDate;
+                    try {
+                        thisUpdateDate = DATE_FORMAT.parse(thisUpdate.toString());
+                        Object reqSerialNumber = payloadData.get(Constants.REQ_SERIAL_NUMBER);
+                        Object crl = payloadData.get(Constants.REQ_CRL);
+                        if (reqSerialNumber != null && reqSerialNumber instanceof List) {
+                            CRL_MANAGER.revoke(((List<String>) reqSerialNumber).toArray(new String[]{}));
                             response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-                        } catch (DecoderException e) {
-                            Log.e(e.getMessage() + e.getClass());
+                        } else if (crl != null && crl instanceof Map) {
+                            Object encoding = ((Map<String, Object>) crl).get(Constants.ENCODING);
+                            Object crlData = ((Map<String, Object>) crl).get(Constants.DATA);
+                            if (encoding != null && encoding instanceof String && crlData != null && crlData instanceof byte[]) {
+                                try {
+                                    if (encoding.equals(BASE_64)) {
+                                        crlData = Base64.decode((byte[]) crlData);
+                                    }
+                                    CRL_MANAGER.update(thisUpdateDate, (byte[]) crlData);
+                                    response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
+                                } catch (DecoderException e) {
+                                    Log.e(e.getMessage() + e.getClass());
+                                }
+                            }
                         }
+                    } catch (CRLException | IOException | OperatorCreationException | ParseException e) {
+                        Log.e(e.getMessage() + e.getClass());
                     }
                 }
-            } catch (CRLException | IOException | OperatorCreationException | ParseException e) {
-                Log.e(e.getMessage() + e.getClass());
             }
         }
         return response;
index 0bf7401..71fb1a0 100644 (file)
@@ -21,6 +21,7 @@
  */
 package org.iotivity.cloud.accountserver.x509.cert;
 
+import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.openssl.PEMException;
 import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
@@ -95,8 +96,11 @@ public class CSRParser {
      * Returns common name from csr subject.
      */
     public String getCommonName() {
-        return subject.getRDNs(CN)[0].getFirst().getValue().toString();
-
+        AttributeTypeAndValue rdn = subject.getRDNs(CN)[0].getFirst();
+        if (rdn != null) {
+            return rdn.getValue().toString();
+        }
+        return null;
     }
 
     /**
index 041bea7..7aed99f 100644 (file)
@@ -58,31 +58,31 @@ public class CertificateBuilder {
     /**
      * Attribute for X500Name subject.
      */
-    private X500Name subject;
+    private final X500Name subject;
 
     /**
      * Attribute for public key.
      */
-    private PublicKey publicKey;
+    private final PublicKey publicKey;
 
     /**
      * Attribute for certificate extension.
      */
-    private CertificateExtension extension;
+    private final CertificateExtension extension;
 
     /**
      * Constructs certificate builder with specified subject
      * public key and certificate extension.
      */
-    public CertificateBuilder(X500Name subject,
-                              PublicKey publicKey, CertificateExtension extension) {
+    public CertificateBuilder(X500Name subject, PublicKey publicKey, CertificateExtension extension) {
         this.subject = subject;
         this.publicKey = publicKey;
         this.extension = extension;
     }
 
     /**
-     * Builds X509Certificate with default root key.
+     * Builds X509Certificate, issued by CA issuer, with specific subject and publick key
+     * Adds extension during build.
      */
     public X509Certificate build() throws CertIOException, GeneralSecurityException, OperatorCreationException {
         X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
@@ -120,6 +120,4 @@ public class CertificateBuilder {
                 Integer.parseInt(NOT_AFTER_INTERVAL));
         return calendar.getTime();
     }
-
-
 }
\ No newline at end of file
index 8172a19..86b9ff8 100644 (file)
@@ -69,8 +69,6 @@ public class CertificateExtension {
 
     /**
      * Returns ASN1Encodable attribute value.
-     *
-     * @return
      */
     ASN1Encodable getValue() {
         return value;
index 6e4df99..3ea06b2 100644 (file)
@@ -36,7 +36,7 @@ import java.util.Date;
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CA_ISSUER;
 
 /**
- * Class is used for generating CRL with specified parameters.
+ * Class is used for generating CRLs with specified parameters.
  */
 public final class CrlIssuer {
     /**
@@ -45,7 +45,7 @@ public final class CrlIssuer {
     public static final CrlIssuer CRL_ISSUER = new CrlIssuer();
 
     /**
-     * Creates new instance of CRL issuer.
+     * Private constructor to make class non-instantiable.
      */
     private CrlIssuer() {
     }
@@ -55,7 +55,6 @@ public final class CrlIssuer {
      */
     public byte[] generate(Date thisUpdate, Date nextUpdate, Collection<? extends X509CRLEntry> certs,
                            String... serialNumbers) throws IOException, OperatorCreationException {
-        byte[] crl;
         X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(CA_ISSUER,
                 thisUpdate);
         crlBuilder.setNextUpdate(nextUpdate);
@@ -67,8 +66,8 @@ public final class CrlIssuer {
         for (String serialNumber : serialNumbers) {
             crlBuilder.addCRLEntry(new BigInteger(serialNumber), new Date(), 0);
         }
-        crl = crlBuilder.build(CertificateBuilder.SIGNER_BUILDER.
+        return crlBuilder.build(CertificateBuilder.SIGNER_BUILDER.
                 build(CertificateStorage.ROOT_PRIVATE_KEY)).getEncoded();
-        return crl;
     }
+
 }
\ No newline at end of file
index 83800a7..f69d51c 100644 (file)
@@ -49,6 +49,7 @@ 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.util.Cbor;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -104,7 +105,8 @@ public class AccountResourceTest {
         }).when(mMockDevice).sendResponse(Mockito.anyObject());
     }
 
-    public static void resetAccountDatabase() throws Exception {
+    @After
+    public void resetAccountDatabase() throws Exception {
         MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
         mongoDB.createTable(Constants.USER_TABLE);
         mongoDB.createTable(Constants.TOKEN_TABLE);
@@ -178,6 +180,7 @@ public class AccountResourceTest {
                 .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
         HashMap<String, Object> getUserInfo = ((ArrayList<HashMap<String, Object>>) payloadData
                 .get("ulist")).get(0);
+
         assertTrue(getUserInfo.get("uid").equals(uuid));
     }
 
index 62bdca5..552eb7a 100644 (file)
  */
 package org.iotivity.cloud.accountserver.resources.account.credprov.cert;
 
-import org.bouncycastle.util.encoders.Base64;
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.TokenTable;
-import org.iotivity.cloud.accountserver.resources.account.credprov.crl.CrlResourceTest;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateResource;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
-import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.accountserver.x509.cert.Utility;
 import org.iotivity.cloud.base.OICConstants;
@@ -56,38 +53,32 @@ import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.math.BigInteger;
-import java.security.cert.*;
-import java.util.*;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
-import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
-import static org.junit.Assert.*;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CERTIFICATE_FACTORY;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.KEYSTORE_FILE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
 public class CertificateResourceTest {
 
-    private static final String COMMON_NAME = "OU=OCF Device CA, O=Samsung, C=KR, CN=uuid:B371C481-38E6-4D47-8320-7688D8A5B58C";
-
+    public static final String COMMON_NAME = "OU=OCF Device CA, O=Samsung, C=KR, CN=uuid:B371C481-38E6-4D47-8320-7688D8A5B58C";
+    public static final String DEVICE_ID = "B371C481-38E6-4D47-8320-7688D8A5B58C";
     private static final String CERTIFICATE_URI = OICConstants.CREDPROV_CERT_FULL_URI;
-
-    private static final String DEVICE_ID = "B371C481-38E6-4D47-8320-7688D8A5B58C";
-
+    private static CertificateResource certificateResource = new CertificateResource();
+    private static TypeCastingManager<TokenTable> castingManager = new TypeCastingManager<>();
     private CoapDevice mMockDevice = mock(CoapDevice.class);
-
     private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
-
     private IResponse mResponse = null;
-
     private CountDownLatch mLatch = new CountDownLatch(
             1);
-
-    private static CertificateResource certificateResource = new CertificateResource();
-
     private byte[] csr;
 
-    private static TypeCastingManager<TokenTable> castingManager = new TypeCastingManager<>();
-
     static void createToken() {
         TokenTable certificateTable = new TokenTable();
         certificateTable.setDid(DEVICE_ID);
@@ -99,6 +90,7 @@ public class CertificateResourceTest {
     @AfterClass
     public static void after() {
         KEYSTORE_FILE.delete();
+        AccountDBManager.getInstance().deleteRecord(Constants.CERTIFICATE_TABLE, new HashMap<>());
     }
 
     @BeforeClass
@@ -142,8 +134,6 @@ public class CertificateResourceTest {
                 Object[] args = invocation.getArguments();
                 CoapResponse resp = (CoapResponse) args[0];
                 mResponse = resp;
-
-
                 mLatch.countDown();
                 return null;
             }
@@ -247,67 +237,6 @@ public class CertificateResourceTest {
         assertTrue(methodCheck(mResponse, ResponseStatus.BAD_REQUEST));
     }
 
-    Map<String, Object> payloadData;
-
-    Map<String, Object> crlMap;
-
-    byte[] data;
-
-    X509CRL crlX509;
-
-    @Test
-    public void testReIssueBase64() throws CRLException, CertificateException {
-        IRequest request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-
-        Map<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-        List<BigInteger> serialNumbers = new ArrayList<>();
-        Map<String, Object> certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
-        InputStream in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
-        X509Certificate personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
-        serialNumbers.add(personaleCert.getSerialNumber());
-        serialNumbers.add(personaleCert.getSerialNumber().subtract(BigInteger.ONE));
-
-        request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        payloadData = mCbor
-                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-        certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
-        in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
-        personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
-        serialNumbers.add(personaleCert.getSerialNumber());
-
-
-        request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        getTestMethodName();
-        request = CrlResourceTest.crlRequest(RequestMethod.GET, CrlResourceTest.CRL_URI, CrlResourceTest.CRL_URI_QUERY);
-        CrlResource crlResource = new CrlResource();
-        crlResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-        hashmapCheck(mResponse, Constants.ENCODING);
-        hashmapCheck(mResponse, Constants.DATA);
-        if (mResponse.getPayload() != null) {
-            payloadData = mCbor
-                    .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-            crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
-            data = (byte[]) crlMap.get(Constants.DATA);
-            crlX509 = (X509CRL) CERTIFICATE_FACTORY.generateCRL(new ByteArrayInputStream(data));
-        }
-
-        assertEquals(DER, crlMap.get(Constants.ENCODING));
-        assertNotNull(data);
-        Set<? extends X509CRLEntry> entries = crlX509.getRevokedCertificates();
-        Iterator<? extends X509CRLEntry> iterator = entries.iterator();
-        while (iterator.hasNext()) {
-            assertTrue(serialNumbers.contains(iterator.next().getSerialNumber()));
-        }
-    }
-
     @Test
     public void testMethodNotAllowed() {
         IRequest request = csrRequest(DEVICE_ID, CertificateConstants.DER, csr, RequestMethod.GET, true);
@@ -364,7 +293,24 @@ public class CertificateResourceTest {
         return request;
     }
 
-    private static class CSR {
+    private boolean methodCheck(IResponse response,
+                                ResponseStatus responseStatus) {
+        if (responseStatus == response.getStatus())
+            return true;
+        else
+            return false;
+    }
+
+    private boolean hashmapCheck(IResponse response, String propertyName) {
+        HashMap<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
+        if (payloadData.containsKey(propertyName))
+            return true;
+        else
+            return false;
+    }
+
+    public static class CSR {
         String encoding;
 
         byte[] data;
@@ -394,21 +340,4 @@ public class CertificateResourceTest {
         }
     }
 
-    private boolean methodCheck(IResponse response,
-                                ResponseStatus responseStatus) {
-        if (responseStatus == response.getStatus())
-            return true;
-        else
-            return false;
-    }
-
-    private boolean hashmapCheck(IResponse response, String propertyName) {
-        HashMap<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
-        if (payloadData.containsKey(propertyName))
-            return true;
-        else
-            return false;
-    }
-
 }
index 1afb0ef..d548d1f 100644 (file)
@@ -27,6 +27,8 @@ import org.bouncycastle.util.encoders.Base64;
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.CRLTable;
+import org.iotivity.cloud.accountserver.resources.account.credprov.cert.CertificateResourceTest;
+import org.iotivity.cloud.accountserver.resources.account.credprov.cert.GenerateCSR;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateResource;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
@@ -34,6 +36,7 @@ import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager;
 import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.accountserver.x509.crl.CrlIssuer;
+import org.iotivity.cloud.base.OICConstants;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.protocols.IRequest;
 import org.iotivity.cloud.base.protocols.IResponse;
@@ -43,7 +46,9 @@ 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.util.Cbor;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -52,6 +57,7 @@ import org.mockito.stubbing.Answer;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -61,6 +67,7 @@ import java.security.Security;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509CRL;
 import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
 import java.text.ParseException;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
@@ -84,13 +91,22 @@ public class CrlResourceTest {
     public static final String CRL_URI_QUERY_CONDITION_FALSE = "lu=21160726210000";
     public static final String CRL_URI_QUERY_PARSE_ERROR = "lu=1231212asdzfg4123123123123123";
     public static final String[] FOR_FULL_CRL = {Constants.REQ_THIS_UPDATE, Constants.REQ_NEXT_UPDATE, Constants.REQ_CRL};
-    public static final PublicKey key = CertificateStorage.ROOT_CERTIFICATE.getPublicKey();
+    public static PublicKey key;
+    static CertificateResource certificateResource;
 
     private static TypeCastingManager<CRLTable> castingManager = new TypeCastingManager<>();
 
-    static {
+    @AfterClass
+    public static void after() {
+        AccountDBManager.getInstance().deleteRecord(Constants.CERTIFICATE_TABLE, new HashMap<>());
+        AccountDBManager.getInstance().deleteRecord(Constants.CRL_TABLE, new HashMap<>());
+    }
+
+    @BeforeClass
+    public static void setUpBefore() {
         Security.insertProviderAt(new BouncyCastleProvider(), 0);
-        new CertificateResource();
+        certificateResource = new CertificateResource();
+        key = CertificateStorage.ROOT_CERTIFICATE.getPublicKey();
     }
 
     /**
@@ -121,11 +137,12 @@ public class CrlResourceTest {
                     payloadData = mCbor
                             .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
                     crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
-                    data = (byte[]) crlMap.get(Constants.DATA);
-                    CertificateFactory factory = CertificateFactory.getInstance("X509");
-                    crlX509 = (X509CRL) factory.generateCRL(new ByteArrayInputStream(data));
+                    if (crlMap != null) {
+                        data = (byte[]) crlMap.get(Constants.DATA);
+                        CertificateFactory factory = CertificateFactory.getInstance("X509");
+                        crlX509 = (X509CRL) factory.generateCRL(new ByteArrayInputStream(data));
+                    }
                 }
-
                 mLatch.countDown();
                 return null;
             }
@@ -158,6 +175,73 @@ public class CrlResourceTest {
         return SERIAL_NUMBER;
     }
 
+
+    @Test
+    public void testAeIssueBase64() throws Exception {
+        byte[] csr = GenerateCSR.generatePKCS10(CertificateResourceTest.COMMON_NAME, false);
+        IRequest request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        Map<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+        List<BigInteger> serialNumbers = new ArrayList<>();
+        Map<String, Object> certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
+        InputStream in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
+        X509Certificate personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+        serialNumbers.add(personaleCert.getSerialNumber());
+        serialNumbers.add(personaleCert.getSerialNumber().subtract(BigInteger.ONE));
+        request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        payloadData = mCbor
+                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+        certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
+        in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
+        personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+        serialNumbers.add(personaleCert.getSerialNumber());
+        request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        getTestMethodName();
+        request = CrlResourceTest.crlRequest(RequestMethod.GET, CrlResourceTest.CRL_URI, CrlResourceTest.CRL_URI_QUERY);
+        CrlResource crlResource = new CrlResource();
+        crlResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+        hashmapCheck(mResponse, Constants.ENCODING);
+        hashmapCheck(mResponse, Constants.DATA);
+        if (mResponse.getPayload() != null) {
+            payloadData = mCbor
+                    .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+            crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
+            data = (byte[]) crlMap.get(Constants.DATA);
+            crlX509 = (X509CRL) CERTIFICATE_FACTORY.generateCRL(new ByteArrayInputStream(data));
+        }
+        assertEquals(DER, crlMap.get(Constants.ENCODING));
+        assertNotNull(data);
+        Set<? extends X509CRLEntry> entries = crlX509.getRevokedCertificates();
+        Iterator<? extends X509CRLEntry> iterator = entries.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(serialNumbers.contains(iterator.next().getSerialNumber()));
+        }
+    }
+
+    private IRequest csrRequest(String deviceId, String encoding, byte[] data, RequestMethod method, boolean isEncoded) {
+        IRequest request;
+        HashMap<String, Object> payloadData = new HashMap<>();
+        payloadData.put(Constants.REQ_DEVICE_ID, deviceId);
+        CertificateResourceTest.CSR csr = new CertificateResourceTest.CSR();
+        if (isEncoded) {
+            csr.setEncoding(encoding);
+            csr.setData(data);
+            payloadData.put("csr", csr);
+        }
+        request = MessageBuilder.createRequest(method, OICConstants.CREDPROV_CERT_FULL_URI,
+                null, ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(payloadData));
+        return request;
+    }
+
+
     @Test
     public void testCrlGetContent() throws Exception {
         getTestMethodName();
@@ -208,34 +292,6 @@ public class CrlResourceTest {
     }
 
     @Test
-    public void testX509CRL() {
-        Field field;
-        Method m;
-        try {
-            IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
-            crlResource.onDefaultRequestReceived(mMockDevice, request);
-            assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-            field = CrlManager.class.getDeclaredField("x509CRL");
-            field.setAccessible(true);
-            Object value = field.get(CrlManager.CRL_MANAGER);
-            field.set(CrlManager.CRL_MANAGER, null);
-            request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
-            crlResource.onDefaultRequestReceived(mMockDevice, request);
-            assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
-            m = CrlManager.class.getDeclaredMethod("getPayload");
-            m.setAccessible(true);
-            field.set(CrlManager.CRL_MANAGER, null);
-            Object o = m.invoke(CrlManager.CRL_MANAGER);
-            assertEquals(Collections.EMPTY_MAP, o);
-            field.set(CrlManager.CRL_MANAGER, value);
-        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Test
     public void testCrlPreconditionFailedException() throws ParseException, IOException, OperatorCreationException {
         getTestMethodName();
         getTestMethodName();
@@ -261,6 +317,7 @@ public class CrlResourceTest {
         getTestMethodName();
         IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
         crlResource.onDefaultRequestReceived(mMockDevice, request);
+        System.out.println("MRESPONSE" + mResponse.getStatus());
         assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
         String thisUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getThisUpdate());
         String nextUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getNextUpdate());
index ace8a22..a699048 100644 (file)
@@ -46,6 +46,7 @@ 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.util.Cbor;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -103,6 +104,14 @@ public class SessionResourceTest {
         }).when(mMockDevice).sendResponse(Mockito.anyObject());
     }
 
+    @After
+    public void resetAccountDatabase() throws Exception {
+        MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
+        mongoDB.createTable(Constants.USER_TABLE);
+        mongoDB.createTable(Constants.TOKEN_TABLE);
+        mongoDB.createTable(Constants.GROUP_TABLE);
+    }
+
     @Test
     public void testSignInOnDefaultRequestReceived() throws Exception {
         getTestMethodName();
index ee03ffd..2d1df31 100644 (file)
@@ -1,6 +1,5 @@
 package org.iotivity.cloud.accountserver.resources.account.tokenrefresh;
 
-import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
 import java.text.DateFormat;
@@ -10,19 +9,19 @@ import java.util.HashMap;
 
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
+import org.iotivity.cloud.accountserver.db.MongoDB;
 import org.iotivity.cloud.accountserver.db.TokenTable;
 import org.iotivity.cloud.accountserver.db.UserTable;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.base.device.CoapDevice;
 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.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.util.Cbor;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -33,18 +32,16 @@ import org.mockito.stubbing.Answer;
 public class TokenRefreshResourceTest {
     private static final String            REFRESH_TOKEN_URI         = Constants.ACCOUNT_TOKENREFRESH_FULL_URI;
     private static final String            DEVICE_ID                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
-    private String                         mAuthProvider             = "Google";
-    private String                         mAccessToken              = "ya29.Ci9VA06h_WhVG0lV3nU-kXMPSmisPJ6sM5iqMuoaNz0YYCO2lkXo5TGGy7wiol6Rdw";
-    private String                         mRefreshToken             = "1/UKLrjrMWErlq8has8XcpPg_riBcHcehKFUdoPoX9k0E";
-    private String                         mUuid                     = "3ff62bac-c7cb-46f5-bb9b-c0f2f75f8c1d";
+    private String                         mAuthProvider             = "Samsung";
+    private String                         mRefreshToken             = "rt0001";
+    private String                         mUuid                     = "u0001";
     private String                         mUserId                   = "userId";
-    private Cbor<HashMap<String, Object>>  mCbor                     = new Cbor<>();
-    private CoapDevice                     mMockDevice               = mock(
+    private Cbor<HashMap<String, String>>  mCbor                     = new Cbor<HashMap<String, String>>();
+    private CoapDevice                     mockDevice                = mock(
             CoapDevice.class);
     private TypeCastingManager<UserTable>  mUserTableCastingManager  = new TypeCastingManager<>();
     private TypeCastingManager<TokenTable> mTokenTableCastingManager = new TypeCastingManager<>();
     private TokenRefreshResource           mTokenRefreshResource     = new TokenRefreshResource();
-    private IResponse                      mResponse                 = null;
 
     @Before
     public void setUp() throws Exception {
@@ -60,22 +57,17 @@ public class TokenRefreshResourceTest {
                         .println("\t----payload : " + resp.getPayloadString());
                 System.out
                         .println("\t----responsestatus : " + resp.getStatus());
-                mResponse = resp;
                 return resp;
             }
-        }).when(mMockDevice).sendResponse(Mockito.anyObject());
+        }).when(mockDevice).sendResponse(Mockito.anyObject());
     }
 
-    @Test
-    public void testRefreshTokenonDefaultRequestReceived() throws Exception {
-        String uuid = this.mUuid;
-        RegisterTokenInfo(uuid, mUserId, mAccessToken, mRefreshToken);
-        TokenRefresh(RequestMethod.POST, mMockDevice, uuid, DEVICE_ID,
-                mRefreshToken);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        assertTrue(hashmapCheck(mResponse, "accesstoken"));
-        assertTrue(hashmapCheck(mResponse, "refreshtoken"));
-        assertTrue(hashmapCheck(mResponse, "expiresin"));
+    @After
+    public void resetAccountDatabase() throws Exception {
+        MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
+        mongoDB.createTable(Constants.USER_TABLE);
+        mongoDB.createTable(Constants.TOKEN_TABLE);
+        mongoDB.createTable(Constants.GROUP_TABLE);
     }
 
     @Test(expected = ServerException.NotFoundException.class)
@@ -83,7 +75,7 @@ public class TokenRefreshResourceTest {
             throws Exception {
         String uuid = this.mUuid + "WrongRefreshTokenCase";
         RegisterTokenInfo(uuid, mUserId, mAuthProvider, mRefreshToken);
-        TokenRefresh(RequestMethod.POST, mMockDevice, uuid, DEVICE_ID,
+        TokenRefresh(RequestMethod.POST, mockDevice, uuid, DEVICE_ID,
                 mRefreshToken + "NotExist");
     }
 
@@ -92,7 +84,7 @@ public class TokenRefreshResourceTest {
             throws Exception {
         String uuid = this.mUuid + "InvalidRequestMethod (GET)";
         RegisterTokenInfo(uuid, mUserId, mAuthProvider, mRefreshToken);
-        TokenRefresh(RequestMethod.GET, mMockDevice, uuid, DEVICE_ID,
+        TokenRefresh(RequestMethod.GET, mockDevice, uuid, DEVICE_ID,
                 mRefreshToken + "InvalidMethod");
     }
 
@@ -100,7 +92,7 @@ public class TokenRefreshResourceTest {
     public void testRefreshTokenonRequestReceivedNullUuid() throws Exception {
         String uuid = this.mUuid + "NullUuid";
         RegisterTokenInfo(uuid, mUserId, mAuthProvider, mRefreshToken);
-        TokenRefresh(RequestMethod.POST, mMockDevice, null, DEVICE_ID,
+        TokenRefresh(RequestMethod.POST, mockDevice, null, DEVICE_ID,
                 mRefreshToken + "InvalidMethod");
     }
 
@@ -108,7 +100,7 @@ public class TokenRefreshResourceTest {
     public void testRefreshTokenonRequestReceivedNullDi() throws Exception {
         String uuid = this.mUuid + "NullDi";
         RegisterTokenInfo(uuid, mUserId, mAuthProvider, mRefreshToken);
-        TokenRefresh(RequestMethod.POST, mMockDevice, uuid, null,
+        TokenRefresh(RequestMethod.POST, mockDevice, uuid, null,
                 mRefreshToken + "InvalidMethod");
     }
 
@@ -117,7 +109,7 @@ public class TokenRefreshResourceTest {
             throws Exception {
         String uuid = this.mUuid + "NullRefreshToken";
         RegisterTokenInfo(uuid, mUserId, mAuthProvider, mRefreshToken);
-        TokenRefresh(RequestMethod.POST, mMockDevice, uuid, DEVICE_ID, null);
+        TokenRefresh(RequestMethod.POST, mockDevice, uuid, DEVICE_ID, null);
     }
 
     public void TokenRefresh(RequestMethod method, CoapDevice device,
@@ -178,21 +170,4 @@ public class TokenRefreshResourceTest {
         userInfo.setUserid(userId);
         return userInfo;
     }
-
-    private boolean methodCheck(IResponse response,
-            ResponseStatus responseStatus) {
-        if (responseStatus == response.getStatus())
-            return true;
-        else
-            return false;
-    }
-
-    private boolean hashmapCheck(IResponse response, String propertyName) {
-        HashMap<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
-        if (payloadData.containsKey(propertyName))
-            return true;
-        else
-            return false;
-    }
 }
index 70b4e93..61cefac 100644 (file)
@@ -44,6 +44,7 @@ import org.iotivity.cloud.base.protocols.enums.Observe;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.util.Cbor;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -93,6 +94,14 @@ public class GroupResourceTest {
         }).when(mMockDevice).sendResponse(Mockito.anyObject());
     }
 
+    @After
+    public void resetAccountDatabase() throws Exception {
+        MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
+        mongoDB.createTable(Constants.USER_TABLE);
+        mongoDB.createTable(Constants.TOKEN_TABLE);
+        mongoDB.createTable(Constants.GROUP_TABLE);
+    }
+
     @Test
     public void testCreateGroup() throws Exception {
         getTestMethodName();
index 2f7600d..e7f84ce 100644 (file)
@@ -33,6 +33,7 @@ import java.util.concurrent.CountDownLatch;
 
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.MongoDB;
+import org.iotivity.cloud.accountserver.resources.acl.group.GroupResource;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
 import org.iotivity.cloud.base.protocols.IRequest;
@@ -53,13 +54,18 @@ import org.mockito.stubbing.Answer;
 
 public class InviteResourceTest {
     private static final String           INVITE_URI        = Constants.INVITE_FULL_URI;
+    private static final String           GROUP_URI         = Constants.GROUP_FULL_URI;
 
     private static final String           TEST_INVITE_USER  = "u0001";
     private static final String           TEST_INVITED_USER = "u0002";
     private static final String           TEST_GROUP_ID     = "g0001";
 
+    private String                        mInvitedGroupId   = null;
+
     private InviteResource                mInviteResource   = null;
 
+    private GroupResource                 mGroupResource    = new GroupResource();
+
     private CountDownLatch                mLatch            = null;
 
     private CoapDevice                    mMockDevice       = null;
@@ -91,6 +97,18 @@ public class InviteResourceTest {
                 CoapResponse resp = (CoapResponse) args[0];
                 mResponse = resp;
 
+                if (resp.getPayloadSize() != 0) {
+
+                    HashMap<String, Object> payloadData = mCbor
+                            .parsePayloadFromCbor(resp.getPayload(),
+                                    HashMap.class);
+
+                    if (payloadData.containsKey(Constants.REQ_GROUP_ID)) {
+                        mInvitedGroupId = (String) payloadData
+                                .get(Constants.REQ_GROUP_ID);
+                    }
+                }
+
                 mLatch.countDown();
 
                 return resp;
@@ -247,11 +265,25 @@ public class InviteResourceTest {
     }
 
     @Test
-    public void testDeleteInvitation() throws Exception {
+    public void testDeleteInvitationForAccept() throws Exception {
 
-        sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
+        createGroup(TEST_INVITE_USER, "Public");
+        sendInvitation(mInvitedGroupId, TEST_INVITED_USER);
 
-        deleteInvitation(TEST_GROUP_ID, TEST_INVITED_USER, "");
+        deleteInvitationWithQuery(mInvitedGroupId, TEST_INVITED_USER, true);
+
+        assertTrue(mLatch.await(1L, SECONDS));
+        assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
+
+    }
+
+    @Test
+    public void testDeleteInvitationForDeny() throws Exception {
+
+        createGroup(TEST_INVITE_USER, "Public");
+        sendInvitation(mInvitedGroupId, TEST_INVITED_USER);
+
+        deleteInvitationWithQuery(mInvitedGroupId, TEST_INVITED_USER, false);
 
         assertTrue(mLatch.await(1L, SECONDS));
         assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
@@ -347,4 +379,43 @@ public class InviteResourceTest {
         return false;
     }
 
+    private void deleteInvitationWithQuery(String gid, String uid,
+            boolean accept) {
+
+        int acceptInt = 0;
+
+        if (accept)
+            acceptInt = 1;
+
+        String uriQuery = Constants.REQ_GROUP_ID + "=" + gid + ";"
+                + Constants.REQ_UUID_ID + "=" + uid + ";"
+                + Constants.REQ_INVITE_ACCEPT + "=" + acceptInt;
+
+        IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
+                INVITE_URI, uriQuery);
+
+        mInviteResource.onDefaultRequestReceived(mMockDevice, request);
+    }
+
+    private void createGroup(String gmid, String gtype) {
+
+        IRequest request = createGroupRequest(gmid, gtype);
+
+        mGroupResource.onDefaultRequestReceived(mMockDevice, request);
+    }
+
+    private IRequest createGroupRequest(String uuid, String gtype) {
+
+        IRequest request = null;
+
+        HashMap<String, Object> payloadData = new HashMap<String, Object>();
+        payloadData.put("gmid", uuid);
+        payloadData.put("gtype", gtype);
+
+        request = MessageBuilder.createRequest(RequestMethod.POST, GROUP_URI,
+                null, ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(payloadData));
+
+        return request;
+    }
 }
\ No newline at end of file
index 766cd3a..8ca99b5 100644 (file)
@@ -50,5 +50,5 @@ public class Constants extends OICConstants {
 
     public static final String REQ_LINKS           = "links";
     public static final String REQ_HREF            = "href";
-    public static final String REQ_CRL = "crl";
+    public static final String REQ_CRL             = "crl";
 }
index 772a051..1fc959c 100644 (file)
@@ -52,6 +52,12 @@ import io.netty.channel.ChannelHandler.Sharable;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPromise;
 
+/**
+ *
+ * This class provides a set of APIs to manage all of request
+ *
+ */
+
 public class DeviceServerSystem extends ServerSystem {
 
     IRequestChannel mRDServer = null;
@@ -60,9 +66,20 @@ public class DeviceServerSystem extends ServerSystem {
         mRDServer = ConnectorPool.getConnection("rd");
     }
 
+    /**
+     *
+     * This class provides a set of APIs to manage device pool.
+     *
+     */
     public class CoapDevicePool {
         HashMap<String, Device> mMapDevice = new HashMap<>();
 
+        /**
+         * API for adding device information into pool.
+         * 
+         * @param device
+         *            device to be added
+         */
         public void addDevice(Device device) {
             String deviceId = ((CoapDevice) device).getDeviceId();
             synchronized (mMapDevice) {
@@ -70,6 +87,12 @@ public class DeviceServerSystem extends ServerSystem {
             }
         }
 
+        /**
+         * API for removing device information into pool.
+         * 
+         * @param device
+         *            device to be removed
+         */
         public void removeDevice(Device device) throws ClientException {
             String deviceId = ((CoapDevice) device).getDeviceId();
             synchronized (mMapDevice) {
@@ -91,6 +114,12 @@ public class DeviceServerSystem extends ServerSystem {
             }
         }
 
+        /**
+         * API for getting device information.
+         * 
+         * @param deviceId
+         *            device id to get device
+         */
         public Device queryDevice(String deviceId) {
             Device device = null;
             synchronized (mMapDevice) {
@@ -102,6 +131,11 @@ public class DeviceServerSystem extends ServerSystem {
 
     CoapDevicePool mDevicePool = new CoapDevicePool();
 
+    /**
+     *
+     * This class provides a set of APIs to manage life cycle of coap message.
+     *
+     */
     @Sharable
     class CoapLifecycleHandler extends ChannelDuplexHandler {
         @Override
@@ -184,6 +218,14 @@ public class DeviceServerSystem extends ServerSystem {
             }
         }
 
+        /**
+         * API for sending state to resource directory
+         * 
+         * @param deviceId
+         *            device id to be sent to resource directory
+         * @param state
+         *            device state to be sent to resource directory
+         */
         public void sendDevicePresence(String deviceId, String state) {
 
             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
index ae83028..cc029c4 100644 (file)
@@ -45,6 +45,12 @@ import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.ciserver.DeviceServerSystem.CoapDevicePool;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about message to another
+ * device
+ *
+ */
 public class DiResource extends Resource {
 
     private CoapDevicePool mDevicePool = null;
@@ -108,6 +114,12 @@ public class DiResource extends Resource {
                 null);
     }
 
+    /**
+     *
+     * This class provides a set of APIs to handling message contains link
+     * interface.
+     *
+     */
     class LinkInterfaceHandler implements IResponseEventHandler {
         private Cbor<List<HashMap<String, Object>>> mCbor      = new Cbor<>();
         private String                              mTargetDI  = null;
@@ -143,6 +155,15 @@ public class DiResource extends Resource {
         }
     }
 
+    /**
+     * API for handling optional method for handling packet contains link
+     * interface.
+     * 
+     * @param srcDevice
+     *            device information contains response channel
+     * @param request
+     *            received request to relay
+     */
     public void onLinkInterfaceRequestReceived(Device srcDevice,
             IRequest request) throws ServerException {
         IRequestChannel requestChannel = getTargetDeviceChannel(request);
@@ -175,7 +196,6 @@ public class DiResource extends Resource {
         }
     }
 
-    // This is optional method for packet handling
     @Override
     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
             throws ServerException {
index 572e7ba..4e41179 100644 (file)
@@ -37,6 +37,12 @@ import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about account to account
+ *
+ */
+
 public class Account extends Resource {
     IRequestChannel mASServer = null;
 
index 2722bcb..7f3bf84 100644 (file)
@@ -35,6 +35,12 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about session to account
+ *
+ */
+
 public class AccountSession extends Resource {
     IRequestChannel                       mAuthServer = null;
     private Cbor<HashMap<String, Object>> mCbor       = new Cbor<>();
index 6adccec..e16aaf5 100644 (file)
@@ -31,6 +31,12 @@ import org.iotivity.cloud.base.protocols.IRequest;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about acl to account
+ *
+ */
+
 public class Acl extends Resource {
     IRequestChannel mAuthServer = null;
 
index 8a690d0..e9bed77 100644 (file)
@@ -36,6 +36,12 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about group to account
+ *
+ */
+
 public class AclGroup extends Resource {
 
     private IRequestChannel               mAuthServer = null;
index 54e46af..ff05fab 100644 (file)
@@ -35,6 +35,12 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about invite to account
+ *
+ */
+
 public class AclInvite extends Resource {
 
     IRequestChannel mAuthServer = null;
index e0e8e31..0bbf181 100644 (file)
@@ -31,12 +31,19 @@ import org.iotivity.cloud.base.protocols.IRequest;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about certificate to
+ * account
+ *
+ */
+
 public class Certificate extends Resource {
     IRequestChannel mAuthServer = null;
 
     public Certificate() {
-        super(Arrays.asList(Constants.PREFIX_OIC,
-                Constants.CREDPROV_URI, Constants.CERT_URI));
+        super(Arrays.asList(Constants.PREFIX_OIC, Constants.CREDPROV_URI,
+                Constants.CERT_URI));
         mAuthServer = ConnectorPool.getConnection("account");
     }
 
index 687585b..4286902 100644 (file)
@@ -31,6 +31,13 @@ import org.iotivity.cloud.base.protocols.IRequest;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about MQ message to
+ * message queue
+ *
+ */
+
 public class MessageQueue extends Resource {
     IRequestChannel mPSServer = null;
 
index 5f9e0e2..864c755 100644 (file)
@@ -40,6 +40,13 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about device presence to
+ * resource directory
+ *
+ */
+
 public class DevicePresence extends Resource {
     IRequestChannel                       mASServer = null;
     private Cbor<HashMap<String, Object>> mCbor     = new Cbor<>();
index fa024d0..a2fa953 100644 (file)
@@ -42,6 +42,13 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about publish resource to
+ * resource directory
+ *
+ */
+
 public class ResourceDirectory extends Resource {
     private Cbor<HashMap<String, Object>> mCbor     = new Cbor<>();
     IRequestChannel                       mRDServer = null;
@@ -72,23 +79,23 @@ public class ResourceDirectory extends Resource {
 
                 HashMap<String, Object> requestPayload = new HashMap<>();
 
-                requestPayload
-                        .put(Constants.REQ_DEVICE_LIST, Arrays.asList(di));
+                requestPayload.put(Constants.REQ_DEVICE_LIST,
+                        Arrays.asList(di));
                 IRequest requestToAS = MessageBuilder.createRequest(
                         RequestMethod.POST, uriPath.toString(), null,
                         ContentFormat.APPLICATION_CBOR,
                         mCbor.encodingPayloadToCbor(requestPayload));
 
-                mASServer.sendRequest(requestToAS, new AccountReceiveHandler(
-                        request, srcDevice));
+                mASServer.sendRequest(requestToAS,
+                        new AccountReceiveHandler(request, srcDevice));
                 break;
 
             case DELETE:
                 mRDServer.sendRequest(request, srcDevice);
                 break;
             default:
-                throw new BadRequestException(request.getMethod()
-                        + " request type is not support");
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not support");
         }
     }
 
@@ -121,8 +128,8 @@ public class ResourceDirectory extends Resource {
                             null, ContentFormat.APPLICATION_CBOR,
                             convertedPayload);
 
-                    mRDServer.sendRequest(mRequest, new PublishResponseHandler(
-                            mSrcDevice));
+                    mRDServer.sendRequest(mRequest,
+                            new PublishResponseHandler(mSrcDevice));
                     break;
 
                 default:
@@ -135,8 +142,8 @@ public class ResourceDirectory extends Resource {
         private byte[] convertPublishHref(IRequest request, Device device) {
 
             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
-            HashMap<String, Object> payload = cbor.parsePayloadFromCbor(
-                    request.getPayload(), HashMap.class);
+            HashMap<String, Object> payload = cbor
+                    .parsePayloadFromCbor(request.getPayload(), HashMap.class);
 
             if (verifyPublishPayload(payload) == false) {
 
@@ -213,8 +220,8 @@ public class ResourceDirectory extends Resource {
         private byte[] convertResponseHref(IResponse response) {
 
             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
-            HashMap<String, Object> payload = cbor.parsePayloadFromCbor(
-                    response.getPayload(), HashMap.class);
+            HashMap<String, Object> payload = cbor
+                    .parsePayloadFromCbor(response.getPayload(), HashMap.class);
 
             ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
                     .get(Constants.REQ_LINKS);
index f5e73ba..320ebf8 100644 (file)
@@ -40,24 +40,32 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about find resource to
+ * resource directory
+ *
+ */
+
 public class ResourceFind extends Resource {
     IRequestChannel                       mASServer = null;
+    IRequestChannel                       mRDServer = null;
     private Cbor<HashMap<String, Object>> mCbor     = new Cbor<>();
 
     public ResourceFind() {
         super(Arrays.asList(Constants.PREFIX_OIC, Constants.WELL_KNOWN_URI));
 
         mASServer = ConnectorPool.getConnection("account");
+        mRDServer = ConnectorPool.getConnection("rd");
     }
 
     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;
         }
@@ -89,18 +97,12 @@ public class ResourceFind extends Resource {
                         }
                     } else {
                         String additionalQuery = makeAdditionalQuery(
-                                payloadData, mSrcDevice.getDeviceId());
-                        if (additionalQuery == null) {
-                            mSrcDevice.sendResponse(
-                                    MessageBuilder.createResponse(mRequest,
-                                            ResponseStatus.BAD_REQUEST));
-                            return;
-                        }
+                                payloadData);
                         mRequest = MessageBuilder.modifyRequest(mRequest, null,
-                                additionalQuery
-                                        + (mRequest.getUriQuery() != null
-                                                ? ";" + mRequest.getUriQuery()
-                                                : ""),
+                                (mRequest.getUriQuery() != null
+                                        ? mRequest.getUriQuery() : "")
+                                        + (additionalQuery == null ? ""
+                                                : ";" + additionalQuery),
                                 null, null);
                     }
 
@@ -112,13 +114,16 @@ public class ResourceFind extends Resource {
             }
         }
 
-        private String makeAdditionalQuery(HashMap<String, Object> payloadData,
-                String did) {
+        private String makeAdditionalQuery(
+                HashMap<String, Object> payloadData) {
 
             StringBuilder additionalQuery = new StringBuilder();
-
             List<String> deviceList = getResponseDeviceList(payloadData);
 
+            if (deviceList == null) {
+                return null;
+            }
+
             if (deviceList.isEmpty()) {
                 return null;
             }
@@ -146,19 +151,26 @@ public class ResourceFind extends Resource {
     @Override
     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
             throws ServerException {
-        StringBuffer uriQuery = new StringBuffer();
-        uriQuery.append(Constants.REQ_MEMBER_ID + "=" + srcDevice.getUserId());
-
-        StringBuffer uriPath = new StringBuffer();
-        uriPath.append(Constants.PREFIX_OIC + "/");
-        uriPath.append(Constants.ACL_URI + "/");
-        uriPath.append(Constants.GROUP_URI + "/");
-        uriPath.append(srcDevice.getUserId());
-
-        IRequest requestToAS = MessageBuilder.createRequest(RequestMethod.GET,
-                uriPath.toString(), uriQuery.toString());
-
-        mASServer.sendRequest(requestToAS,
-                new AccountReceiveHandler(request, srcDevice));
+        if (request.getUriQuery() != null && request.getUriQueryMap()
+                .containsKey(Constants.REQ_DEVICE_ID)) {
+
+            mRDServer.sendRequest(request, srcDevice);
+        } else {
+            StringBuffer uriQuery = new StringBuffer();
+            uriQuery.append(
+                    Constants.REQ_MEMBER_ID + "=" + srcDevice.getUserId());
+
+            StringBuffer uriPath = new StringBuffer();
+            uriPath.append(Constants.PREFIX_OIC + "/");
+            uriPath.append(Constants.ACL_URI + "/");
+            uriPath.append(Constants.GROUP_URI + "/");
+            uriPath.append(srcDevice.getUserId());
+
+            IRequest requestToAS = MessageBuilder.createRequest(
+                    RequestMethod.GET, uriPath.toString(), uriQuery.toString());
+
+            mASServer.sendRequest(requestToAS,
+                    new AccountReceiveHandler(request, srcDevice));
+        }
     }
 }
\ No newline at end of file
index f8e232b..f708115 100644 (file)
@@ -40,6 +40,13 @@ import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ *
+ * This class provides a set of APIs to send requests about resource presence to
+ * resource directory
+ *
+ */
+
 public class ResourcePresence extends Resource {
     IRequestChannel                       mASServer = null;
     private Cbor<HashMap<String, Object>> mCbor     = new Cbor<>();
index 42943f6..1d58984 100644 (file)
@@ -56,18 +56,16 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 public class DevicePresenceTest {
-    public static final String DEVICE_PRS_REQ_URI  = Constants.DEVICE_PRESENCE_FULL_URI;
-    public static final String DEVICE_LIST_KEY     = "devices";
-    public static final String RES_PRS_URI         = Constants.RESOURCE_PRESENCE_FULL_URI;
-    private String             mDi                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
-    private CoapDevice         mMockDevice         = mock(CoapDevice.class);
-    private IRequest           mReq                = null;
-    private DeviceServerSystem mDeviceServerSystem = new DeviceServerSystem();
-    final CountDownLatch       mLatch              = new CountDownLatch(1);
+    private static final String DEVICE_PRS_REQ_URI  = Constants.DEVICE_PRESENCE_FULL_URI;
+    private String              mDi                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
+    private CoapDevice          mMockDevice         = mock(CoapDevice.class);
+    private IRequest            mReq                = null;
+    private DeviceServerSystem  mDeviceServerSystem = new DeviceServerSystem();
+    final CountDownLatch        mLatch              = new CountDownLatch(1);
     @Mock
-    private IRequestChannel    mRequestChannel;
+    private IRequestChannel     mRequestChannel;
     @InjectMocks
-    private DevicePresence     mPrsHandler         = new DevicePresence();
+    private DevicePresence      mPrsHandler         = new DevicePresence();
 
     @Before
     public void setUp() throws Exception {
index 708edd2..109b22a 100644 (file)
@@ -65,8 +65,10 @@ public class ResourceFindTest {
     private DeviceServerSystem  mDeviceServerSystem    = new DeviceServerSystem();
     final CountDownLatch        mLatch                 = new CountDownLatch(1);
 
-    @Mock
-    private IRequestChannel     mRequestChannel;
+    @Mock(name = "mRDServer")
+    IRequestChannel             mRequestChannelRDServer;
+    @Mock(name = "mASServer")
+    IRequestChannel             mRequestChannelASServer;
 
     @InjectMocks
     private ResourceFind        mResHandler            = new ResourceFind();
@@ -105,8 +107,27 @@ public class ResourceFindTest {
                 mLatch.countDown();
                 return null;
             }
-        }).when(mRequestChannel).sendRequest(Mockito.any(IRequest.class),
-                Mockito.any(CoapDevice.class));
+        }).when(mRequestChannelRDServer).sendRequest(
+                Mockito.any(IRequest.class), Mockito.any(CoapDevice.class));
+
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public CoapRequest answer(InvocationOnMock invocation)
+                    throws Throwable {
+                Object[] args = invocation.getArguments();
+                CoapRequest request = (CoapRequest) args[0];
+                System.out.println(
+                        "\t----------payload : " + request.getPayloadString());
+                System.out.println(
+                        "\t----------uripath : " + request.getUriPath());
+                System.out.println(
+                        "\t---------uriquery : " + request.getUriQuery());
+                mReq = request;
+                mLatch.countDown();
+                return null;
+            }
+        }).when(mRequestChannelASServer).sendRequest(
+                Mockito.any(IRequest.class), Mockito.any(CoapDevice.class));
     }
 
     // @InjectMocks for testSpecificDeviceonResponseReceived
@@ -181,7 +202,7 @@ public class ResourceFindTest {
         System.out.println(
                 "\t--------------OnRequestReceived(RD) Resource Find (entire deivces) Test------------");
         IRequest request = MessageBuilder.createRequest(RequestMethod.GET,
-                TEST_RESOURCE_FIND_URI, "rt=core.light;di=" + di);
+                TEST_RESOURCE_FIND_URI, "rt=core.light");
         mResHandler.onRequestReceived(mockDevice, request);
         HashMap<String, List<String>> queryMap = mReq.getUriQueryMap();
         assertTrue(mLatch.await(1L, SECONDS));
@@ -201,8 +222,8 @@ public class ResourceFindTest {
         // assertion: if the request packet from the CI contains the query
         // which includes device ID and the accesstoken
         assertTrue(mLatch.await(1L, SECONDS));
-        assertTrue(queryMap.containsKey("mid"));
-        assertEquals(mReq.getUriPath(), Constants.GROUP_FULL_URI + "/null");
+        assertTrue(queryMap.containsKey("di"));
+        assertEquals(mReq.getUriPath(), Constants.WELL_KNOWN_FULL_URI);
     }
 
     private IResponse responseFromAccountServer() {
index c28a978..9ed3e0a 100644 (file)
@@ -56,7 +56,6 @@ import org.mockito.stubbing.Answer;
 
 public class ResourcePresenceTest {
     public static final String DEVICE_PRS_REQ_URI = Constants.DEVICE_PRESENCE_FULL_URI;
-    public static final String DEVICE_LIST_KEY    = "devices";
     public static final String RES_PRS_URI        = Constants.RESOURCE_PRESENCE_FULL_URI;
     private String             mDi                = "B371C481-38E6-4D47-8320-7688D8A5B58C";
     private CoapDevice         mMockDevice        = mock(CoapDevice.class);
index 7947944..052bc14 100644 (file)
@@ -26,8 +26,23 @@ import java.util.HashMap;
 import org.iotivity.cloud.util.Cbor;
 import org.iotivity.cloud.util.Log;
 
+/**
+ * 
+ * This class provides a set of APIs of utilities for MessageQueue.
+ *
+ */
 public class MessageQueueUtils {
 
+    /**
+     * API to get data in the payload with specific property key
+     * 
+     * @param payload
+     *            payload received
+     * @param key
+     *            property key to get data
+     *
+     * @return extracted data in payload
+     */
     public static <T> T extractDataFromPayload(byte[] payload, String key) {
 
         if (payload == null || key.isEmpty()) {
@@ -48,6 +63,16 @@ public class MessageQueueUtils {
         return parsedData.get(key);
     }
 
+    /**
+     * API to build payload with property key and value
+     * 
+     * @param key
+     *            property key
+     * @param value
+     *            property value
+     *
+     * @return cbor encoded payload with providing key and value
+     */
     public static <T> byte[] buildPayload(String key, T value) {
 
         Cbor<HashMap<String, T>> cbor = new Cbor<>();
index a67f8c1..dfc9458 100644 (file)
@@ -32,6 +32,11 @@ import org.I0Itec.zkclient.ZkConnection;
 import org.iotivity.cloud.mqserver.Constants;
 import org.iotivity.cloud.util.Log;
 
+/**
+ *
+ * This class provides a set of APIs to use Kafka APIs for basic operation.
+ *
+ */
 public class KafkaCommonWrapper {
 
     private ZkClient mZkClient = null;
@@ -47,6 +52,15 @@ public class KafkaCommonWrapper {
                 false);
     }
 
+    /**
+     * API to create topic using Kafka utilities
+     * 
+     * @param topic
+     *            name of topic to create
+     * 
+     * @return returns true if the topic is successfully created, otherwise
+     *         false
+     */
     public boolean createTopic(String topic) {
 
         Log.d("kafka createTopic - " + topic);
@@ -64,6 +78,15 @@ public class KafkaCommonWrapper {
         return true;
     }
 
+    /**
+     * API to delete topic using Kafka utilities
+     * 
+     * @param topic
+     *            name of topic to delete
+     * 
+     * @return returns true if the topic is successfully deleted, otherwise
+     *         false
+     */
     public boolean deleteTopic(String topic) {
 
         Log.d("kafka deleteTopic - " + topic);
index 3ca503b..73e1e50 100644 (file)
@@ -54,6 +54,12 @@ import org.iotivity.cloud.mqserver.Constants;
 import org.iotivity.cloud.mqserver.topic.Topic;
 import org.iotivity.cloud.util.Log;
 
+/**
+ *
+ * This class provides a set of APIs to use Kafka consumer APIs for receiving
+ * messages.
+ *
+ */
 public class KafkaConsumerWrapper {
 
     private String            mTopicName         = null;
@@ -88,11 +94,21 @@ public class KafkaConsumerWrapper {
                 false);
     }
 
+    /**
+     * API to check if Kafka consumer is started
+     * 
+     * @return returns true if Kafka consumer started, otherwise false
+     */
     public boolean consumerStarted() {
         return mConsumerStarted;
     }
 
-    // TODO exception handling
+    /**
+     * API to subscribe Kafka topic to receive messages
+     * 
+     * @return returns true if the topic is successfully subscribed, otherwise
+     *         false
+     */
     public boolean subscribeTopic() {
 
         Log.d("kafka subscribeTopic - " + mTopicName);
@@ -148,6 +164,12 @@ public class KafkaConsumerWrapper {
         return true;
     }
 
+    /**
+     * API to unsubscribe Kafka topic to stop receiving messages
+     * 
+     * @return returns true if the topic is successfully unsubscribed, otherwise
+     *         false
+     */
     public boolean unsubscribeTopic() {
 
         Log.d("kafka unsubscribeTopic - " + mTopicName);
@@ -168,6 +190,9 @@ public class KafkaConsumerWrapper {
         return true;
     }
 
+    /**
+     * API to close Kafka consumer connection
+     */
     public void closeConnection() {
 
         if (mConsumerStarted == true) {
@@ -178,6 +203,11 @@ public class KafkaConsumerWrapper {
         mZkClient.close();
     }
 
+    /**
+     * API to get all messages from Kafka topic
+     * 
+     * @return returns the list of messages published to the topic
+     */
     public ArrayList<byte[]> getMessages() {
 
         Log.d("kafka get all messages - " + mTopicName);
index 9b3f2c1..164baf9 100644 (file)
@@ -28,6 +28,12 @@ import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerRecord;
 import org.iotivity.cloud.util.Log;
 
+/**
+ *
+ * This class provides a set of APIs to use Kafka producer APIs for publishing
+ * messages.
+ *
+ */
 public class KafkaProducerWrapper {
 
     private String                   mTopicName = null;
@@ -44,7 +50,15 @@ public class KafkaProducerWrapper {
         mProducer = new KafkaProducer<>(buildPropertiesForPublish());
     }
 
-    // TODO handle exception
+    /**
+     * API to publish message to Kafka topic
+     * 
+     * @param message
+     *            message to publish
+     * 
+     * @return returns true if the message is successfully published, otherwise
+     *         false
+     */
     public boolean publishMessage(byte[] message) {
 
         Log.d("kafka publishMessage - " + mTopicName);
@@ -58,6 +72,9 @@ public class KafkaProducerWrapper {
         return true;
     }
 
+    /**
+     * API to close Kafka producer connection
+     */
     public void closeConnection() {
 
         mProducer.close();
index 5b67c3f..4d07cdc 100644 (file)
@@ -43,6 +43,11 @@ import org.iotivity.cloud.mqserver.MessageQueueUtils;
 import org.iotivity.cloud.mqserver.topic.Topic;
 import org.iotivity.cloud.mqserver.topic.TopicManager;
 
+/**
+ * 
+ * This class provides a set of APIs to handle requests to MessageQueue Broker.
+ *
+ */
 public class MQBrokerResource extends Resource {
 
     private TopicManager mTopicManager = new TopicManager();
@@ -51,6 +56,14 @@ public class MQBrokerResource extends Resource {
         super(Arrays.asList(Constants.PREFIX_OIC, Constants.MQ_BROKER_URI));
     }
 
+    /**
+     * API to set Kafka zookeeper and broker information
+     * 
+     * @param zookeeper
+     *            address and port number of the zookeeper
+     * @param broker
+     *            address and port number of the Kafka broker
+     */
     public void setKafkaInformation(String zookeeper, String broker) {
         mTopicManager.setKafkaInformation(zookeeper, broker);
     }
@@ -83,8 +96,7 @@ public class MQBrokerResource extends Resource {
     private IResponse handleGetRequest(Device srcDevice, IRequest request) {
 
         // DISCOVER
-        if (request.getUriPathSegments().size() == getUriPathSegments()
-                .size()) {
+        if (request.getUriPathSegments().size() == getUriPathSegments().size()) {
             return discoverTopic(request);
         }
 
@@ -106,8 +118,7 @@ public class MQBrokerResource extends Resource {
     // CREATE topic
     private IResponse handlePutRequest(IRequest request) {
 
-        if (request.getUriPathSegments().size() == getUriPathSegments()
-                .size()) {
+        if (request.getUriPathSegments().size() == getUriPathSegments().size()) {
 
             throw new BadRequestException(
                     "topic name is not included in request uri");
@@ -131,8 +142,7 @@ public class MQBrokerResource extends Resource {
     private IResponse createTopic(IRequest request) {
 
         // main topic creation request
-        if (request.getUriPathSegments().size() == getUriPathSegments().size()
-                + 1) {
+        if (request.getUriPathSegments().size() == getUriPathSegments().size() + 1) {
             return createMainTopic(request);
         }
 
@@ -161,8 +171,8 @@ public class MQBrokerResource extends Resource {
         String uriPath = request.getUriPath();
 
         String parentName = uriPath.substring(0, uriPath.lastIndexOf('/'));
-        String targetName = request.getUriPathSegments()
-                .get(request.getUriPathSegments().size() - 1);
+        String targetName = request.getUriPathSegments().get(
+                request.getUriPathSegments().size() - 1);
 
         Topic parentTopic = mTopicManager.getTopic(parentName);
 
@@ -233,14 +243,14 @@ public class MQBrokerResource extends Resource {
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
-                ContentFormat.APPLICATION_CBOR, MessageQueueUtils
-                        .buildPayload(Constants.MQ_TOPICLIST, topicList));
+                ContentFormat.APPLICATION_CBOR, MessageQueueUtils.buildPayload(
+                        Constants.MQ_TOPICLIST, topicList));
     }
 
     private IResponse createMainTopic(IRequest request) {
 
-        String topicName = request.getUriPathSegments()
-                .get(request.getUriPathSegments().size() - 1);
+        String topicName = request.getUriPathSegments().get(
+                request.getUriPathSegments().size() - 1);
 
         String type = new String();
 
index 4458a35..28dc14e 100644 (file)
@@ -39,6 +39,11 @@ import org.iotivity.cloud.mqserver.kafka.KafkaConsumerWrapper;
 import org.iotivity.cloud.mqserver.kafka.KafkaProducerWrapper;
 import org.iotivity.cloud.util.Cbor;
 
+/**
+ * 
+ * This class provides a set of APIs to handle requests to MessageQueue Topic.
+ *
+ */
 public class Topic {
 
     private TopicManager           mTopicManager = null;
@@ -88,18 +93,36 @@ public class Topic {
         mLatestData = mCbor.encodingPayloadToCbor(data);
     }
 
+    /**
+     * API to get name of the topic
+     * 
+     * @return name of the topic
+     */
     public String getName() {
         return mName;
     }
 
+    /**
+     * API to get type of the topic
+     * 
+     * @return type of the topic
+     */
     public String getType() {
         return mType;
     }
 
+    /**
+     * API to handle request to create subtopic
+     * 
+     * @param request
+     *            received request for subtopic creation
+     * 
+     * @return response of subtopic creation
+     */
     public IResponse handleCreateSubtopic(IRequest request) {
 
-        String newTopicName = request.getUriPathSegments()
-                .get(request.getUriPathSegments().size() - 1);
+        String newTopicName = request.getUriPathSegments().get(
+                request.getUriPathSegments().size() - 1);
 
         String newTopicType = new String();
 
@@ -128,6 +151,16 @@ public class Topic {
         return response;
     }
 
+    /**
+     * API to handle request to remove subtopic
+     * 
+     * @param request
+     *            received request for subtopic removal
+     * @param topicName
+     *            subtopic name to remove
+     * 
+     * @return response of subtopic removal
+     */
     public IResponse handleRemoveSubtopic(IRequest request, String topicName) {
 
         Topic targetTopic = getSubtopic(topicName);
@@ -149,6 +182,16 @@ public class Topic {
         return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
     }
 
+    /**
+     * API to handle request to subscribe the topic
+     * 
+     * @param srcDevice
+     *            device that sent request for topic subscription
+     * @param request
+     *            received request for topic subscription
+     * 
+     * @return response of topic subscription
+     */
     public IResponse handleSubscribeTopic(Device srcDevice, IRequest request) {
 
         // get latest data from kafka if consumer started for the first time
@@ -166,20 +209,28 @@ public class Topic {
         }
 
         synchronized (mSubscribers) {
-            mSubscribers.put(request.getRequestId(),
-                    new TopicSubscriber(srcDevice, request));
+            mSubscribers.put(request.getRequestId(), new TopicSubscriber(
+                    srcDevice, request));
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
                 ContentFormat.APPLICATION_CBOR, mLatestData);
     }
 
+    /**
+     * API to handle request to unsubscribe the topic
+     * 
+     * @param request
+     *            received request for topic unsubscription
+     * 
+     * @return response of topic unsubscription
+     */
     public IResponse handleUnsubscribeTopic(IRequest request) {
 
         synchronized (mSubscribers) {
 
-            TopicSubscriber subscriber = mSubscribers
-                    .get(request.getRequestId());
+            TopicSubscriber subscriber = mSubscribers.get(request
+                    .getRequestId());
 
             mSubscribers.remove(subscriber.mRequest.getRequestId());
 
@@ -194,6 +245,14 @@ public class Topic {
                 ContentFormat.APPLICATION_CBOR, mLatestData);
     }
 
+    /**
+     * API to handle request to publish message to the topic
+     * 
+     * @param request
+     *            received request for message publication
+     * 
+     * @return response of message publication
+     */
     public IResponse handlePublishMessage(IRequest request) {
         byte[] payload = request.getPayload();
 
@@ -217,6 +276,14 @@ public class Topic {
         return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
     }
 
+    /**
+     * API to handle request to read latest message in the topic
+     * 
+     * @param request
+     *            received request for reading latest message in topic
+     * 
+     * @return response of reading latest message in topic
+     */
     public IResponse handleReadMessage(IRequest request) {
         // if consumer is not started, get data from kafka broker
         if (mKafkaConsumerOperator.consumerStarted() == false) {
@@ -232,13 +299,21 @@ public class Topic {
                 ContentFormat.APPLICATION_CBOR, mLatestData);
     }
 
+    /**
+     * API to close connection of Kafka producer and consumer
+     */
     public void cleanup() {
 
         mKafkaProducerOperator.closeConnection();
         mKafkaConsumerOperator.closeConnection();
     }
 
-    // callback from Kafka Consumer
+    /**
+     * callback from Kafka Consumer to get published message
+     * 
+     * @param message
+     *            published message
+     */
     public void onMessagePublished(byte[] message) {
 
         mLatestData = message;
@@ -261,8 +336,8 @@ public class Topic {
         synchronized (mSubscribers) {
             for (TopicSubscriber subscriber : mSubscribers.values()) {
 
-                subscriber.mSubscriber.sendResponse(
-                        MessageBuilder.createResponse(subscriber.mRequest,
+                subscriber.mSubscriber.sendResponse(MessageBuilder
+                        .createResponse(subscriber.mRequest,
                                 ResponseStatus.CONTENT,
                                 ContentFormat.APPLICATION_CBOR, mLatestData));
             }
index c36a510..5280915 100644 (file)
@@ -25,6 +25,11 @@ import java.util.ArrayList;
 
 import org.iotivity.cloud.mqserver.kafka.KafkaCommonWrapper;
 
+/**
+ *
+ * This class provides a set of APIs to manage topics in MessageQueue Broker
+ *
+ */
 public class TopicManager {
 
     private ArrayList<Topic>   mTopics              = new ArrayList<>();
@@ -35,6 +40,14 @@ public class TopicManager {
 
     private KafkaCommonWrapper mKafkaCommonOperator = null;
 
+    /**
+     * API to create topic
+     * 
+     * @param topic
+     *            topic to create
+     * 
+     * @return returns true if the topic successfully created, otherwise false
+     */
     public boolean createTopic(Topic topic) {
 
         if (mKafkaCommonOperator.createTopic(topic.getName()) == false) {
@@ -48,11 +61,24 @@ public class TopicManager {
         return true;
     }
 
+    /**
+     * API to remove topic
+     * 
+     * @param topic
+     *            topic to remove
+     * 
+     * @return returns true if the topic successfully removed, otherwise false
+     */
     public boolean removeTopic(Topic topic) {
 
         return removeTopics(topic.getName());
     }
 
+    /**
+     * API to get list of topics
+     * 
+     * @return returns list of topic uris
+     */
     public ArrayList<String> getTopicList() {
 
         ArrayList<String> topicList = new ArrayList<>();
@@ -66,6 +92,14 @@ public class TopicManager {
         return topicList;
     }
 
+    /**
+     * API to get list of topics with specific topic type
+     * 
+     * @param type
+     *            topic type
+     * 
+     * @return returns list of topic uris searched with the topic type
+     */
     public ArrayList<String> getTopicListByType(String type) {
 
         ArrayList<String> topicList = new ArrayList<>();
@@ -82,6 +116,14 @@ public class TopicManager {
         return topicList;
     }
 
+    /**
+     * API to get topic with topic name
+     * 
+     * @param topicName
+     *            topic name to search
+     * 
+     * @return topic searched with the topic name
+     */
     public Topic getTopic(String topicName) {
 
         Topic foundTopic = null;
@@ -99,6 +141,14 @@ public class TopicManager {
         return foundTopic;
     }
 
+    /**
+     * API to set Kafka zookeeper and broker information
+     * 
+     * @param zookeeper
+     *            address and port number of the zookeeper
+     * @param broker
+     *            address and port number of the Kafka broker
+     */
     public void setKafkaInformation(String zookeeper, String broker) {
         mKafkaZookeeper = zookeeper;
         mKafkaBroker = broker;
@@ -106,10 +156,20 @@ public class TopicManager {
         mKafkaCommonOperator = new KafkaCommonWrapper(zookeeper, broker);
     }
 
+    /**
+     * API to get zookeeper information
+     * 
+     * @return address and port number of the zookeeper
+     */
     public String getKafkaZookeeper() {
         return mKafkaZookeeper;
     }
 
+    /**
+     * API to get Kafka broker information
+     * 
+     * @return address and port number of the Kafka broker
+     */
     public String getKafkaBroker() {
         return mKafkaBroker;
     }
index 6a3f102..ef8d1f4 100644 (file)
@@ -35,6 +35,13 @@ import java.util.HashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import kafka.admin.TopicCommand;
+import kafka.admin.TopicCommand.TopicCommandOptions;
+import kafka.utils.ZKStringSerializer$;
+import kafka.utils.ZkUtils;
+
+import org.I0Itec.zkclient.ZkClient;
+import org.I0Itec.zkclient.ZkConnection;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.exception.ServerException.ForbiddenException;
 import org.iotivity.cloud.base.exception.ServerException.NotFoundException;
@@ -50,6 +57,7 @@ import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.mqserver.Constants;
 import org.iotivity.cloud.util.Cbor;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -65,17 +73,17 @@ public class MQBrokerResourceTest {
     IResponse                mResponse         = null;
     CountDownLatch           mLatch            = null;
 
+    // insert user's zookeper and broker addresses
+    String                   mZookeeper        = "127.0.0.1:2181";
+    String                   mBroker           = "127.0.0.1:9092";
+
     @Before
     // setup for each test
     public void setUp() throws Exception {
         mMqBrokerResource = new MQBrokerResource();
 
-        // insert user's zookeper and broker addresses
-        String zookeeper = "127.0.0.1:2181";
-        String broker = "127.0.0.1:9092";
-
         mTopicPrefix = "mqtestTopic";
-        mMqBrokerResource.setKafkaInformation(zookeeper, broker);
+        mMqBrokerResource.setKafkaInformation(mZookeeper, mBroker);
         mLatch = new CountDownLatch(1);
         mResponse = null; // initialize response packet
         mMockDevice = mock(CoapDevice.class);
@@ -94,6 +102,25 @@ public class MQBrokerResourceTest {
         }).when(mMockDevice).sendResponse(Mockito.anyObject());
     }
 
+    @After
+    public void tearDown() throws Exception {
+        // delete topics in Kafka broker
+        ZkClient zkClient = new ZkClient(mZookeeper, 10000, 10000,
+                ZKStringSerializer$.MODULE$);
+        ZkUtils zkUtils = new ZkUtils(zkClient, new ZkConnection(mZookeeper),
+                false);
+
+        String topic = MQ_BROKER_URI + "/*";
+        topic = topic.replace('/', '.');
+
+        String[] arr = { "--topic", topic };
+        TopicCommandOptions opts = new TopicCommandOptions(arr);
+        TopicCommand.deleteTopic(zkUtils, opts);
+
+        zkClient.close();
+        zkUtils.close();
+    }
+
     @Test
     // test topic creation
     public void testTopicCreationOnDefaultRequestReceived() throws Exception {
@@ -251,6 +278,8 @@ public class MQBrokerResourceTest {
                 if (latchSubscriber.getCount() == 0) {
                     assertTrue(methodCheck(resp, ResponseStatus.CONTENT));
                     assertTrue(hashmapCheck(resp, "message"));
+
+                    DeleteTopic(mMockDevice, topic);
                 }
                 return resp;
             }
index 57ef745..f4789bf 100644 (file)
  */
 package org.iotivity.cloud.rdserver;
 
-import java.util.Arrays;
-import java.util.List;
-
 import org.iotivity.cloud.base.OICConstants;
 
 public class Constants extends OICConstants {
 
-    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       PRESENCE_LIST           = "prslist";
+    /** Database, Table name */
+    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       RS_NON                  = "non";
-    public static final String       RS_TRIGGER              = "trg";
+    /** A human friendly name of device */
+    public static final String DEVICE_NAME             = "n";
+    /** An unique identifier of device */
+    public static final String DEVICE_ID               = "di";
+    /** policies that apply for resource */
+    public static final String POLICY                  = "p";
+    /** To represent bitmap. */
+    public static final String BITMAP                  = "bm";
+    /** An ordinal number that is not repeated */
+    public static final String INS                     = "ins";
+    /** Time (in seconds) to indicate how long RD should publish this item */
+    public static final String DEVICE_TTL              = "lt";
+    /** Time to live for this link */
+    public static final String RESOURCE_TTL            = "ttl";
+    /** URI Reference */
+    public static final String HREF                    = "href";
+    /** Resource Types */
+    public static final String RESOURCE_TYPE           = "rt";
+    /** Resource interface */
+    public static final String INTERFACE               = "if";
+    /** Relation between target URI and context URI */
+    public static final String REL                     = "rel";
+    /** Title for the link relation */
+    public static final String TITLE                   = "title";
+    /** This is used to override the context URI */
+    public static final String ANCHOR                  = "anchor";
+    /** Media type. Default : application/json */
+    public static final String MEDIA_TYPE              = "type";
+    /** To represent links. */
+    public static final String LINKS                   = "links";
+    /** To represent resource type with Publish RD. */
+    public static final String RESOURCE_TYPE_RDPUBLISH = "oic.wk.rdpub";
 
-    public static final long         OBSERVE_REGISTER        = 0;
-    public static final long         OBSERVE_DEREGISTER      = 1;
+    /** '/oic/prs' resource property */
+    public static final String PRESENCE_STATE          = "state";
+    public static final String PRESENCE_ON             = "on";
+    public static final String PRESENCE_OFF            = "off";
+    public static final String PRESENCE_LIST           = "prslist";
+    public static final String DEVICE_PRESENCE         = "device_presence";
 
-    public static final byte         RES_CREATE              = 0;
-    public static final byte         RES_CHANGE              = 1;
-    public static final byte         RES_DELETE              = 2;
+    /** '/oic/ad' resource property */
+    public static final String NON                     = "non";
+    public static final String TRIGGER                 = "trg";
+    public static final byte   RES_CREATE              = 0;
+    public static final byte   RES_CHANGE              = 1;
+    public static final byte   RES_DELETE              = 2;
+    public static final String RESOURCE_PRESENCE       = "resource_presence";
 
 }
index 16fccc3..b5f41c2 100644 (file)
@@ -32,6 +32,11 @@ import org.iotivity.cloud.rdserver.resources.presence.device.DevicePresenceResou
 import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresenceResource;
 import org.iotivity.cloud.util.Log;
 
+/**
+ *
+ * This class is in charge of running of resource directory server.
+ *
+ */
 public class ResourceDirectoryServer {
 
     public static void main(String[] args) throws Exception {
@@ -40,8 +45,7 @@ public class ResourceDirectoryServer {
         System.out.println("-----RD SERVER-----");
 
         if (args.length != 2) {
-            Log.e("coap server port and TLS mode required\n"
-                    + "ex) 5684 0\n");
+            Log.e("coap server port and TLS mode required\n" + "ex) 5684 0\n");
             return;
         }
 
index aefb1bb..734c52f 100644 (file)
@@ -23,65 +23,226 @@ 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.base.exception.ServerException.InternalServerErrorException;
 import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
 
+/**
+ *
+ * This class provides a set of APIs to access a DataBase.
+ *
+ */
 public class DBManager {
 
-    private static DBManager mDBManager = new DBManager();
-    private MongoDB          mMongoDB   = null;;
+    private static DBManager                   mDBManager = new DBManager();
+    private MongoDB                            mMongoDB   = null;
+    private HashMap<String, ArrayList<String>> mKeyField  = new HashMap<>();
 
     private DBManager() {
+        createDatabase();
+        createTables();
+        createIndexes();
+    }
+
+    /**
+     * API to return DBManager object
+     * 
+     * @return DBManager DBManager object
+     */
+    public static DBManager getInstance() {
+        return mDBManager;
+    }
+
+    private void createDatabase() {
+
         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();
+            throw new InternalServerErrorException("Database create failed!");
         }
     }
 
-    public static DBManager getInstance() {
-        return mDBManager;
+    private void createTables() {
+        mMongoDB.createTable(Constants.RD_TABLE);
+        mMongoDB.createTable(Constants.PRESENCE_TABLE);
+    }
+
+    private void createIndexes() {
+
+        ArrayList<String> keys = new ArrayList<>();
+        keys.add(Constants.DEVICE_ID);
+        keys.add(Constants.INS);
+
+        mMongoDB.createIndex(Constants.RD_TABLE, keys);
+        mKeyField.put(Constants.RD_TABLE, keys);
+
+        keys = new ArrayList<>();
+        keys.add(Constants.DEVICE_ID);
+
+        mMongoDB.createIndex(Constants.PRESENCE_TABLE, keys);
+        mKeyField.put(Constants.PRESENCE_TABLE, keys);
+
+    }
+
+    /**
+     * API for inserting a record into DB table. the record will not be inserted
+     * if duplicated one.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param insert
+     *            record to be inserted
+     */
+    public void insertRecord(String tableName, HashMap<String, Object> insert) {
+
+        if (!_insertRecord(tableName, insert))
+            throw new InternalServerErrorException(
+                    "Database record insert failed");
+    }
+
+    /**
+     * API for inserting a record into DB table. the record will be replaced if
+     * duplicated one.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param replace
+     *            record to be inserted
+     */
+    public void insertAndReplaceRecord(String tableName,
+            HashMap<String, Object> replace) {
+
+        if (!_insertAndReplaceRecord(tableName, replace))
+            throw new InternalServerErrorException(
+                    "Database record insert failed");
+    }
+
+    /**
+     * API for selecting records from DB table.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param condition
+     *            condition record to be selected
+     * @return selected records
+     */
+    public ArrayList<HashMap<String, Object>> selectRecord(String tableName,
+            HashMap<String, Object> condition) {
+
+        return _selectRecord(tableName, condition);
     }
 
-    public ArrayList<ResPresencePayload> registerResource(
-            ArrayList<HashMap<Object, Object>> pubResourceList) {
-        return mMongoDB.createRDResource(pubResourceList, Constants.RD_TABLE);
+    /**
+     * API for deleting records from DB table.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param condition
+     *            condition record to be deleted
+     */
+    public void deleteRecord(String tableName,
+            HashMap<String, Object> condition) {
+
+        if (!_deleteRecord(tableName, condition))
+            throw new InternalServerErrorException(
+                    "Database record delete failed");
     }
 
-    public ArrayList<HashMap<Object, Object>> findResourceAboutDi(String di) {
-        return mMongoDB.readResourceAboutDid(di, Constants.RD_TABLE);
+    /**
+     * API for updating a record into DB table.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param replace
+     *            record to be updated
+     */
+    public void updateRecord(String tableName,
+            HashMap<String, Object> replace) {
+
+        if (!_updateRecord(tableName, replace))
+            throw new InternalServerErrorException(
+                    "Database record update failed");
+
     }
-    
-    public ArrayList<HashMap<Object, Object>> findResourceAboutDiAndFilter(String di,
-            String key, String value) {
-        return mMongoDB.readResourceAboutDidAndFilter(di, key, value,
-                Constants.RD_TABLE);
+
+    private Boolean _insertRecord(String tableName,
+            HashMap<String, Object> record) {
+
+        Document doc = createDocument(record);
+
+        return mMongoDB.insertRecord(tableName, doc);
     }
 
-    public ArrayList<ResPresencePayload> deleteResourceAboutDi(String di) {
-        return mMongoDB.deleteResourceAboutDi(di, Constants.RD_TABLE);
+    private Boolean _insertAndReplaceRecord(String tableName,
+            HashMap<String, Object> record) {
+
+        Document doc = createDocument(record);
+        Document filter = getKeyFilter(tableName, record);
+
+        return mMongoDB.insertAndReplaceRecord(tableName, filter, doc);
     }
 
-    public ArrayList<ResPresencePayload> deleteResourceAboutDiAandIns(String di,
-            String ins) {
-        return mMongoDB.deleteResourceAboutDiAndIns(di, ins,
-                Constants.RD_TABLE);
+    private Boolean _deleteRecord(String tableName,
+            HashMap<String, Object> condition) {
+
+        Document doc = createDocument(condition);
+
+        return mMongoDB.deleteRecord(tableName, doc);
     }
 
-    public Object findInsAboutDi(String di, String href) {
-        return mMongoDB.readInsAboutDid(di, href, Constants.RD_TABLE);
+    private Boolean _updateRecord(String tableName,
+            HashMap<String, Object> record) {
+
+        Document replace = createDocument(record);
+        Document filter = getKeyFilter(tableName, record);
+
+        return mMongoDB.updateRecord(tableName, filter, replace);
     }
 
-    public void updateDeviceState(HashMap<Object, Object> deviceState) {
-        mMongoDB.createDevicePresenceResource(deviceState,
-                Constants.PRESENCE_TABLE);
+    private ArrayList<HashMap<String, Object>> _selectRecord(String tableName,
+            HashMap<String, Object> record) {
+
+        Document doc = createDocument(record);
+
+        return mMongoDB.selectRecord(tableName, doc);
     }
 
-    public String findDeviceState(String deviceId) {
-        return mMongoDB.readDeviceState(deviceId, Constants.PRESENCE_TABLE);
+    private Document getKeyFilter(String tableName,
+            HashMap<String, Object> record) {
+
+        Document filterDoc = new Document();
+
+        ArrayList<String> keys = mKeyField.get(tableName);
+
+        for (String key : keys) {
+
+            Object value = record.get(key);
+            filterDoc.append(key, value);
+        }
+
+        return filterDoc;
     }
-}
+
+    private Document createDocument(HashMap<String, Object> record) {
+
+        Document doc = new Document();
+        Set<Entry<String, Object>> resEntrySet = record.entrySet();
+        Iterator<Entry<String, Object>> entryIter = resEntrySet.iterator();
+
+        while (entryIter.hasNext()) {
+            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) entryIter
+                    .next();
+            doc.append(entry.getKey().toString(), entry.getValue());
+        }
+
+        return doc;
+    }
+
+}
\ No newline at end of file
index ff48f63..d15100c 100644 (file)
@@ -29,14 +29,13 @@ 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 org.iotivity.cloud.util.Log;
 
 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;
+import com.mongodb.client.model.IndexOptions;
 
 /**
  *
@@ -56,298 +55,232 @@ public class MongoDB {
      * @throws Exception
      */
     public MongoDB(String dbname) throws Exception {
+
         mongoClient = new MongoClient();
         mongoClient.dropDatabase(dbname);
         db = mongoClient.getDatabase(dbname);
     }
 
     /**
-     * API creating collection
+     * API for creating collection
      *
      * @param tableName
      *            collection name
      */
     public void createTable(String tableName) {
-        deleteTable(tableName);
+
         db.createCollection(tableName);
     }
 
     /**
-     * API deleting collection
+     * API for creating index
      *
      * @param tableName
      *            collection name
+     * @param keys
+     *            key fields of collection
      */
-    public void deleteTable(String tableName) {
-        db.getCollection(tableName).drop();
-    }
-
-    private Document createDocument(HashMap<Object, Object> storeRes) {
+    public void createIndex(String tablename, ArrayList<String> keys) {
 
         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) {
+        for (String key : keys) {
 
-        Iterator<HashMap<Object, Object>> resListIter = storeResList.iterator();
-
-        ArrayList<Document> docList = new ArrayList<>();
+            doc.append(key, 1);
+        }
 
-        while (resListIter.hasNext()) {
-            Document doc = new Document();
+        IndexOptions options = new IndexOptions();
+        options.unique(true);
 
-            HashMap<Object, Object> storeRes = resListIter.next();
-            Set<Entry<Object, Object>> resEntrySet = storeRes.entrySet();
-            Iterator<Entry<Object, Object>> entryIter = resEntrySet.iterator();
+        db.getCollection(tablename).createIndex(doc, options);
+    }
 
-            while (entryIter.hasNext()) {
-                Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) entryIter
-                        .next();
-                doc.append(entry.getKey().toString(), entry.getValue());
-            }
-            docList.add(doc);
-        }
+    /**
+     * API for deleting collection
+     *
+     * @param tableName
+     *            collection name
+     */
+    public void deleteTable(String tableName) {
 
-        return docList;
+        db.getCollection(tableName).drop();
     }
 
-    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());
-            }
-        }
+    /**
+     * API for getting database object
+     *
+     */
+    public MongoDatabase getMongoDatabase() {
 
-        return resourceMap;
+        return db;
     }
 
     /**
-     * API for storing information of published resources
-     *
-     * @param publishPayloadFormat
-     *            information of published resources to store in collection
+     * API for inserting a record into DB table. the record will not be inserted
+     * if duplicated one.
+     * 
      * @param tableName
-     *            collection name
+     *            table name to be inserted
+     * @param doc
+     *            document to be inserted
      */
-    public ArrayList<ResPresencePayload> createRDResource(
-            ArrayList<HashMap<Object, Object>> storeResList, String tableName) {
-        ArrayList<Document> docList = createDocuments(storeResList);
-        Iterator<Document> docIter = docList.iterator();
+    public Boolean insertRecord(String tableName, Document doc) {
+
+        if (tableName == null || doc == null)
+            return false;
 
         MongoCollection<Document> collection = db.getCollection(tableName);
 
-        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+        try {
 
-        while (docIter.hasNext()) {
-            Document doc = docIter.next();
-            byte trigger = 0;
+            if (collection.find(doc).first() == null) {
 
-            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;
 
+                Log.w("DB insert failed due to duplecated one.");
+                return false;
             }
 
-            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) {
+        } catch (Exception e) {
 
-            collection.insertOne(doc);
+            e.printStackTrace();
+            return false;
         }
 
-        return;
-    }
-
-    private ResPresencePayload makeResourcePresencePayload(Document doc,
-            byte trigger) {
-
-        ResPresencePayload resPayload = new ResPresencePayload();
-
-        resPayload.setTrg(trigger);
+        showRecord(tableName);
 
-        Object rt = doc.get(Constants.RESOURCE_TYPE);
-        if (rt != null) {
-            resPayload.setRt(rt.toString());
-        }
-        Object href = doc.get(Constants.HREF);
-        if (href != 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;
+        return true;
     }
 
-    public String readDeviceState(String deviceId, String tableName) {
+    /**
+     * API for inserting a record into DB table. the record will be replaced if
+     * duplicated one.
+     * 
+     * @param tableName
+     *            table name to be inserted
+     * @param filter
+     *            document filter
+     * @param doc
+     *            document to be inserted
+     * @return returns true if the record is inserted and replaced successfully,
+     *         or returns false
+     */
+    public Boolean insertAndReplaceRecord(String tableName, Document filter,
+            Document doc) {
 
-        String deviceState = null;
+        if (tableName == null || filter == null || doc == null)
+            return false;
 
         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;
+            if (collection.findOneAndReplace(filter, doc) == null) {
+
+                collection.insertOne(doc);
             }
 
-        } finally {
+        } catch (Exception e) {
 
-            cursor.close();
+            e.printStackTrace();
+            return false;
         }
 
-        return deviceState;
+        showRecord(tableName);
+
+        return true;
     }
 
-    public ArrayList<HashMap<Object, Object>> readResourceAboutDid(String di, String tableName) {
+    /**
+     * API for updating a record into DB table.
+     * 
+     * @param tableName
+     *            table name to be updated
+     * @param filter
+     *            document filter
+     * @param record
+     *            record to be updated
+     * @return returns true if the record is updated successfully, or returns
+     *         false
+     */
+    public Boolean updateRecord(String tableName, Document filter,
+            Document record) {
+
+        if (tableName == null || filter == null || record == null)
+            return false;
+
         MongoCollection<Document> collection = db.getCollection(tableName);
-        ArrayList<HashMap<Object, Object>> resList = null;
-        MongoCursor<Document> cursor = collection
-                .find(Filters.eq(Constants.DEVICE_ID, di))
-                .iterator();
-
-        if (cursor.hasNext()) {
-            resList = new ArrayList<>();
-            try {
-                while (cursor.hasNext()) {
-                    Document doc = cursor.next();
-                    resList.add(convertDocumentToHashMap(doc));
-                }
-            } finally {
-                cursor.close();
-            }
+
+        if (collection.findOneAndReplace(filter, record) == null) {
+
+            Log.w("DB update failed due to no matched record!");
+            return false;
         }
 
-        return resList;
+        showRecord(tableName);
+
+        return true;
     }
 
     /**
-     * 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
+     * API for deleting records from DB table.
+     * 
      * @param tableName
-     *            collection name
-     * @return ArrayList<PublishPayloadFormat> - array list of resource
-     *         information
+     *            table name for the record to be deleted
+     * @param record
+     *            record filter to be deleted
+     * @return returns true if the record is deleted successfully, or returns
+     *         false
      */
-    public ArrayList<HashMap<Object, Object>> readResourceAboutDidAndFilter(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();
-            }
-        }
+    public Boolean deleteRecord(String tableName, Document record) {
 
-        return resList;
-    }
+        if (tableName == null || record == null)
+            return false;
 
-    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();
+
+            collection.deleteMany(record);
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            return false;
         }
-        return null;
+
+        showRecord(tableName);
+
+        return true;
     }
 
     /**
-     * API for deleting resources about a particular device ID in collection
-     *
-     * @param di
-     *            device id
+     * API for selecting records from DB table.
+     * 
      * @param tableName
-     *            collection name
+     *            table name for the record to be selected
+     * @param doc
+     *            document filter to be selected
+     * @return record list according to the filter document
      */
-    public ArrayList<ResPresencePayload> deleteResourceAboutDi(String di,
-            String tableName) {
+    public ArrayList<HashMap<String, Object>> selectRecord(String tableName,
+            Document doc) {
 
-        MongoCollection<Document> collection = db.getCollection(tableName);
+        if (tableName == null || doc == null)
+            return null;
 
-        MongoCursor<Document> cursor = collection
-                .find(Filters.eq(Constants.DEVICE_ID, di)).iterator();
+        MongoCollection<Document> collection = db.getCollection(tableName);
+        MongoCursor<Document> cursor = collection.find(doc).iterator();
 
-        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+        ArrayList<HashMap<String, Object>> recordList = new ArrayList<>();
 
         try {
+
             while (cursor.hasNext()) {
-                Document doc = cursor.next();
-                resPayloadList.add(
-                        makeResourcePresencePayload(doc, Constants.RES_DELETE));
+                Document selectedDoc = cursor.next();
+                recordList.add(convertDocumentToHashMap(selectedDoc));
             }
 
         } finally {
@@ -355,50 +288,50 @@ public class MongoDB {
             cursor.close();
         }
 
-        collection.deleteMany(Filters.eq(Constants.DEVICE_ID, di));
-
-        return resPayloadList;
+        return recordList;
     }
 
-    /**
-     * 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) {
+    private HashMap<String, Object> convertDocumentToHashMap(Document doc) {
+        HashMap<String, Object> resourceMap = new HashMap<>();
 
-        MongoCollection<Document> collection = db.getCollection(tableName);
+        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();
 
-        MongoCursor<Document> cursor = collection
-                .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
-                        Filters.eq(Constants.INS, ins)))
-                .iterator();
+            String entryKey = entry.getKey();
 
-        ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
+            // remove a mongoDB index
+            if (entry.getValue() != null && !entryKey.equals("_id")) {
 
-        try {
-            while (cursor.hasNext()) {
-                Document doc = cursor.next();
-                resPayloadList.add(
-                        makeResourcePresencePayload(doc, Constants.RES_DELETE));
+                resourceMap.put(entry.getKey(), entry.getValue());
             }
+        }
 
-        } finally {
+        return resourceMap;
+    }
 
-            cursor.close();
-        }
+    private void showRecord(String tableName) {
+
+        MongoCollection<Document> collection = db.getCollection(tableName);
+        MongoCursor<Document> cursor = collection.find().iterator();
 
-        collection.deleteOne(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
-                Filters.eq(Constants.INS, ins)));
+        Log.i("<" + tableName + ">");
 
-        return resPayloadList;
+        HashMap<String, Object> records = null;
+        int index = 0;
+        while (cursor.hasNext()) {
+
+            Document doc = cursor.next();
+            records = convertDocumentToHashMap(doc);
+
+            Log.i("[" + index + "] " + records.toString());
+            index++;
+        }
 
+        cursor.close();
     }
 }
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/PayloadManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/PayloadManager.java
new file mode 100644 (file)
index 0000000..bf1e91f
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * //******************************************************************
+ * //
+ * // 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;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.rdserver.Constants;
+
+/**
+ * 
+ * This class provides a set of APIs handle a payload
+ *
+ */
+public class PayloadManager {
+
+    /** tag values of /oic/rd resource payload */
+    public List<String> pubTagKey       = Arrays.asList("di", "n", "lt");
+
+    /** links values of /oic/rd resource payload */
+    public List<String> pubLinkKey      = Arrays.asList("href", "rel", "rt",
+            "if", "p", "title", "anchor", "ins", "ttl", "type");
+
+    /** tag values of /oic/res resource payload */
+    public List<String> discoverTagKey  = Arrays.asList("di", "n");
+
+    /** links values of /oic/res resource payload */
+    public List<String> discoverLinkKey = Arrays.asList("href", "rt", "if",
+            "p");
+
+    /**
+     * API for setting data of payload
+     * 
+     * @param payload
+     *            payload data
+     * @param keyType
+     *            key type
+     * @return data included keys of keyType
+     */
+    public HashMap<String, Object> setPayloadData(
+            HashMap<String, Object> payload, List<String> keyType) {
+
+        HashMap<String, Object> data = new HashMap<String, Object>();
+
+        for (String key : keyType) {
+            Object value = payload.get(key);
+            if (value != null) {
+                data.put(key, value);
+            }
+        }
+        return data;
+    }
+
+    /**
+     * API for changing type of policy property to store in DB
+     * 
+     * @param payload
+     *            payload data
+     */
+    public void changePolicyTypeToStore(HashMap<String, Object> payload) {
+        Object policy = payload.get(Constants.POLICY);
+        if (policy != null) {
+            HashMap<String, Object> bm = (HashMap<String, Object>) policy;
+            payload.put(Constants.POLICY, (int) (bm.get(Constants.BITMAP)));
+        }
+    }
+
+    /**
+     * API for changing type of policy property to make a discovery response
+     * 
+     * @param payload
+     *            payload data
+     */
+    public void changePolicyTypeToDiscover(HashMap<String, Object> payload) {
+        Object policy = payload.get(Constants.POLICY);
+        if (policy != null) {
+            HashMap<Object, Object> bm = new HashMap<>();
+            bm.put(Constants.BITMAP, policy);
+            payload.put(Constants.POLICY, bm);
+        }
+    }
+
+}
diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/RDManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/RDManager.java
new file mode 100644 (file)
index 0000000..881eead
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * //******************************************************************
+ * //
+ * // 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.db.DBManager;
+import org.iotivity.cloud.rdserver.resources.directory.rd.InsManager;
+import org.iotivity.cloud.util.Log;
+
+/**
+ * 
+ * This class provides a set of APIs handle requests about resource information
+ *
+ */
+public class RDManager {
+
+    private InsManager                         mInsManager       = new InsManager();
+    private PayloadManager                     mPayloadManager   = new PayloadManager();
+
+    private ArrayList<HashMap<String, Object>> mResourcePresence = new ArrayList<>();
+
+    /**
+     * API for handling resource-publish process
+     * 
+     * @param requestPayload
+     *            request payload
+     * @return response payload
+     */
+    public HashMap<String, Object> publishResource(
+            HashMap<String, Object> requestPayload) {
+
+        HashMap<String, Object> deviceInfo = setResourceDeviceInfo(
+                requestPayload);
+        ArrayList<HashMap<String, Object>> links = getLinks(requestPayload);
+
+        // check ins and set ins
+        setResourceIns(deviceInfo.get(Constants.DEVICE_ID).toString(), links);
+
+        storeResource(links, deviceInfo);
+
+        return requestPayload;
+
+    }
+
+    // set di, n, lt info
+    private HashMap<String, Object> setResourceDeviceInfo(
+            HashMap<String, Object> payload) {
+        return mPayloadManager.setPayloadData(payload,
+                mPayloadManager.pubTagKey);
+    }
+
+    private ArrayList<HashMap<String, Object>> getLinks(
+            HashMap<String, Object> requestPayload) {
+        return (ArrayList<HashMap<String, Object>>) requestPayload
+                .get(Constants.LINKS);
+
+    }
+
+    private void storeResource(ArrayList<HashMap<String, Object>> links,
+            HashMap<String, Object> deviceInfo) {
+
+        ArrayList<HashMap<String, Object>> resourcePresence = new ArrayList<>();
+
+        for (HashMap<String, Object> link : links) {
+            HashMap<String, Object> storeInfo = new HashMap<>();
+            HashMap<String, Object> storeLink = mPayloadManager
+                    .setPayloadData(link, mPayloadManager.pubLinkKey);
+            mPayloadManager.changePolicyTypeToStore(storeLink);
+            storeInfo.putAll(storeLink);
+            storeInfo.putAll(deviceInfo);
+            storeResourceInDB(storeInfo);
+            resourcePresence.add(storeInfo);
+        }
+        setmResourcePresence(resourcePresence);
+
+    }
+
+    private void storeResourceInDB(HashMap<String, Object> rdInfo) {
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.DEVICE_ID, rdInfo.get(Constants.DEVICE_ID));
+        condition.put(Constants.INS, rdInfo.get(Constants.INS));
+        if (checkResourceExist(condition).isEmpty()) {
+            DBManager.getInstance().insertRecord(Constants.RD_TABLE, rdInfo);
+            // set resource presence
+            rdInfo.put(Constants.TRIGGER, Constants.RES_CREATE);
+        } else {
+            DBManager.getInstance().insertAndReplaceRecord(Constants.RD_TABLE,
+                    rdInfo);
+            rdInfo.put(Constants.TRIGGER, Constants.RES_CHANGE);
+        }
+
+    }
+
+    private void setResourceIns(String di,
+            ArrayList<HashMap<String, Object>> links) {
+
+        for (HashMap<String, Object> link : links) {
+            String href = link.get(Constants.HREF).toString();
+            int ins = (int) link.get(Constants.INS);
+            int newIns = checkResourceIns(di, href, ins);
+            if (newIns == -1) {
+                throw new BadRequestException("resource ins is not correct");
+            }
+            link.put(Constants.INS, newIns);
+        }
+    }
+
+    private int checkResourceIns(String di, String href, int ins) {
+        int storedIns = mInsManager.getIns(di, href);
+        if (ins == 0) {
+            if (storedIns == -1) {
+                // create ins
+                ins = mInsManager.createIns(di);
+            } else {
+                ins = storedIns;
+            }
+        } else {
+            if (ins != storedIns) {
+                ins = -1;
+            }
+        }
+        return ins;
+    }
+
+    /**
+     * API for handling resource-delete process
+     * 
+     * @param di
+     *            device id
+     * @param ins
+     *            unique id of resource
+     */
+    public void deleteResource(String di, List<String> insList) {
+
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.DEVICE_ID, di);
+
+        ArrayList<HashMap<String, Object>> foundRecord = new ArrayList<>();
+
+        if (insList == null) {
+            foundRecord = checkResourceExist(condition);
+            DBManager.getInstance().deleteRecord(Constants.RD_TABLE, condition);
+        } else {
+            for (String ins : insList) {
+                condition.put(Constants.INS, Integer.parseInt(ins));
+                if (!checkResourceExist(condition).isEmpty()) {
+                    foundRecord.add(checkResourceExist(condition).get(0));
+                    DBManager.getInstance().deleteRecord(Constants.RD_TABLE,
+                            condition);
+                }
+            }
+        }
+
+        if (!foundRecord.isEmpty()) {
+            // set resource presence
+            for (HashMap<String, Object> record : foundRecord) {
+                record.put(Constants.TRIGGER, Constants.RES_DELETE);
+            }
+            setmResourcePresence(foundRecord);
+        }
+    }
+
+    private ArrayList<HashMap<String, Object>> checkResourceExist(
+            HashMap<String, Object> condition) {
+        ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
+                .selectRecord(Constants.RD_TABLE, condition);
+
+        return records;
+    }
+
+    /**
+     * API for handling resource-discover process
+     * 
+     * @param diList
+     *            list of device id
+     * @param rtList
+     *            list of resource type
+     * @param ifList
+     *            list of resource interface
+     * @return response payload
+     */
+    public ArrayList<Object> discoverResource(List<String> diList,
+            List<String> rtList, List<String> ifList) {
+
+        HashMap<String, Object> condition = new HashMap<>();
+
+        ArrayList<Object> response = new ArrayList<>();
+
+        if (diList == null) {
+            return response;
+        }
+
+        if (rtList == null && ifList == null) {
+            readResource(diList, condition, response);
+        }
+
+        if (rtList != null) {
+            for (String rt : rtList) {
+                condition.put(Constants.RESOURCE_TYPE, rt);
+                readResource(diList, condition, response);
+            }
+        }
+
+        if (ifList != null) {
+            for (String itf : ifList) {
+                condition.put(Constants.INTERFACE, itf);
+                readResource(diList, condition, response);
+            }
+        }
+
+        Log.d("discovery payload : " + response);
+
+        return response;
+    }
+
+    private void readResource(List<String> diList,
+            HashMap<String, Object> condition, ArrayList<Object> response) {
+
+        for (String di : diList) {
+            condition.put(Constants.DEVICE_ID, di);
+            ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
+                    .selectRecord(Constants.RD_TABLE, condition);
+
+            if (!records.isEmpty()) {
+                response.add(makeDiscoverResponseSegment(records));
+            }
+
+        }
+    }
+
+    private HashMap<String, Object> makeDiscoverResponseSegment(
+            ArrayList<HashMap<String, Object>> records) {
+
+        HashMap<String, Object> responseSegment = new HashMap<>();
+
+        // make Tags
+        HashMap<String, Object> discoverTag = mPayloadManager
+                .setPayloadData(records.get(0), mPayloadManager.discoverTagKey);
+        responseSegment.putAll(discoverTag);
+
+        ArrayList<Object> links = new ArrayList<>();
+        // make links
+        for (HashMap<String, Object> record : records) {
+            HashMap<String, Object> link = mPayloadManager
+                    .setPayloadData(record, mPayloadManager.discoverLinkKey);
+            mPayloadManager.changePolicyTypeToDiscover(link);
+            links.add(link);
+        }
+        responseSegment.put(Constants.LINKS, links);
+
+        return responseSegment;
+
+    }
+
+    private void setmResourcePresence(
+            ArrayList<HashMap<String, Object>> resourcePresence) {
+        this.mResourcePresence = resourcePresence;
+    }
+
+    /**
+     * API for getting resource information to notify
+     * 
+     * @return resource information
+     */
+    public ArrayList<HashMap<String, Object>> getmResourcePresence() {
+        return mResourcePresence;
+    }
+
+}
index 980e092..f97e2fc 100644 (file)
  */
 package org.iotivity.cloud.rdserver.resources.directory.rd;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
+import org.iotivity.cloud.rdserver.Constants;
 import org.iotivity.cloud.rdserver.db.DBManager;
 
+/**
+ *
+ * This class provides a set of APIs to handle ins(unique value of resource)
+ *
+ */
 public class InsManager {
 
     private HashMap<String, Integer> mNextIns      = new HashMap<>();
     private int                      mInitialValue = 1;
 
+    /**
+     * API for getting ins from DB
+     * 
+     * @param di
+     *            device id
+     * @param href
+     *            resource uri
+     * @return ins
+     */
     public int getIns(String di, String href) {
 
-        Object objectIns = DBManager.getInstance().findInsAboutDi(di, href);
-        if (objectIns == null) {
-            return 0;
-        } else {
-            return (int) objectIns;
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.DEVICE_ID, di);
+        condition.put(Constants.HREF, href);
+        ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
+                .selectRecord(Constants.RD_TABLE, condition);
 
+        if (records.isEmpty()) {
+            return -1;
+        } else {
+            return (int) (records.get(0).get(Constants.INS));
         }
     }
 
+    /**
+     * API for creating ins
+     * 
+     * @param di
+     *            device id
+     * @return created ins
+     */
     public int createIns(String di) {
         Object objectIns;
 
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
deleted file mode 100644 (file)
index 6a64e36..0000000
+++ /dev/null
@@ -1,155 +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.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
deleted file mode 100644 (file)
index e02b726..0000000
+++ /dev/null
@@ -1,60 +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.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
deleted file mode 100644 (file)
index f240ff9..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.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;
-    }
-}
index 9d465a4..f56f29d 100644 (file)
@@ -37,21 +37,20 @@ 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.rdserver.resources.directory.RDManager;
+import org.iotivity.cloud.rdserver.resources.presence.PresenceManager;
 import org.iotivity.cloud.util.Cbor;
 import org.iotivity.cloud.util.Log;
 
+/**
+ * 
+ * This class provides a set of APIs handle requests about resource directory
+ *
+ */
 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                           mNotiDeviceId            = null;
-    private ArrayList<ResPresencePayload>    mNotiPayloadList         = new ArrayList<ResPresencePayload>();
+    private Cbor<HashMap<String, Object>> mCbor      = new Cbor<>();
+    private RDManager                     mRdManager = new RDManager();
 
     public ResourceDirectoryResource() {
         super(Arrays.asList(Constants.PREFIX_OIC, Constants.RD_URI));
@@ -73,208 +72,83 @@ public class ResourceDirectoryResource extends Resource {
                 break;
 
             default:
-                throw new BadRequestException(request.getMethod()
-                        + " request type is not supported");
+                throw new BadRequestException(
+                        request.getMethod() + " request type is not supported");
         }
 
         srcDevice.sendResponse(response);
 
-        ResPresenceManager.getInstance().notifyToObservers(mNotiDeviceId,
-                mNotiPayloadList);
+        PresenceManager.getInstance()
+                .notifyToObservers(mRdManager.getmResourcePresence());
 
     }
 
-    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());
+    private void checkLinksProperty(HashMap<String, Object> payload) {
 
-            mNotiDeviceId = pubPayload.getTags().getDi();
-
-            // PublishPayload copyPubPayload = pubPayload.copy();
-
-            // ArrayList<HashMap<Object, Object>> storeResList =
-            // creatDBStoreResource(changeResourceUri(copyPubPayload));
-
-            ArrayList<HashMap<Object, Object>> storeResList = creatDBStoreResource(pubPayload);
-
-            mNotiPayloadList = DBManager.getInstance().registerResource(
-                    storeResList);
-
-            encodedPayload = createPublishResponse(pubPayload);
-
-        } else {
-            throw new PreconditionFailedException(
-                    "rt property is not rd publish");
+        Object links = payload.get(Constants.LINKS);
+        if (links == null) {
+            throw new BadRequestException("links property is null");
         }
-
-        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));
+        ArrayList<HashMap<String, Object>> linksList = (ArrayList<HashMap<String, Object>>) links;
+        for (HashMap<String, Object> link : linksList) {
+            checkPayloadException(
+                    Arrays.asList(Constants.HREF, Constants.RESOURCE_TYPE,
+                            Constants.INS, Constants.INTERFACE),
+                    link);
         }
-        responseMap.put(Constants.LINKS, links);
-
-        Log.i("publish response :" + responseMap.toString());
-
-        byte[] encodedPaylod = mCbor.encodingPayloadToCbor(responseMap);
-
-        return encodedPaylod;
     }
 
-    private PublishPayload parsingPublishPayload(byte[] payload)
+    private IResponse handlePostRequest(IRequest request)
             throws ServerException {
 
-        HashMap<Object, Object> payloadData = mCbor.parsePayloadFromCbor(
-                payload, HashMap.class);
-
-        if (payloadData == null) {
-            throw new BadRequestException("payload is null");
-        } else {
-            Log.i("publish payload: " + payloadData.toString());
-        }
+        HashMap<String, List<String>> queryMap = request.getUriQueryMap();
 
-        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);
-        }
+        checkQueryException(Arrays.asList(Constants.RESOURCE_TYPE), queryMap);
 
-        PublishPayload pubPayload = new PublishPayload();
-        pubPayload.setTags(tags);
-        pubPayload.setLinks(pubLinksList);
+        List<String> listRT = queryMap.get(Constants.RESOURCE_TYPE);
 
-        return pubPayload;
-    }
+        // check query "rt=oic.rd.pub"
+        if (!listRT.get(0).equals(Constants.RESOURCE_TYPE_RDPUBLISH)) {
+            throw new PreconditionFailedException("rt property is not correct");
+        }
 
-    private PublishPayload changeResourceUri(PublishPayload pubPayload) {
+        HashMap<String, Object> payload = mCbor
+                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
 
-        String di = pubPayload.getTags().getDi();
+        Log.d("publish payload : " + payload);
 
-        for (PublishLinks links : pubPayload.getLinks()) {
-            String originHref = links.getHref();
-            links.setHref("/di/" + di + originHref);
-        }
+        checkPayloadException(
+                Arrays.asList(Constants.DEVICE_ID, Constants.LINKS), payload);
 
-        return pubPayload;
-    }
+        // check mandatory property
+        checkLinksProperty(payload);
 
-    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;
-    }
+        HashMap<String, Object> response = mRdManager.publishResource(payload);
 
-    private ArrayList<HashMap<Object, Object>> creatDBStoreResource(
-            PublishPayload pubPayload) {
-        PublishTags tags = pubPayload.getTags();
-        ArrayList<PublishLinks> linksList = pubPayload.getLinks();
+        Log.d("publish response : " + response);
 
-        ArrayList<HashMap<Object, Object>> storeResList = new ArrayList<HashMap<Object, Object>>();
-        HashMap<Object, Object> storeTags = mPublishTagsTypeManager
-                .convertObjectToMap(tags);
+        return MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(response));
 
-        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);
-                mNotiDeviceId = di;
-
-                if (insList == null) {
-                    mNotiPayloadList = DBManager.getInstance()
-                            .deleteResourceAboutDi(di);
-
-                } else {
-                    String ins = insList.get(0);
-                    mNotiPayloadList = DBManager.getInstance()
-                            .deleteResourceAboutDiAandIns(di, ins);
-                }
-            }
-        }
+
+        checkQueryException(Arrays.asList(Constants.DEVICE_ID), queryMap);
+
+        List<String> diList = queryMap.get(Constants.DEVICE_ID);
+        List<String> insList = queryMap.get(Constants.INS);
+
+        mRdManager.deleteResource(diList.get(0), insList);
 
         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
deleted file mode 100644 (file)
index e4caa38..0000000
+++ /dev/null
@@ -1,75 +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.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
deleted file mode 100644 (file)
index edae490..0000000
+++ /dev/null
@@ -1,52 +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.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;
-    }
-
-}
index 0462ed3..1f7199f 100644 (file)
@@ -29,7 +29,6 @@ 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;
@@ -37,15 +36,17 @@ 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.rdserver.resources.directory.RDManager;
 import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.Log;
 
+/**
+ * 
+ * This class provides a set of APIs handle requests about resource discovery
+ *
+ */
 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<>();
+    private Cbor<ArrayList<Object>> mCbor      = new Cbor<>();
+    private RDManager               mRdManager = new RDManager();
 
     public DiscoveryResource() {
         super(Arrays.asList(Constants.PREFIX_OIC, Constants.WELL_KNOWN_URI));
@@ -75,105 +76,21 @@ public class DiscoveryResource extends Resource {
 
         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);
+        List<String> diList = queryMap.get(Constants.DEVICE_ID);
+        List<String> rtList = queryMap.get(Constants.RESOURCE_TYPE);
+        List<String> ifList = queryMap.get(Constants.INTERFACE);
 
-        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 = null, 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);
-        }
+        ArrayList<Object> response = mRdManager.discoverResource(diList, rtList,
+                ifList);
 
-        for (String deviceId : deviceList) {
-            if(key != null && value != null){
-                foundResList = DBManager.getInstance().findResourceAboutDiAndFilter(deviceId,
-                        key, value);
-            } else {
-                foundResList = DBManager.getInstance().findResourceAboutDi(deviceId);
-            }
-
-            if (foundResList != null) {
-                resourceList.add(makeDiscoveryPayloadSegment(foundResList));
-            }
+        if (response.size() == 0) {
+            return MessageBuilder.createResponse(request,
+                    ResponseStatus.NOT_FOUND);
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
                 ContentFormat.APPLICATION_CBOR,
-                createDiscoveryResponse(resourceList));
+                mCbor.encodingPayloadToCbor(response));
     }
 
-    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) {
-
-            DiscoveryTags tags = discoveryPayload.getTags();
-
-            HashMap<Object, Object> 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);
-        }
-
-        Log.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
deleted file mode 100644 (file)
index bc1fe35..0000000
+++ /dev/null
@@ -1,45 +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.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/PresenceManager.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/presence/PresenceManager.java
new file mode 100644 (file)
index 0000000..1d6f05d
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * //******************************************************************
+ * //
+ * // 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.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.base.device.Device;
+import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
+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.db.DBManager;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.Log;
+
+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;
+
+/**
+ * 
+ * This class provides a set of APIs handle requests about presence
+ *
+ */
+public class PresenceManager {
+    private static PresenceManager        mPresenceManager = new PresenceManager();
+
+    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;
+    }
+
+    private class PresenceInfo {
+
+        PresenceInfo() {
+            mSubscriber = new HashMap<>();
+            mSubscribedDevices = new HashMap<>();
+            mSequenceNumber = new HashMap<>();
+        }
+
+        // di , token, Subscriber list
+        private HashMap<String, HashMap<String, PresenceSubscriber>> mSubscriber;
+        // token, di list
+        private HashMap<String, List<String>>                        mSubscribedDevices;
+        private HashMap<String, Long>                                mSequenceNumber;
+    }
+
+    private PresenceInfo mDevicePresence   = null;
+    private PresenceInfo mResourcePresence = null;
+
+    private PresenceManager() {
+        mDevicePresence = new PresenceInfo();
+        mResourcePresence = new PresenceInfo();
+    }
+
+    /**
+     * API to return PresenceManager object
+     * 
+     * @return PresenceManager object
+     */
+    public static PresenceManager getInstance() {
+        return mPresenceManager;
+    }
+
+    /**
+     * API to add observer
+     * 
+     * @param srcDevice
+     *            channel information
+     * @param request
+     *            request message
+     * @param deviceIdList
+     *            subscribed device list
+     * @param presenceType
+     *            device presence or resource presence
+     */
+    public void subscribePresence(Device srcDevice, IRequest request,
+            List<String> deviceIdList, String presenceType) {
+
+        PresenceInfo presenceInfo = getPresenceInfo(presenceType);
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = presenceInfo.mSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                subscribers = new HashMap<>();
+                presenceInfo.mSubscriber.put(deviceId, subscribers);
+            }
+
+            subscribers.put(request.getRequestId(),
+                    new PresenceSubscriber(srcDevice, request));
+        }
+
+        presenceInfo.mSubscribedDevices.put(request.getRequestId(),
+                deviceIdList);
+        presenceInfo.mSequenceNumber.put(request.getRequestId(), (long) 1);
+    }
+
+    /**
+     * API to remove observer
+     * 
+     * @param request
+     *            request message
+     * @param deviceIdList
+     *            unsubscribed device list
+     * @param presenceType
+     *            device presence or resource presence
+     */
+    public void unsubscribePresence(IRequest request, List<String> deviceIdList,
+            String presenceType) {
+
+        PresenceInfo presenceInfo = getPresenceInfo(presenceType);
+
+        for (String deviceId : deviceIdList) {
+            HashMap<String, PresenceSubscriber> subscribers = presenceInfo.mSubscriber
+                    .get(deviceId);
+
+            if (subscribers == null) {
+                continue;
+            }
+
+            subscribers.remove(request.getRequestId());
+        }
+    }
+
+    /**
+     * API for notifying to observers about device presence
+     * 
+     * @param deviceId
+     *            device id
+     */
+    public void notifyToObservers(String deviceId) {
+
+        HashMap<String, PresenceSubscriber> tokenNSubscribers = mDevicePresence.mSubscriber
+                .get(deviceId);
+
+        if (tokenNSubscribers != null) {
+            byte[] payload = makeResponsePayload(Arrays.asList(deviceId));
+
+            for (PresenceSubscriber subscriber : tokenNSubscribers.values()) {
+
+                subscriber.mSubscriber.sendResponse(
+                        MessageBuilder.createResponse(subscriber.mRequest,
+                                ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR, payload));
+            }
+        }
+    }
+
+    /**
+     * API to make response payload about device presence
+     * 
+     * @param deviceList
+     *            device id list
+     * @return payload data
+     */
+    public byte[] makeResponsePayload(List<String> deviceList) {
+
+        HashMap<String, Object> getPayload = new HashMap<>();
+        ArrayList<HashMap<String, Object>> prsList = new ArrayList<>();
+
+        for (String deviceId : deviceList) {
+            HashMap<String, Object> payloadSegment = new HashMap<>();
+
+            String deviceState = getDeviceState(deviceId);
+
+            payloadSegment.put(Constants.DEVICE_ID, deviceId);
+
+            if (deviceState != null) {
+                payloadSegment.put(Constants.PRESENCE_STATE, deviceState);
+            } else {
+                payloadSegment.put(Constants.PRESENCE_STATE,
+                        Constants.PRESENCE_OFF);
+            }
+            prsList.add(payloadSegment);
+        }
+        getPayload.put(Constants.PRESENCE_LIST, prsList);
+        Log.i("Device presence observe response : " + getPayload.toString());
+
+        return mCbor.encodingPayloadToCbor(getPayload);
+
+    }
+
+    private String getDeviceState(String deviceId) {
+
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.DEVICE_ID, deviceId);
+
+        String state = null;
+
+        ArrayList<HashMap<String, Object>> readRecords = DBManager.getInstance()
+                .selectRecord(Constants.PRESENCE_TABLE, condition);
+
+        if (!readRecords.isEmpty()
+                && readRecords.get(0).get(Constants.PRESENCE_STATE) != null) {
+            state = readRecords.get(0).get(Constants.PRESENCE_STATE).toString();
+        }
+
+        return state;
+    }
+
+    private PresenceInfo getPresenceInfo(String presenceType) {
+
+        PresenceInfo presenceInfo = null;
+        switch (presenceType) {
+            case Constants.DEVICE_PRESENCE:
+                presenceInfo = mDevicePresence;
+                break;
+            case Constants.RESOURCE_PRESENCE:
+                presenceInfo = mResourcePresence;
+                break;
+            default:
+        }
+        return presenceInfo;
+    }
+
+    /**
+     * API for notifying to observers about resource presence
+     * 
+     * @param resourceInfo
+     *            resource information
+     */
+    public void notifyToObservers(
+            ArrayList<HashMap<String, Object>> resourceInfo) {
+
+        if (resourceInfo.isEmpty()) {
+            return;
+        }
+
+        Object obj = resourceInfo.get(0).get(Constants.DEVICE_ID);
+
+        if (obj == null) {
+            return;
+        }
+
+        String deviceId = obj.toString();
+
+        HashMap<String, PresenceSubscriber> tokenNSubscribers = mResourcePresence.mSubscriber
+                .get(deviceId);
+
+        if (tokenNSubscribers != null) {
+
+            for (PresenceSubscriber subscriber : tokenNSubscribers.values()) {
+
+                for (HashMap<String, Object> resource : resourceInfo) {
+                    subscriber.mSubscriber.sendResponse(
+                            MessageBuilder.createResponse(subscriber.mRequest,
+                                    ResponseStatus.CONTENT,
+                                    ContentFormat.APPLICATION_CBOR,
+                                    makeResponsePayload(
+                                            subscriber.mRequest.getRequestId(),
+                                            resource)));
+                }
+            }
+        }
+    }
+
+    private byte[] makeResponsePayload(String requestId,
+            HashMap<String, Object> resource) {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        CBORFactory f = new CBORFactory();
+        try {
+            JsonGenerator gen = f.createGenerator(out, JsonEncoding.UTF8);
+            gen.writeStartObject();
+            long sequenceId = mResourcePresence.mSequenceNumber.get(requestId);
+            gen.writeNumberField(Constants.NON, sequenceId);
+            mResourcePresence.mSequenceNumber.put(requestId, sequenceId + 1);
+            gen.writeNumberField(Constants.RESOURCE_TTL, Long.parseLong(
+                    checkPayload(resource, Constants.RESOURCE_TTL).toString()));
+
+            gen.writeFieldName(Constants.TRIGGER);
+
+            ((CBORGenerator) gen).writeRaw((byte) (224
+                    + (byte) (checkPayload(resource, Constants.TRIGGER))));
+
+            gen.writeStringField(Constants.RESOURCE_TYPE,
+                    checkPayload(resource, Constants.RESOURCE_TYPE).toString());
+
+            gen.writeStringField(Constants.HREF,
+                    checkPayload(resource, Constants.HREF).toString());
+            gen.writeEndObject();
+
+            gen.close();
+        } catch (Exception e) {
+            throw new InternalServerErrorException(
+                    "notification payload cbor encoding error");
+        }
+
+        return out.toByteArray();
+    }
+
+    private Object checkPayload(HashMap<String, Object> resource, String key) {
+        Object obj = resource.get(key);
+
+        if (obj == null) {
+            throw new InternalServerErrorException(
+                    "property (" + key + ") is null");
+        }
+
+        return obj;
+    }
+
+    /**
+     * API to update device state
+     * 
+     * @param payload
+     *            payload included device state
+     */
+    public void updateDevicePresence(HashMap<String, Object> payload) {
+        DBManager.getInstance().insertAndReplaceRecord(Constants.PRESENCE_TABLE,
+                payload);
+    }
+}
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
deleted file mode 100644 (file)
index f0779db..0000000
+++ /dev/null
@@ -1,170 +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.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();
-    }
-}
index bd8780b..fe4556f 100644 (file)
@@ -21,7 +21,6 @@
  */
 package org.iotivity.cloud.rdserver.resources.presence.device;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -36,36 +35,22 @@ 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.rdserver.resources.presence.PresenceManager;
 import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.Log;
 
+/**
+ * 
+ * This class provides a set of APIs handle requests about device presence
+ *
+ */
 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_OIC,
                 Constants.DEVICE_PRESENCE_URI));
 
-        mDeviceSubscriber = new HashMap<>();
-        mSubscribedDevices = new HashMap<>();
     }
 
     @Override
@@ -95,30 +80,31 @@ public class DevicePresenceResource extends Resource {
             throws ServerException {
         HashMap<String, List<String>> queryMap = request.getUriQueryMap();
 
-        byte[] payload = null;
+        checkQueryException(Arrays.asList(Constants.DEVICE_ID), queryMap);
 
-        if (checkQueryException(Arrays.asList(Constants.DEVICE_ID), queryMap)) {
+        List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
 
-            List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
-
-            switch (request.getObserve()) {
-                case SUBSCRIBE:
-                    addObserver(srcDevice, request, deviceList);
-                    break;
-                case UNSUBSCRIBE:
-                    removeObserver(request);
-                    break;
-                default:
-            }
-
-            payload = makeResponsePayload(deviceList);
+        switch (request.getObserve()) {
+            case SUBSCRIBE:
+                PresenceManager.getInstance().subscribePresence(srcDevice,
+                        request, deviceList, Constants.DEVICE_PRESENCE);
+                break;
+            case UNSUBSCRIBE:
+                PresenceManager.getInstance().unsubscribePresence(request,
+                        deviceList, Constants.DEVICE_PRESENCE);
+                break;
+            default:
         }
 
+        byte[] payload = PresenceManager.getInstance()
+                .makeResponsePayload(deviceList);
+
         return MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
                 ContentFormat.APPLICATION_CBOR, payload);
+
     }
 
-    public IResponse handlePostRequest(IRequest request)
+    private IResponse handlePostRequest(IRequest request)
             throws ServerException {
         // check payload
         byte[] payload = request.getPayload();
@@ -126,104 +112,18 @@ public class DevicePresenceResource extends Resource {
         HashMap<String, Object> parsedPayload = mCbor
                 .parsePayloadFromCbor(payload, HashMap.class);
 
-        if (checkPayloadException(
+        checkPayloadException(
                 Arrays.asList(Constants.DEVICE_ID, Constants.PRESENCE_STATE),
-                parsedPayload)) {
-
-            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);
+                parsedPayload);
 
-            TypeCastingManager<DeviceState> deviceStateTypeManager = new TypeCastingManager<DeviceState>();
-            HashMap<Object, Object> storeMap = deviceStateTypeManager
-                    .convertObjectToMap(deviceState);
+        // store db
+        PresenceManager.getInstance().updateDevicePresence(parsedPayload);
 
-            // store db
-            DBManager.getInstance().updateDeviceState(storeMap);
-
-            // notification to observers
-            notifyToObservers(deviceId);
-        }
+        // notification to observers
+        String di = parsedPayload.get(Constants.DEVICE_ID).toString();
+        PresenceManager.getInstance().notifyToObservers(di);
 
         return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-    }
-
-    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, PresenceSubscriber> tokenNSubscribers = mDeviceSubscriber
-                .get(deviceId);
-
-        if (tokenNSubscribers != null) {
-            byte[] paylod = makeResponsePayload(Arrays.asList(deviceId));
-
-            for (PresenceSubscriber subscriber : tokenNSubscribers.values()) {
-
-                subscriber.mSubscriber.sendResponse(
-                        MessageBuilder.createResponse(subscriber.mRequest,
-                                ResponseStatus.CONTENT,
-                                ContentFormat.APPLICATION_CBOR, paylod));
-            }
-        }
-    }
-
-    private byte[] makeResponsePayload(List<String> deviceList) {
-
-        HashMap<String, Object> getPayload = new HashMap<>();
-        ArrayList<HashMap<String, String>> prsList = 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));
-            prsList.add(payloadSegment);
-        }
-        getPayload.put(Constants.PRESENCE_LIST, prsList);
-        Log.i("Get observe response" + getPayload.toString());
 
-        return mCbor.encodingPayloadToCbor(getPayload);
     }
 }
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
deleted file mode 100644 (file)
index 72fd80c..0000000
+++ /dev/null
@@ -1,45 +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.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
deleted file mode 100644 (file)
index 8a9839a..0000000
+++ /dev/null
@@ -1,70 +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.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
index 1472463..8ab8640 100644 (file)
@@ -28,15 +28,19 @@ 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;
+import org.iotivity.cloud.rdserver.resources.presence.PresenceManager;
 
+/**
+ * 
+ * This class provides a set of APIs handle requests about resource presence
+ *
+ */
 public class ResPresenceResource extends Resource {
 
     public ResPresenceResource() {
@@ -51,7 +55,7 @@ public class ResPresenceResource extends Resource {
 
         switch (request.getMethod()) {
             case GET:
-                response = handleRegisterRequest(srcDevice, request);
+                response = handleGetRequest(srcDevice, request);
                 break;
 
             default:
@@ -62,23 +66,17 @@ public class ResPresenceResource extends Resource {
         srcDevice.sendResponse(response);
     }
 
-    public IResponse handleRegisterRequest(Device srcDevice, IRequest request)
+    private IResponse handleGetRequest(Device srcDevice, IRequest request)
             throws ServerException {
 
         HashMap<String, List<String>> queryMap = request.getUriQueryMap();
 
-        if (queryMap == null) {
-            throw new PreconditionFailedException("query is null");
-        }
+        checkQueryException(Arrays.asList(Constants.DEVICE_ID), queryMap);
 
         List<String> deviceList = queryMap.get(Constants.DEVICE_ID);
 
-        if (deviceList == null) {
-            throw new PreconditionFailedException("deviceList is null");
-        }
-
-        ResPresenceManager.getInstance().addObserver(srcDevice, request,
-                deviceList);
+        PresenceManager.getInstance().subscribePresence(srcDevice, request,
+                deviceList, Constants.RESOURCE_PRESENCE);
 
         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
deleted file mode 100644 (file)
index cc9df99..0000000
+++ /dev/null
@@ -1,111 +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.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) {
-
-        HashMap<Object, Object> map = new HashMap<Object, Object>();
-
-        try {
-            Field[] fieldList = objClass.getClass().getDeclaredFields();
-
-            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);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        return map;
-    }
-
-    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;
-    }
-}
index 3e4e851..1e60ce6 100644 (file)
@@ -22,7 +22,6 @@
 package org.iotivity.cloud.testrdserver;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
@@ -41,7 +40,6 @@ import org.iotivity.cloud.base.protocols.enums.Observe;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.resources.directory.rd.ResourceDirectoryResource;
 import org.iotivity.cloud.rdserver.resources.presence.device.DevicePresenceResource;
 import org.iotivity.cloud.util.Cbor;
 import org.junit.After;
@@ -52,20 +50,18 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 public class DevicePresenceResourceTest {
-    private Cbor<HashMap<String, Object>> mCbor                      = new Cbor<>();
-    private ResourceDirectoryResource     mRDResource                = null;
-    private DevicePresenceResource        mockDevicePresenceResource = null;
-    private CoapDevice                    mockDevice                 = null;
-    private CountDownLatch                mLatch                     = null;
+    private Cbor<HashMap<String, Object>> mCbor                       = new Cbor<>();
+    private DevicePresenceResource        mMockDevicePresenceResource = null;
+    private CoapDevice                    mMockDevice                 = null;
+    private CountDownLatch                mLatch                      = null;
     private IResponse                     mResponse;
 
     @Before
     public void setUp() throws Exception {
         mResponse = null;
-        mockDevice = mock(CoapDevice.class);
+        mMockDevice = mock(CoapDevice.class);
         mLatch = new CountDownLatch(1);
-        mRDResource = new ResourceDirectoryResource();
-        mockDevicePresenceResource = new DevicePresenceResource();
+        mMockDevicePresenceResource = new DevicePresenceResource();
         // callback mock
         Mockito.doAnswer(new Answer<Object>() {
             @Override
@@ -76,7 +72,7 @@ public class DevicePresenceResourceTest {
                 mResponse = resp;
                 return null;
             }
-        }).when(mockDevice).sendResponse(Mockito.anyObject());
+        }).when(mMockDevice).sendResponse(Mockito.anyObject());
     }
 
     @After
@@ -91,64 +87,41 @@ public class DevicePresenceResourceTest {
             request = MessageBuilder.createRequest(RequestMethod.GET,
                     RDServerTestUtils.DEVICE_PRS_REQ_URI, query);
         } else if (obs.compareTo(Observe.UNSUBSCRIBE) == 0) {
-            ArrayList<String> devices = new ArrayList<>();
-            devices.add(RDServerTestUtils.DI);
-            HashMap<String, ArrayList<String>> payload = new HashMap<>();
-            payload.put(Constants.DEVICE_LIST_KEY, devices);
             request = MessageBuilder.createRequest(RequestMethod.GET,
-                    RDServerTestUtils.DEVICE_PRS_REQ_URI, query,
-                    ContentFormat.APPLICATION_CBOR,
-                    mCbor.encodingPayloadToCbor(payload));
+                    RDServerTestUtils.DEVICE_PRS_REQ_URI, query);
         }
         ((CoapRequest) request).setObserve(obs);
         return request;
     }
 
-    private HashMap<String, String> parsePayload(IResponse response) {
-
-        HashMap<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
-
-        ArrayList<HashMap<String, String>> prsList = (ArrayList<HashMap<String, String>>) payloadData
-                .get(Constants.PRESENCE_LIST);
-
-        HashMap<String, String> mapData = prsList.get(0);
-
-        return mapData;
-    }
-
     @Test
     public void testSubscribeRequest() throws Exception {
         System.out.println("\t------testHandleGetSubscribeRequest");
-        mRDResource.onDefaultRequestReceived(mockDevice,
-                RDServerTestUtils.makePublishRequest());
         IRequest request = makePresenceGetRequest(Observe.SUBSCRIBE);
-        mockDevicePresenceResource.onDefaultRequestReceived(mockDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(mMockDevice,
                 request);
         // assertion: if the response status is "CONTENT"
         assertTrue(mLatch.await(2L, SECONDS));
         assertTrue(checkResponseCode(mResponse, ResponseStatus.CONTENT));
-        // assertion : if the payload has "di" and "state"
-        assertTrue(checkPayloadProperty(mResponse, Constants.DEVICE_ID));
-        assertTrue(checkPayloadProperty(mResponse, Constants.PRESENCE_STATE));
-        assertNull(parsePayload(mResponse).get(Constants.PRESENCE_STATE));
+        assertTrue(checkPayloadProperty(mResponse, Constants.DEVICE_ID,
+                RDServerTestUtils.DI));
+        assertTrue(checkPayloadProperty(mResponse, Constants.PRESENCE_STATE,
+                Constants.PRESENCE_OFF));
     }
 
     @Test
     public void testUnsubscribeRequest() throws Exception {
         System.out.println("\t------testHandleGetUnsubscribeRequest");
         IRequest request = makePresenceGetRequest(Observe.UNSUBSCRIBE);
-        mRDResource.onDefaultRequestReceived(mockDevice,
-                RDServerTestUtils.makePublishRequest());
-        mockDevicePresenceResource.onDefaultRequestReceived(mockDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(mMockDevice,
                 request);
         // assertion: if the response status is "CONTENT"
         assertTrue(mLatch.await(2L, SECONDS));
         assertTrue(checkResponseCode(mResponse, ResponseStatus.CONTENT));
-        // assertion : if the payload has "di" and "state"
-        assertTrue(checkPayloadProperty(mResponse, Constants.DEVICE_ID));
-        assertTrue(checkPayloadProperty(mResponse, Constants.PRESENCE_STATE));
-        assertNull(parsePayload(mResponse).get(Constants.PRESENCE_STATE));
+        assertTrue(checkPayloadProperty(mResponse, Constants.DEVICE_ID,
+                RDServerTestUtils.DI));
+        assertTrue(checkPayloadProperty(mResponse, Constants.PRESENCE_STATE,
+                Constants.PRESENCE_OFF));
     }
 
     @Test
@@ -173,11 +146,9 @@ public class DevicePresenceResourceTest {
                     assertTrue(checkResponseCode(response,
                             ResponseStatus.CONTENT));
                     assertTrue(checkPayloadProperty(response,
-                            Constants.DEVICE_ID));
+                            Constants.DEVICE_ID, RDServerTestUtils.DI));
                     assertTrue(checkPayloadProperty(response,
-                            Constants.PRESENCE_STATE));
-                    assertTrue(parsePayload(response)
-                            .get(Constants.PRESENCE_STATE).equals("on"));
+                            Constants.PRESENCE_STATE, Constants.PRESENCE_ON));
                 }
 
                 return null;
@@ -186,17 +157,17 @@ public class DevicePresenceResourceTest {
         }).when(observerDevice).sendResponse(Mockito.anyObject());
         // subscribe request (specific device)
         IRequest subRequest = makePresenceGetRequest(Observe.SUBSCRIBE);
-        mockDevicePresenceResource.onDefaultRequestReceived(observerDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(observerDevice,
                 subRequest);
         // POST device presence off
         HashMap<String, Object> payload = new HashMap<>();
         payload.put(Constants.DEVICE_ID, RDServerTestUtils.DI);
-        payload.put(Constants.PRESENCE_STATE, "on");
+        payload.put(Constants.PRESENCE_STATE, Constants.PRESENCE_ON);
         IRequest request = MessageBuilder.createRequest(RequestMethod.POST,
                 RDServerTestUtils.DEVICE_PRS_REQ_URI, null,
                 ContentFormat.APPLICATION_CBOR,
                 mCbor.encodingPayloadToCbor(payload));
-        mockDevicePresenceResource.onDefaultRequestReceived(mockDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(mMockDevice,
                 request);
         // assertion for resource server device : responseStatus is "CHANGED"
         assertTrue(mLatch.await(2L, SECONDS));
@@ -221,6 +192,10 @@ public class DevicePresenceResourceTest {
                 if (observerLatch.getCount() == 0) {
                     assertTrue(checkResponseCode(response,
                             ResponseStatus.CONTENT));
+                    assertTrue(checkPayloadProperty(response,
+                            Constants.DEVICE_ID, RDServerTestUtils.DI));
+                    assertTrue(checkPayloadProperty(response,
+                            Constants.PRESENCE_STATE, Constants.PRESENCE_OFF));
                 }
 
                 return null;
@@ -229,16 +204,16 @@ public class DevicePresenceResourceTest {
         }).when(observerDevice).sendResponse(Mockito.anyObject());
         // subscribe request (specific device)
         IRequest subRequest = makePresenceGetRequest(Observe.UNSUBSCRIBE);
-        mockDevicePresenceResource.onDefaultRequestReceived(observerDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(observerDevice,
                 subRequest);
         HashMap<String, Object> payload = new HashMap<>();
         payload.put(Constants.DEVICE_ID, RDServerTestUtils.DI);
-        payload.put(Constants.PRESENCE_STATE, "off");
+        payload.put(Constants.PRESENCE_STATE, Constants.PRESENCE_OFF);
         IRequest request = MessageBuilder.createRequest(RequestMethod.POST,
                 RDServerTestUtils.DEVICE_PRS_REQ_URI, null,
                 ContentFormat.APPLICATION_CBOR,
                 mCbor.encodingPayloadToCbor(payload));
-        mockDevicePresenceResource.onDefaultRequestReceived(mockDevice,
+        mMockDevicePresenceResource.onDefaultRequestReceived(mMockDevice,
                 request);
         // assertion for resource server device : responseStatus is "CHANGED"
         assertTrue(mLatch.await(2L, SECONDS));
@@ -247,7 +222,7 @@ public class DevicePresenceResourceTest {
     }
 
     private boolean checkPayloadProperty(IResponse response,
-            String propertyName) {
+            String propertyName, String propertyValue) {
         HashMap<String, Object> payloadData = mCbor
                 .parsePayloadFromCbor(response.getPayload(), HashMap.class);
 
@@ -255,9 +230,10 @@ public class DevicePresenceResourceTest {
                 .get(Constants.PRESENCE_LIST);
 
         HashMap<String, String> mapData = prsList.get(0);
-        if (mapData.containsKey(propertyName))
+        if (mapData.containsKey(propertyName)
+                && mapData.get(propertyName).equals(propertyValue)) {
             return true;
-        else
+        else
             return false;
     }
 
index 193e298..1881f90 100644 (file)
@@ -51,14 +51,14 @@ public class DiscoveryResourceTest {
     private ResourceDirectoryResource mRDResource        = null;
     private DiscoveryResource         mDiscoveryResource = null;
     private CoapDevice                mockDevice         = null;
-    CountDownLatch                    latch              = null;
-    IResponse                         res;
+    private CountDownLatch            mLatch             = null;
+    private IResponse                 mResponse;
 
     @Before
     public void setUp() throws Exception {
-        res = null;
+        mResponse = null;
         mockDevice = mock(CoapDevice.class);
-        latch = new CountDownLatch(1);
+        mLatch = new CountDownLatch(1);
         mRDResource = new ResourceDirectoryResource();
         mDiscoveryResource = new DiscoveryResource();
         // callback mock
@@ -67,8 +67,8 @@ public class DiscoveryResourceTest {
             public CoapResponse answer(InvocationOnMock invocation)
                     throws Throwable {
                 CoapResponse resp = (CoapResponse) invocation.getArguments()[0];
-                latch.countDown();
-                res = resp;
+                mLatch.countDown();
+                mResponse = resp;
                 return resp;
             }
         }).when(mockDevice).sendResponse(Mockito.anyObject());
@@ -85,11 +85,9 @@ public class DiscoveryResourceTest {
                 RDServerTestUtils.DISCOVERY_REQ_URI,
                 "rt=core.light;di=" + RDServerTestUtils.DI);
         mDiscoveryResource.onDefaultRequestReceived(mockDevice, request);
-        // assertion: if the response status is "CONTENT"
-        // assertion : if the payload is null
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.CONTENT));
-        assertTrue(nullPayloadCheck(res));
+        // assertion: if the response status is "NOT_FOUND"
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
     }
 
     @Test
@@ -102,12 +100,12 @@ public class DiscoveryResourceTest {
         mDiscoveryResource.onDefaultRequestReceived(mockDevice, request);
         // assertion: if the response status is "CONTENT"
         // assertion : if the payload contains resource info
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.CONTENT));
-        assertTrue(discoverHashmapCheck(res, "di"));
-        assertTrue(discoveredResourceCheck(res, "href"));
-        assertTrue(discoveredResourceCheck(res, "rt"));
-        assertTrue(discoveredResourceCheck(res, "if"));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+        assertTrue(discoverHashmapCheck(mResponse, "di"));
+        assertTrue(discoveredResourceCheck(mResponse, "href"));
+        assertTrue(discoveredResourceCheck(mResponse, "rt"));
+        assertTrue(discoveredResourceCheck(mResponse, "if"));
     }
 
     private boolean discoverHashmapCheck(IResponse response,
@@ -147,7 +145,7 @@ public class DiscoveryResourceTest {
 
     private boolean nullPayloadCheck(IResponse response) {
         ArrayList<Object> payloadData = mCbor
-                .parsePayloadFromCbor(res.getPayload(), ArrayList.class);
+                .parsePayloadFromCbor(mResponse.getPayload(), ArrayList.class);
         return (payloadData.isEmpty());
     }
 }
\ No newline at end of file
index 7859888..4b06246 100644 (file)
@@ -19,6 +19,7 @@ public class RDServerTestUtils {
     public static final String RES_PRS_URI        = Constants.RESOURCE_PRESENCE_FULL_URI;
 
     public static IRequest makePublishRequest() throws Exception {
+
         HashMap<Object, Object> payload = new HashMap<>();
         payload.put(Constants.DEVICE_ID, DI);
         ArrayList<HashMap<Object, Object>> publishLinks = new ArrayList<>();
@@ -33,6 +34,8 @@ public class RDServerTestUtils {
         link.put(Constants.RESOURCE_TYPE, rt);
         link.put(Constants.INTERFACE, itf);
         link.put(Constants.POLICY, policy);
+        link.put(Constants.INS, 0);
+        link.put(Constants.RESOURCE_TTL, 3000);
         publishLinks.add(link);
         payload.put(Constants.LINKS, publishLinks);
         Cbor<HashMap<Object, Object>> cbor = new Cbor<>();
index 4d67b08..8acc787 100644 (file)
@@ -49,14 +49,14 @@ public class ResourceDirectoryResourceTest {
     private Cbor<HashMap<String, Object>> mCbor       = new Cbor<>();
     private ResourceDirectoryResource     mRDResource = null;
     private CoapDevice                    mockDevice  = null;
-    CountDownLatch                        latch       = null;
-    IResponse                             res;
+    CountDownLatch                        mLatch      = null;
+    IResponse                             mResponse;
 
     @Before
     public void setUp() throws Exception {
-        res = null;
+        mResponse = null;
         mockDevice = mock(CoapDevice.class);
-        latch = new CountDownLatch(1);
+        mLatch = new CountDownLatch(1);
         mRDResource = new ResourceDirectoryResource();
         // callback mock
         Mockito.doAnswer(new Answer<Object>() {
@@ -64,8 +64,8 @@ public class ResourceDirectoryResourceTest {
             public CoapResponse answer(InvocationOnMock invocation)
                     throws Throwable {
                 CoapResponse resp = (CoapResponse) invocation.getArguments()[0];
-                latch.countDown();
-                res = resp;
+                mLatch.countDown();
+                mResponse = resp;
                 return resp;
             }
         }).when(mockDevice).sendResponse(Mockito.anyObject());
@@ -83,15 +83,15 @@ public class ResourceDirectoryResourceTest {
                 RDServerTestUtils.makePublishRequest());
         // assertion: if the response status is "CHANGED" according to
         // the resource publication
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         // assertion : if the mandatory properties are received in the
         // response
-        assertTrue(linkCheck(res, "href"));
-        assertTrue(linkCheck(res, "rt"));
-        assertTrue(linkCheck(res, "if"));
-        assertTrue(linkCheck(res, "ins"));
-        assertTrue(hashmapCheck(res, "di"));
+        assertTrue(linkCheck(mResponse, "href"));
+        assertTrue(linkCheck(mResponse, "rt"));
+        assertTrue(linkCheck(mResponse, "if"));
+        assertTrue(linkCheck(mResponse, "ins"));
+        assertTrue(hashmapCheck(mResponse, "di"));
     }
 
     @Test
@@ -102,8 +102,8 @@ public class ResourceDirectoryResourceTest {
         mRDResource.onDefaultRequestReceived(mockDevice, request);
         // assertion: if the response status is "DELETED" according to the
         // resource publication
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.DELETED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
     }
 
     @Test
@@ -116,8 +116,8 @@ public class ResourceDirectoryResourceTest {
         mRDResource.onDefaultRequestReceived(mockDevice, request);
         // assertion: if the response status is "DELETED" according to the
         // resource publication
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.DELETED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
     }
 
     @Test
@@ -130,8 +130,8 @@ public class ResourceDirectoryResourceTest {
         mRDResource.onDefaultRequestReceived(mockDevice, request);
         // assertion: if the response status is "DELETED" according to the
         // resource publication
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.DELETED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
     }
 
     @Test
@@ -145,8 +145,8 @@ public class ResourceDirectoryResourceTest {
         mRDResource.onDefaultRequestReceived(mockDevice, request);
         // assertion: if the response status is "DELETED" according to the
         // resource publication
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.DELETED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
     }
 
     private boolean hashmapCheck(IResponse response, String propertyName) {
index 0c647d1..d2773fa 100644 (file)
@@ -47,24 +47,24 @@ public class ResourcePresenceResourceTest {
     private ResourceDirectoryResource mRDResource          = null;
     private ResPresenceResource       mResPresenceResource = null;
     private CoapDevice                mockDevice           = null;
-    CountDownLatch                    latch                = null;
-    IResponse                         res;
+    private CountDownLatch            mLatch               = null;
+    private IResponse                 mResponse;
 
     @Before
     public void setUp() throws Exception {
         mRDResource = new ResourceDirectoryResource();
         mResPresenceResource = new ResPresenceResource();
-        res = null;
+        mResponse = null;
         mockDevice = mock(CoapDevice.class);
-        latch = new CountDownLatch(1);
+        mLatch = new CountDownLatch(1);
         // callback mock
         Mockito.doAnswer(new Answer<Object>() {
             @Override
             public CoapResponse answer(InvocationOnMock invocation)
                     throws Throwable {
                 CoapResponse resp = (CoapResponse) invocation.getArguments()[0];
-                latch.countDown();
-                res = resp;
+                mLatch.countDown();
+                mResponse = resp;
                 return resp;
             }
         }).when(mockDevice).sendResponse(Mockito.anyObject());
@@ -81,8 +81,8 @@ public class ResourcePresenceResourceTest {
         IRequest request = MessageBuilder.createRequest(RequestMethod.GET,
                 RDServerTestUtils.RES_PRS_URI, "di=" + RDServerTestUtils.DI);
         mResPresenceResource.onDefaultRequestReceived(mockDevice, request);
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.CONTENT));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
     }
 
     @Test
@@ -125,8 +125,8 @@ public class ResourcePresenceResourceTest {
         mRDResource.onDefaultRequestReceived(mockDevice,
                 RDServerTestUtils.makePublishRequest());
         // assertion: if the response status is "CHANGED"
-        assertTrue(latch.await(2L, SECONDS));
-        assertTrue(methodCheck(res, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
     }
 
     private boolean methodCheck(IResponse response,
index b9335c1..aadd7a4 100644 (file)
@@ -102,3 +102,8 @@ group_invite_src = [
         'group_invite/group_invite.cpp'
         ]
 cc_sample_app_env.Program('group_invite_sample', group_invite_src)
+
+group_light_share_src = [
+        'group_invite/group_light_share.cpp'
+        ]
+cc_sample_app_env.Program('group_light_share_sample', group_light_share_src)
index 344ac22..bc9a929 100644 (file)
@@ -217,6 +217,8 @@ void foundAirconditionerResource(shared_ptr<OC::OCResource> resource)
 
 void foundDevice(shared_ptr<OC::OCResource> resource)
 {
+    cout << "Found device called!" << endl;
+
     vector<string> rt = resource->getResourceTypes();
 
     cout << "Device found: " << resource->uri() << endl;
@@ -248,6 +250,12 @@ void foundDevice(shared_ptr<OC::OCResource> resource)
     }
 }
 
+void errorFoundDevice(const std::string &uri, const int ecode)
+{
+    cout << "Found device error on " << uri << " code " << ecode << endl;
+    g_callbackLock.notify_all();
+}
+
 void presenceDevice(OCStackResult , const unsigned int i, const string &str)
 {
     cout << "Presence received, i=" << i << " str=" << str << endl;
@@ -325,7 +333,7 @@ int main(int argc, char *argv[])
 
     result = OCPlatform::findResource(g_host, "/oic/res?rt=oic.wk.d",
                                       static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4),
-                                      &foundDevice);
+                                      &foundDevice, &errorFoundDevice);
 
     cout << " result: " << result << endl;
 
index b51789c..ec85e5e 100644 (file)
@@ -241,143 +241,150 @@ int main(int argc, char *argv[])
     {
         cin >> cmd;
 
-        QueryParamsMap query;
-        OCRepresentation rep;
-
-        switch (atoi(cmd.c_str()))
+        try
         {
-            case 1:
-                cout << "Put userUUID to search:" << endl;
-                cin >> cmd;
-                result = accountMgr->searchUser(cmd, &ocPost);
-                break;
-
-            case 2:
-                cout << "Put email to search:" << endl;
-                cin >> cmd;
-                query["email"] = cmd;
-                result = accountMgr->searchUser(query, &ocPost);
-                break;
-
-            case 3:
-                cout << "Put phone number to search:" << endl;
-                cin >> cmd;
-                query["phone"] = cmd;
-                result = accountMgr->searchUser(query, &ocPost);
-                break;
-
-            case 4:
-                cout << "PUT deviceID to delete:";
-                cin >> cmd;
-                result = accountMgr->deleteDevice(cmd, &onDelete);
-                break;
-
-            case 5:
-                result = accountMgr->createGroup(OC::AclGroupType::PUBLIC, &ocPost);
-                break;
-
-            case 6:
-                cout << "PUT groupId to observe:";
-                cin >> cmd;
-                result = accountMgr->observeGroup(cmd, &onObserve);
-                break;
-
-            case 7:
-                result = accountMgr->getGroupList(&ocPost);
-                break;
-
-            case 8:
-                cout << "PUT groupId to delete:";
-                cin >> cmd;
-                result = accountMgr->deleteGroup(cmd, &onDelete);
-                break;
-
-            case 9:
-                cout << "PUT groupId to join:";
-                cin >> cmd;
-                result = accountMgr->joinGroup(cmd, &ocPost);
-                break;
-
-            case 10:
-                cout << "PUT groupId to add device:";
-                cin >> cmd;
-                cout << "PUT deviceId to add to group:";
-                cin >> cmd2;
-                {
-                    vector<string> deviceIds;
-                    deviceIds.push_back(cmd2);
-                    result = accountMgr->addDeviceToGroup(cmd, deviceIds, &ocPost);
-                }
-                break;
-
-            case 11:
-                cout << "PUT groupId to get info:";
-                cin >> cmd;
-                result = accountMgr->getGroupInfo(cmd, &ocPost);
-                break;
-
-            case 12:
-                cout << "PUT groupId to leave:";
-                cin >> cmd;
-                result = accountMgr->leaveGroup(cmd, &onDelete);
-                break;
-
-            case 13:
-                cout << "PUT groupId to remove device:";
-                cin >> cmd;
-                cout << "PUT deviceId to remove from group:";
-                cin >> cmd2;
-                {
-                    vector<string> deviceIds;
-                    deviceIds.push_back(cmd2);
-                    result = accountMgr->deleteDeviceFromGroup(cmd, deviceIds, &onDelete);
-                }
-                break;
-
-            case 14:
-                result = accountMgr->observeInvitation(&onObserve);
-                break;
-
-            case 15:
-                cout << "PUT groupId to invite:";
-                cin >> cmd;
-                cout << "PUT userUUID to invite:";
-                cin >> cmd2;
-                result = accountMgr->sendInvitation(cmd, cmd2, &ocPost);
-                break;
-
-            case 16:
-                cout << "PUT groupId to cancel invitation:";
-                cin >> cmd;
-                cout << "PUT userUUID to cancel invitation:";
-                cin >> cmd2;
-                result = accountMgr->cancelInvitation(cmd, cmd2, &onDelete);
-                break;
-
-            case 17:
-                cout << "PUT groupId to delete invitation:";
-                cin >> cmd;
-                result = accountMgr->deleteInvitation(cmd, &onDelete);
-                break;
-
-            case 18:
-                cout << "PUT groupId to cancel observe:";
-                cin >> cmd;
-                result = accountMgr->cancelObserveGroup(cmd);
-                break;
-
-            case 19:
-                result = accountMgr->cancelObserveInvitation();
-                break;
-
-            case 20:
-                goto exit;
-                break;
-        }
+            QueryParamsMap query;
+            OCRepresentation rep;
+
+            switch (atoi(cmd.c_str()))
+            {
+                case 1:
+                    cout << "Put userUUID to search:" << endl;
+                    cin >> cmd;
+                    result = accountMgr->searchUser(cmd, &ocPost);
+                    break;
+
+                case 2:
+                    cout << "Put email to search:" << endl;
+                    cin >> cmd;
+                    query["email"] = cmd;
+                    result = accountMgr->searchUser(query, &ocPost);
+                    break;
+
+                case 3:
+                    cout << "Put phone number to search:" << endl;
+                    cin >> cmd;
+                    query["phone"] = cmd;
+                    result = accountMgr->searchUser(query, &ocPost);
+                    break;
+
+                case 4:
+                    cout << "PUT deviceID to delete:";
+                    cin >> cmd;
+                    result = accountMgr->deleteDevice(cmd, &onDelete);
+                    break;
+
+                case 5:
+                    result = accountMgr->createGroup(OC::AclGroupType::PUBLIC, &ocPost);
+                    break;
 
-        if (result != OC_STACK_OK)
+                case 6:
+                    cout << "PUT groupId to observe:";
+                    cin >> cmd;
+                    result = accountMgr->observeGroup(cmd, &onObserve);
+                    break;
+
+                case 7:
+                    result = accountMgr->getGroupList(&ocPost);
+                    break;
+
+                case 8:
+                    cout << "PUT groupId to delete:";
+                    cin >> cmd;
+                    result = accountMgr->deleteGroup(cmd, &onDelete);
+                    break;
+
+                case 9:
+                    cout << "PUT groupId to join:";
+                    cin >> cmd;
+                    result = accountMgr->joinGroup(cmd, &ocPost);
+                    break;
+
+                case 10:
+                    cout << "PUT groupId to add device:";
+                    cin >> cmd;
+                    cout << "PUT deviceId to add to group:";
+                    cin >> cmd2;
+                    {
+                        vector<string> deviceIds;
+                        deviceIds.push_back(cmd2);
+                        result = accountMgr->addDeviceToGroup(cmd, deviceIds, &ocPost);
+                    }
+                    break;
+
+                case 11:
+                    cout << "PUT groupId to get info:";
+                    cin >> cmd;
+                    result = accountMgr->getGroupInfo(cmd, &ocPost);
+                    break;
+
+                case 12:
+                    cout << "PUT groupId to leave:";
+                    cin >> cmd;
+                    result = accountMgr->leaveGroup(cmd, &onDelete);
+                    break;
+
+                case 13:
+                    cout << "PUT groupId to remove device:";
+                    cin >> cmd;
+                    cout << "PUT deviceId to remove from group:";
+                    cin >> cmd2;
+                    {
+                        vector<string> deviceIds;
+                        deviceIds.push_back(cmd2);
+                        result = accountMgr->deleteDeviceFromGroup(cmd, deviceIds, &onDelete);
+                    }
+                    break;
+
+                case 14:
+                    result = accountMgr->observeInvitation(&onObserve);
+                    break;
+
+                case 15:
+                    cout << "PUT groupId to invite:";
+                    cin >> cmd;
+                    cout << "PUT userUUID to invite:";
+                    cin >> cmd2;
+                    result = accountMgr->sendInvitation(cmd, cmd2, &ocPost);
+                    break;
+
+                case 16:
+                    cout << "PUT groupId to cancel invitation:";
+                    cin >> cmd;
+                    cout << "PUT userUUID to cancel invitation:";
+                    cin >> cmd2;
+                    result = accountMgr->cancelInvitation(cmd, cmd2, &onDelete);
+                    break;
+
+                case 17:
+                    cout << "PUT groupId to delete invitation:";
+                    cin >> cmd;
+                    result = accountMgr->deleteInvitation(cmd, &onDelete);
+                    break;
+
+                case 18:
+                    cout << "PUT groupId to cancel observe:";
+                    cin >> cmd;
+                    result = accountMgr->cancelObserveGroup(cmd);
+                    break;
+
+                case 19:
+                    result = accountMgr->cancelObserveInvitation();
+                    break;
+
+                case 20:
+                    goto exit;
+                    break;
+            }
+
+            if (result != OC_STACK_OK)
+            {
+                cout << "Error, return code: " << result << endl;
+            }
+        }
+        catch (exception e)
         {
-            cout << "Error, return code: " << result << endl;
+            cout << "Precondition failed." << endl;
         }
     }
 
diff --git a/cloud/samples/client/group_invite/group_light_share.cpp b/cloud/samples/client/group_invite/group_light_share.cpp
new file mode 100644 (file)
index 0000000..17aecff
--- /dev/null
@@ -0,0 +1,432 @@
+#include <memory>
+#include <iostream>
+#include <stdexcept>
+#include <condition_variable>
+#include <map>
+#include <vector>
+#include <string>
+#include <unistd.h>
+
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "rd_client.h"
+
+#include <OCApi.h>
+#include <OCPlatform.h>
+
+#define maxSequenceNumber 0xFFFFFF
+
+using namespace OC;
+using namespace std;
+
+string g_host = "coap+tcp://";
+condition_variable g_callbackLock;
+
+class LightResource
+{
+public:
+    /// Access this property from a TB client
+    std::string m_power;
+    std::string m_lightUri;
+    OCResourceHandle m_resourceHandle;
+    OCRepresentation m_lightRep;
+
+    /// Constructor
+    LightResource() :
+            m_power(""), m_lightUri("/a/light")
+    {
+        // Initialize representation
+        m_lightRep.setUri(m_lightUri);
+        m_lightRep.setValue("power", m_power);
+    }
+
+    /// This function internally calls registerResource API.
+    void createResource()
+    {
+        std::string resourceURI = m_lightUri; //URI of the resource
+        std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
+        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+
+        EntityHandler cb = std::bind(&LightResource::entityHandler, this, std::placeholders::_1);
+
+        // This will internally create and register the resource.
+        OCStackResult result = OCPlatform::registerResource(m_resourceHandle, resourceURI,
+                resourceTypeName, resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource creation was unsuccessful\n";
+        }
+    }
+
+    OCRepresentation post(OCRepresentation &rep)
+    {
+        m_power = rep.getValueToString("power");
+        return get();
+    }
+
+    // gets the updated representation.
+    // Updates the representation with latest internal state before
+    // sending out.
+    OCRepresentation get()
+    {
+        m_lightRep.setValue("power", m_power);
+
+        return m_lightRep;
+    }
+
+private:
+    // This is just a sample implementation of entity handler.
+    // Entity handler can be implemented in several ways by the manufacturer
+    OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
+    {
+        cout << "\tIn Server CPP entity handler:\n";
+        OCEntityHandlerResult ehResult = OC_EH_ERROR;
+        if (request)
+        {
+            // Get the request type and request flag
+            std::string requestType = request->getRequestType();
+            int requestFlag = request->getRequestHandlerFlag();
+
+            if (requestFlag & RequestHandlerFlag::RequestFlag)
+            {
+                cout << "\t\trequestFlag : Request\n";
+                auto pResponse = std::make_shared< OC::OCResourceResponse >();
+                pResponse->setRequestHandle(request->getRequestHandle());
+                pResponse->setResourceHandle(request->getResourceHandle());
+
+                // If the request type is GET
+                if (requestType == "GET")
+                {
+                    cout << "\t\t\trequestType : GET\n";
+                    pResponse->setErrorCode(200);
+                    pResponse->setResponseResult(OC_EH_OK);
+                    pResponse->setResourceRepresentation(get());
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        ehResult = OC_EH_OK;
+                    }
+                }
+                else if (requestType == "POST")
+                {
+                    cout << "\t\t\trequestType : POST\n";
+
+                    OCRepresentation rep = request->getResourceRepresentation();
+
+                    // Do related operations related to POST request
+                    OCRepresentation rep_post = post(rep);
+                    pResponse->setResourceRepresentation(rep_post);
+                    pResponse->setErrorCode(200);
+
+                    if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
+                    {
+                        ehResult = OC_EH_OK;
+                    }
+                }
+                else
+                {
+                    std::cout << "Unhandled request type" << std::endl;
+                }
+            }
+        }
+        else
+        {
+            std::cout << "Request invalid" << std::endl;
+        }
+
+        return ehResult;
+    }
+};
+
+void printRepresentation(OCRepresentation rep)
+{
+    for (auto itr = rep.begin(); itr != rep.end(); ++itr)
+    {
+        cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
+        if (itr->type() == AttributeType::Vector)
+        {
+            switch (itr->base_type())
+            {
+                case AttributeType::OCRepresentation:
+                    for (auto itr2 : (*itr).getValue< vector< OCRepresentation > >())
+                    {
+                        printRepresentation(itr2);
+                    }
+                    break;
+
+                case AttributeType::Integer:
+                    for (auto itr2 : (*itr).getValue< vector< int > >())
+                    {
+                        cout << "\t\t" << itr2 << endl;
+                    }
+                    break;
+
+                case AttributeType::String:
+                    for (auto itr2 : (*itr).getValue< vector< string > >())
+                    {
+                        cout << "\t\t" << itr2 << endl;
+                    }
+                    break;
+
+                default:
+                    cout << "Unhandled base type " << itr->base_type() << endl;
+                    break;
+            }
+        }
+        else if (itr->type() == AttributeType::OCRepresentation)
+        {
+            printRepresentation((*itr).getValue< OCRepresentation >());
+        }
+    }
+}
+
+void getResource(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
+{
+    cout << "Resource get: " << ecode << endl;
+
+    printRepresentation(rep);
+}
+
+void foundMyDevice(shared_ptr< OC::OCResource > resource)
+{
+    cout << "Device found: " << resource->uri() << endl;
+    cout << "DI: " << resource->sid() << endl;
+
+    g_callbackLock.notify_all();
+}
+
+void foundDevice(shared_ptr< OC::OCResource > resource)
+{
+    vector < string > rt = resource->getResourceTypes();
+
+    cout << "Device found: " << resource->uri() << endl;
+    cout << "DI: " << resource->sid() << endl;
+
+    QueryParamsMap query;
+    resource->get(query, &getResource);
+}
+
+void onObserveGroup(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep,
+        const int &eCode, const int /*&sequenceNumber*/)
+{
+    cout << "onObserveGroup response received code: " << eCode << endl;
+
+    if (eCode == OC_STACK_OK)
+    {
+        printRepresentation(rep);
+
+        vector < string > dilist = rep.getValue < vector< string > > ("dilist");
+
+        for (auto itr = dilist.begin(); itr != dilist.end(); ++itr)
+        {
+            cout << (*itr) << " discovered" << endl;
+            if ((*itr) != OCGetServerInstanceIDString())
+            {
+                cout << "New device joined" << endl;
+                string query = "/oic/res?di=";
+                query += (*itr);
+                OCStackResult result = OC_STACK_ERROR;
+
+                cout << "find my resource : " << *itr << endl;
+                result = OCPlatform::findResource(g_host, query,
+                        static_cast< OCConnectivityType >(CT_ADAPTER_TCP | CT_IP_USE_V4),
+                        &foundDevice);
+                cout << " result: " << result << endl;
+                break;
+            }
+        }
+    }
+    g_callbackLock.notify_all();
+}
+
+string g_invitedGroup;
+void onInvite(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep, const int &eCode,
+        const int &sequenceNumber)
+{
+    cout << "onInvite response received code: " << eCode << endl;
+
+    if (eCode == OC_STACK_OK)
+    {
+        printRepresentation(rep);
+
+        if (sequenceNumber != OC_OBSERVE_REGISTER)
+        {
+            vector < OCRepresentation > invited = rep.getValue < vector< OCRepresentation >
+                    > ("invited");
+
+            g_invitedGroup = invited[0].getValueToString("gid");
+        }
+    }
+
+    g_callbackLock.notify_all();
+}
+
+string g_gid;
+void onCreateGroup(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
+{
+    cout << "onCreateGroup response received code: " << ecode << endl;
+
+    if (ecode == 4)
+    {
+        printRepresentation(rep);
+        g_gid = rep.getValueToString("gid");
+    }
+
+    g_callbackLock.notify_all();
+}
+
+void onPublish(const OCRepresentation &, const int &eCode)
+{
+    cout << "Publish resource response received, code: " << eCode << endl;
+    g_callbackLock.notify_all();
+}
+
+void onPost(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode)
+{
+    if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CHANGED)
+    {
+        cout << "\tRequest was successful: " << eCode << endl;
+
+        printRepresentation(rep);
+    }
+    else
+    {
+        cout << "\tResponse error: " << eCode << endl;
+    }
+
+    g_callbackLock.notify_all();
+}
+
+string g_uid;
+string g_accesstoken;
+
+void handleLoginoutCB(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
+{
+    cout << "Auth response received code: " << ecode << endl;
+
+    if (rep.getPayload() != NULL)
+    {
+        printRepresentation(rep);
+    }
+
+    if (ecode == 4)
+    {
+        g_accesstoken = rep.getValueToString("accesstoken");
+
+        g_uid = rep.getValueToString("uid");
+    }
+
+    g_callbackLock.notify_all();
+}
+
+string g_option;
+
+static FILE *client_open(const char * /*path*/, const char *mode)
+{
+    string option = "./";
+    option += g_option;
+    option += ".dat";
+    return fopen(option.c_str(), mode);
+}
+
+int main(int argc, char **argv)
+{
+    if (argc != 5)
+    {
+        cout
+                << "Put \"[host-ipaddress:port] [authprovider] [authcode] [\'owner\'|\'member\']\" for sign-up and sign-in"
+                << endl;
+        cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in" << endl;
+        return 0;
+    }
+
+    g_option = argv[4];
+
+    OCPersistentStorage ps
+    { client_open, fread, fwrite, fclose, unlink };
+
+    PlatformConfig cfg
+    { ServiceType::InProc, ModeType::Both, "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
+            0, // Uses randomly available port
+            QualityOfService::LowQos, &ps };
+
+    OCPlatform::Configure(cfg);
+
+    OCStackResult result = OC_STACK_ERROR;
+
+    g_host += argv[1];
+
+    OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
+            CT_ADAPTER_TCP);
+
+    mutex blocker;
+    unique_lock < mutex > lock(blocker);
+
+    if (g_option == "1")
+    {
+        accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
+        g_callbackLock.wait(lock);
+    }
+    else
+    {
+        accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
+        g_callbackLock.wait(lock);
+        accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
+        g_callbackLock.wait(lock);
+    }
+
+    string cmd;
+
+    LightResource lightResource;
+    lightResource.createResource();
+
+    ResourceHandles resourceHandles;
+    resourceHandles.push_back(lightResource.m_resourceHandle);
+
+    OCPlatform::publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, resourceHandles,
+            &onPublish);
+    g_callbackLock.wait(lock);
+    if (g_option == "owner")
+    {
+        cout << "Creating group" << endl;
+        accountMgr->createGroup(AclGroupType::PUBLIC, &onCreateGroup);
+        g_callbackLock.wait(lock);
+        cout << "Adding device " << OCGetServerInstanceIDString() << " to group " << g_gid << endl;
+        accountMgr->addDeviceToGroup(g_gid,
+        { OCGetServerInstanceIDString() }, &onPost);
+        g_callbackLock.wait(lock);
+
+        accountMgr->observeGroup(g_gid, &onObserveGroup);
+        g_callbackLock.wait(lock);
+        cout << "Put userUUID to send invitation" << endl;
+        cin >> cmd;
+        cout << "Group id : " << g_gid << " send invitation to " << cmd << endl;
+        accountMgr->sendInvitation(g_gid, cmd, &onPost);
+        g_callbackLock.wait(lock);
+
+        cin >> cmd;
+    }
+    else if (g_option == "member")
+    {
+        cout << "Observing invitation" << endl;
+        accountMgr->observeInvitation(&onInvite);
+        g_callbackLock.wait(lock);
+        cout << "Waiting invitation" << endl;
+        g_callbackLock.wait(lock);
+        cout << "Joining group " << g_invitedGroup << endl;
+        accountMgr->joinGroup(g_invitedGroup, &onPost);
+        g_callbackLock.wait(lock);
+
+        cout << "find my resource " << cmd << endl;
+        result = OCPlatform::findResource(g_host, "/oic/res",
+                static_cast< OCConnectivityType >(CT_ADAPTER_TCP | CT_IP_USE_V4), &foundMyDevice);
+        g_callbackLock.wait(lock);
+
+        accountMgr->observeGroup(g_invitedGroup, &onObserveGroup);
+        g_callbackLock.wait(lock);
+
+        cin >> cmd;
+    }
+
+    return 0;
+}
index f04e037..743b794 100644 (file)
@@ -216,66 +216,89 @@ int main(int argc, char *argv[])
     {
         cin >> cmd;
 
-        QueryParamsMap query;
-        OCRepresentation rep;
-        string      topicType;
-
-        switch (cmd[0])
+        try
         {
-            case '0':
-                gTopicList.clear();
-                cout << "Discovering topics" << endl;
-                result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
-                break;
-
-            case '1':
-                gTopicList.clear();
-                cout << "Put topic type to discover: ";
-                cin >> cmd;
-                query["rt"] = cmd;
-                result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
-                break;
-
-            case '2':
-                cout << "Put discovered topic index to select: ";
-                cin >> cmd;
-                g_mqSelectedTopicResource = gTopicList[atoi(cmd.c_str())];
-                cout << g_mqSelectedTopicResource->uri() << " selected" << endl;
-                break;
-
-            case '3':
-                cout << "Put message to selected topic: ";
-                cin >> cmd;
-                rep["message"] = cmd;
-                result = g_mqSelectedTopicResource->publishMQTopic(rep, query, &publishMessageCB,
-                         QualityOfService::LowQos);
-                break;
-
-            case '4':
-                cout << "Put topic uri to create: ";
-                cin >> cmd;
-                result = g_mqBrokerResource->createMQTopic(rep, cmd, query, &createTopicCB,
-                         QualityOfService::LowQos);
-                break;
-
-            case '5':
-                cout << "Put topic uri to create: ";
-                cin >> cmd;
-                cout << "Put topic type: ";
-                cin >> topicType;
-                query["rt"] = topicType;
-                result = g_mqBrokerResource->createMQTopic(rep, cmd, query, &createTopicCB,
-                         QualityOfService::LowQos);
-                break;
-
-            case 'q':
-                goto exit;
-                break;
-        }
 
-        if (result != OC_STACK_OK)
+            QueryParamsMap query;
+            OCRepresentation rep;
+            string      topicType;
+
+            switch (cmd[0])
+            {
+                case '0':
+                    gTopicList.clear();
+                    cout << "Discovering topics" << endl;
+                    result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
+                    break;
+
+                case '1':
+                    gTopicList.clear();
+                    cout << "Put topic type to discover: ";
+                    cin >> cmd;
+                    query["rt"] = cmd;
+                    result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
+                    break;
+
+                case '2':
+                    cout << "Put discovered topic index to select: ";
+                    cin >> cmd;
+                    {
+                        int index = atoi(cmd.c_str());
+                        if (index < 0 || (unsigned int) index >= gTopicList.size())
+                        {
+                            cout << "invalid topic index selected" << endl;
+                            continue;
+                        }
+
+                        g_mqSelectedTopicResource = gTopicList[index];
+                        cout << g_mqSelectedTopicResource->uri() << " selected" << endl;
+                    }
+                    break;
+
+                case '3':
+                    if (g_mqSelectedTopicResource == nullptr)
+                    {
+                        cout << "Topic is not selected." << endl;
+                        continue;
+                    }
+
+                    cout << "Put message to selected topic: ";
+                    cin >> cmd;
+                    rep["message"] = cmd;
+                    result = g_mqSelectedTopicResource->publishMQTopic(rep, query, &publishMessageCB,
+                             QualityOfService::LowQos);
+                    break;
+
+                case '4':
+                    cout << "Put topic uri to create: ";
+                    cin >> cmd;
+                    result = g_mqBrokerResource->createMQTopic(rep, cmd, query, &createTopicCB,
+                             QualityOfService::LowQos);
+                    break;
+
+                case '5':
+                    cout << "Put topic uri to create: ";
+                    cin >> cmd;
+                    cout << "Put topic type: ";
+                    cin >> topicType;
+                    query["rt"] = topicType;
+                    result = g_mqBrokerResource->createMQTopic(rep, cmd, query, &createTopicCB,
+                             QualityOfService::LowQos);
+                    break;
+
+                case 'q':
+                    goto exit;
+                    break;
+            }
+
+            if (result != OC_STACK_OK)
+            {
+                cout << "Error, return code: " << result << endl;
+            }
+        }
+        catch (const exception &e)
         {
-            cout << "Error, return code: " << result << endl;
+            cout << "Precondition failed: " << e.what() << endl;
         }
     }
 
index bd60726..fbebe6e 100644 (file)
@@ -229,51 +229,78 @@ int main(int argc, char *argv[])
     {
         cin >> cmd;
 
-        QueryParamsMap query;
-        OCRepresentation rep;
-
-        switch (cmd[0])
+        try
         {
-            case '0':
-                gTopicList.clear();
-                cout << "Discovering topics" << endl;
-                result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
-                break;
-
-            case '1':
-                gTopicList.clear();
-                cout << "Put topic type to discover: ";
-                cin >> cmd;
-                query["rt"] = cmd;
-                result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
-                break;
-
-            case '2':
-                cout << "Put discovered topic index to select: ";
-                cin >> cmd;
-                g_mqSelectedTopicResource = gTopicList[atoi(cmd.c_str())];
-                cout << g_mqSelectedTopicResource->uri() << " selected" << endl;
-                break;
-
-            case '3':
-                cout << "Subscribe to selected topic" << endl;
-                result = g_mqSelectedTopicResource->subscribeMQTopic(ObserveType::Observe, query, &subscribeCB,
-                         QualityOfService::LowQos);
-                break;
-
-            case '4':
-                cout << "Unsubscribe to selected topic" << endl;
-                result = g_mqSelectedTopicResource->unsubscribeMQTopic(QualityOfService::LowQos);
-                break;
-
-            case 'q':
-                goto exit;
-                break;
-        }
+            QueryParamsMap query;
+            OCRepresentation rep;
+
+            switch (cmd[0])
+            {
+                case '0':
+                    gTopicList.clear();
+                    cout << "Discovering topics" << endl;
+                    result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
+                    break;
+
+                case '1':
+                    gTopicList.clear();
+                    cout << "Put topic type to discover: ";
+                    cin >> cmd;
+                    query["rt"] = cmd;
+                    result = g_mqBrokerResource->discoveryMQTopics(query, &discoverTopicCB, QualityOfService::LowQos);
+                    break;
+
+                case '2':
+                    cout << "Put discovered topic index to select: ";
+                    cin >> cmd;
+                    {
+                        int index = atoi(cmd.c_str());
+                        if (index < 0 || (unsigned int) index >= gTopicList.size())
+                        {
+                            cout << "invalid topic index selected" << endl;
+                            continue;
+                        }
+
+                        g_mqSelectedTopicResource = gTopicList[index];
+                        cout << g_mqSelectedTopicResource->uri() << " selected" << endl;
+                    }
+                    break;
+
+                case '3':
+                    if (g_mqSelectedTopicResource == nullptr)
+                    {
+                        cout << "Topic is not selected." << endl;
+                        continue;
+                    }
+
+                    cout << "Subscribe to selected topic" << endl;
+                    result = g_mqSelectedTopicResource->subscribeMQTopic(ObserveType::Observe, query, &subscribeCB,
+                             QualityOfService::LowQos);
+                    break;
+
+                case '4':
+                    if (g_mqSelectedTopicResource == nullptr)
+                    {
+                        cout << "Topic is not selected." << endl;
+                        continue;
+                    }
+                    cout << "Unsubscribe to selected topic" << endl;
+                    result = g_mqSelectedTopicResource->unsubscribeMQTopic(QualityOfService::LowQos);
+                    break;
 
-        if (result != OC_STACK_OK)
+                case 'q':
+                    goto exit;
+                    break;
+            }
+
+            if (result != OC_STACK_OK)
+            {
+                cout << "Error, return code: " << result << endl;
+            }
+        }
+        catch (const exception &e)
         {
-            cout << "Error, return code: " << result << endl;
+            cout << "Precondition failed: " << e.what() << endl;
         }
     }
 
index 9f2104e..17cec71 100644 (file)
@@ -43,7 +43,7 @@ using namespace std;
 #define DEFAULT_AUTH_REFRESH "/oic/account/tokenrefresh"
 
 OCStackResult OCCloudSignup(const char *host, const char *deviceId, const char *authprovider,
-        const char *authcode, OCClientResponseHandler response)
+                            const char *authcode, OCClientResponseHandler response)
 {
     char targetUri[MAX_URI_LENGTH * 2] =
     { 0, };
@@ -66,15 +66,16 @@ OCStackResult OCCloudSignup(const char *host, const char *deviceId, const char *
     OCRepPayloadSetPropString(registerPayload, "authcode", authcode);
 
     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) registerPayload,
-            CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 
-    no_memory: OCRepPayloadDestroy(registerPayload);
+no_memory:
+    OCRepPayloadDestroy(registerPayload);
     return OC_STACK_NO_MEMORY;
 }
 
 OCStackResult OCCloudSession(const char *host, const char *query, const char *uId,
-        const char *deviceId, const char *accesstoken, bool isLogin,
-        OCClientResponseHandler response)
+                             const char *deviceId, const char *accesstoken, bool isLogin,
+                             OCClientResponseHandler response)
 {
     char targetUri[MAX_URI_LENGTH * 2] =
     { 0, };
@@ -109,15 +110,16 @@ OCStackResult OCCloudSession(const char *host, const char *query, const char *uI
     OCRepPayloadSetPropBool(loginoutPayload, "login", isLogin);
 
     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) loginoutPayload,
-            CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 
-    no_memory: OCRepPayloadDestroy(loginoutPayload);
+no_memory:
+    OCRepPayloadDestroy(loginoutPayload);
     return OC_STACK_NO_MEMORY;
 }
 
 //Client should call refresh before expiresin or when receive 4.01 during sign-in
 OCStackResult OCCloudRefresh(const char *host, const char *query, const char *uId,
-        const char *deviceId, const char *refreshtoken, OCClientResponseHandler response)
+                             const char *deviceId, const char *refreshtoken, OCClientResponseHandler response)
 {
     char targetUri[MAX_URI_LENGTH * 2] =
     { 0, };
@@ -141,14 +143,15 @@ OCStackResult OCCloudRefresh(const char *host, const char *query, const char *uI
     OCRepPayloadSetPropString(refreshPayload, "refreshtoken", refreshtoken);
 
     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) refreshPayload,
-            CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 
-    no_memory: OCRepPayloadDestroy(refreshPayload);
+no_memory:
+    OCRepPayloadDestroy(refreshPayload);
     return OC_STACK_NO_MEMORY;
 }
 
 OCStackResult OCCloudLogin(const char *host, const char *uId, const char *deviceId,
-        const char *accesstoken, OCClientResponseHandler response)
+                           const char *accesstoken, OCClientResponseHandler response)
 {
     return OCCloudSession(host, DEFAULT_AUTH_SESSION, uId, deviceId, accesstoken, true, response);
 }
@@ -198,10 +201,6 @@ OCRepPayload *constructResponse(OCEntityHandlerRequest *ehRequest)
     {
         currLightResource = &gLightInstance[0];
     }
-    else if (ehRequest->resource == gLightInstance[1].handle)
-    {
-        currLightResource = &gLightInstance[1];
-    }
 
     if (OC_REST_PUT == ehRequest->method)
     {
@@ -276,17 +275,13 @@ void *ChangeLightRepresentation(void *param)
     {
         sleep(3);
         gLightInstance[0].power += 1;
-        gLightInstance[1].power += 3;
 
         if (gLightUnderObservation)
         {
             cout << " =====> Notifying stack of new power level " << gLightInstance[0].power
-                    << endl;
-            cout << " =====> Notifying stack of new power level " << gLightInstance[1].power
-                    << endl;
+                 << endl;
             // Notifying all observers
             result = OCNotifyAllObservers(gLightInstance[0].handle, OC_NA_QOS);
-            result = OCNotifyAllObservers(gLightInstance[1].handle, OC_NA_QOS);
 
             cout << " =====> Notifying result " << result << endl;
         }
@@ -297,7 +292,7 @@ void *ChangeLightRepresentation(void *param)
 void ProcessObserveRegister(OCEntityHandlerRequest *ehRequest)
 {
     cout << "Received observation registration request with observation Id "
-            << ehRequest->obsInfo.obsId << endl;
+         << ehRequest->obsInfo.obsId << endl;
 
     if (!observeThreadStarted)
     {
@@ -321,7 +316,7 @@ void ProcessObserveDeregister(OCEntityHandlerRequest *ehRequest)
     bool clientStillObserving = false;
 
     cout << "Received observation deregistration request for observation Id "
-            << ehRequest->obsInfo.obsId << endl;
+         << ehRequest->obsInfo.obsId << endl;
     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
     {
         if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
@@ -339,13 +334,15 @@ void ProcessObserveDeregister(OCEntityHandlerRequest *ehRequest)
 }
 
 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest, void * /*callback*/)
+                                        OCEntityHandlerRequest *entityHandlerRequest, void * /*callback*/)
 {
     OCEntityHandlerResult ehResult = OC_EH_OK;
     OCEntityHandlerResponse response =
-    { 0, 0, OC_EH_ERROR, 0, 0,
-    { },
-    { 0 }, false };
+    {
+        0, 0, OC_EH_ERROR, 0, 0,
+        { },
+        { 0 }, false
+    };
 
     // Validate pointer
     if (!entityHandlerRequest)
@@ -357,7 +354,7 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
     // Initialize certain response fields
     response.numSendVendorSpecificHeaderOptions = 0;
     memset(response.sendVendorSpecificHeaderOptions, 0,
-            sizeof response.sendVendorSpecificHeaderOptions);
+           sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
     OCRepPayload *payload = nullptr;
 
@@ -378,7 +375,7 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
         else
         {
             cout << "Received unsupported method %d from client " << entityHandlerRequest->method
-                    << endl;
+                 << endl;
             ehResult = OC_EH_ERROR;
         }
         // If the result isn't an error or forbidden, send response
@@ -431,7 +428,7 @@ int createLightResource(char *uri, LightResource *lightResource)
     lightResource->state = false;
     lightResource->power = 0;
     OCStackResult res = OCCreateResource(&(lightResource->handle), "core.light", "oc.mi.def", uri,
-            OCEntityHandlerCb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+                                         OCEntityHandlerCb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
     cout << "Created Light resource with result:" << res << endl;
 
     return res;
@@ -550,7 +547,7 @@ OCStackApplicationResult handleLoginoutCB(void *ctx, OCDoHandle /*handle*/,
     cout << "Login/out response received code: " << clientResponse->result << endl;
 
     if (clientResponse->payload != NULL
-            && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
+        && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
     {
         cout << "PAYLOAD_TYPE_REPRESENTATION received" << endl;
 
@@ -578,7 +575,7 @@ OCStackApplicationResult handleRegisterCB(void *ctx, OCDoHandle /*handle*/,
     cout << "Register response received code: " << clientResponse->result << endl;
 
     if (clientResponse->payload != NULL
-            && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
+        && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
     {
         cout << "PAYLOAD_TYPE_REPRESENTATION received" << endl;
         cout << "You can Sign-In using retrieved accesstoken when disconnected or reboot" << endl;
@@ -675,21 +672,21 @@ int main(int argc, char *argv[])
         case 2:
             cout << "Sign-Up to cloud using " << authProvider << " " << authCode << endl;
             res = OCCloudSignup(g_host.c_str(), OCGetServerInstanceIDString(), authProvider.c_str(),
-                    authCode.c_str(), handleRegisterCB);
+                                authCode.c_str(), handleRegisterCB);
             cout << "OCCloudSignup return " << res << endl;
             break;
 
         case 4:
             cout << "Sign-In to cloud using " << accessToken << endl;
             res = OCCloudLogin(g_host.c_str(), uId.c_str(), OCGetServerInstanceIDString(),
-                    accessToken.c_str(), handleLoginoutCB);
+                               accessToken.c_str(), handleLoginoutCB);
             cout << "OCCloudLogin return " << res << endl;
             break;
 
         case 5:
             cout << "Token refresh to cloud using the refresh token " << refreshToken << endl;
             res = OCCloudRefresh(g_host.c_str(), DEFAULT_AUTH_REFRESH, uId.c_str(),
-                    OCGetServerInstanceIDString(), refreshToken.c_str(), handleRegisterCB);
+                                 OCGetServerInstanceIDString(), refreshToken.c_str(), handleRegisterCB);
             cout << "OCCloudRefresh return " << res << endl;
             break;
 
index 369e268..d98b531 100644 (file)
@@ -131,16 +131,17 @@ public class CoapClient implements IRequestChannel, IResponseEventHandler {
         }
 
         // Subscription response should stored
-        if (reqInfo.observe != Observe.SUBSCRIBE) {
+        if (reqInfo.observe != Observe.SUBSCRIBE
+                || coapResponse.getSequenceNumber() == -1) {
             mTokenExchanger.remove(Bytes.bytesToLong(coapResponse.getToken()));
-            if (reqInfo.observe == Observe.UNSUBSCRIBE && mSubscription
+            if (mSubscription
                     .containsKey(Bytes.bytesToLong(reqInfo.originToken))) {
                 mSubscription.remove(Bytes.bytesToLong(reqInfo.originToken));
             }
         }
 
         coapResponse.setToken(reqInfo.originToken);
-        reqInfo.responseHandler.onResponseReceived(response);
+        reqInfo.responseHandler.onResponseReceived(coapResponse);
     }
 
     private void addObserve(long token, long newtoken) {
index 196ecca..7ab584e 100644 (file)
@@ -142,14 +142,14 @@ public class CoapDevice extends Device {
     @Override
     public void sendResponse(IResponse response) {
         // This message must converted to CoapResponse
-        CoapResponse coapResp = (CoapResponse) response;
+        CoapResponse coapResponse = (CoapResponse) response;
 
         Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
         while (iterator.hasNext()) {
             Long token = iterator.next();
-            Long respToken = Bytes.bytesToLong(coapResp.getToken());
+            Long respToken = Bytes.bytesToLong(coapResponse.getToken());
             if (respToken.equals(token)
-                    && coapResp.getObserve().equals(Observe.UNSUBSCRIBE)) {
+                    && coapResponse.getSequenceNumber() == -1) {
                 iterator.remove();
             }
         }