- 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)
- 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
#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
serverSystem.addResource(new AclResource());
- serverSystem.addResource(new CrlResource());
-
- serverSystem.addResource(new AclResource());
-
serverSystem.addResource(new InviteResource());
serverSystem.addServer(new CoapServer(
*/
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";
}
}
+ /**
+ * API to implement singleton pattern based DB manager
+ *
+ * @return account DB manager
+ */
public static AccountDBManager getInstance() {
return accoutDBManager;
*
* @param tableName
* table name to be inserted
- * @param insert
+ * @param record
* record to be inserted
*/
public void insertRecord(String tableName, HashMap<String, Object> insert) {
if (!_updateRecord(tableName, replace))
throw new InternalServerErrorException(
- "Database record updateX509CRL failed");
+ "Database record update failed");
}
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;
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();
}
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;
}
/**
*
- * 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;
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();
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;
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();
@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);
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) {
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();
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;
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() {
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");
}
}
}
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")
}
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()
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);
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;
* This class provides a set of APIs to invite a user to a group
*
*/
-
public class InviteManager {
private TypeCastingManager<InviteTable> mTypeInvite = new TypeCastingManager<>();
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
}
}
- 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);
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<>();
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<>();
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);
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));
+ }
}
}
}
-}
+}
\ No newline at end of file
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));
request);
break;
case UNSUBSCRIBE:
- responsePayload = mInviteManager.removeSubscriber(uid);
+ responsePayload = mInviteManager.removeSubscriber(uid, request);
break;
default:
break;
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);
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;
}
}
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
*/
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 {
}
/**
- * 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();
}
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 {
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) {
}
/**
- * 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);
}
/**
- * 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<>();
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),
return null;
}
}
-}
+}
\ No newline at end of file
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;
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);
}
}
+ /**
+ * 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 {
}
/**
- * 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());
}
}
}
}
/**
- * This class is used for response
+ * Response utility class.
*/
private static final class CSR {
this.data = data;
}
+ /**
+ * Return encoding.
+ */
public String getEncoding() {
return encoding;
}
+ /**
+ * Retrieves data.
+ */
public byte[] getData() {
return data;
}
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;
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 {
/**
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());
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());
+ }
}
}
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) {
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);
+ }
}
/**
}
/**
- * Static inner class for CBOR Crl presentation.
+ * Utility class for CBOR Crl presentation.
*/
private static final class CRL {
private final byte[] data;
- public CRL(String encoding, byte[] data) {
+ CRL(String encoding, byte[] data) {
this.encoding = encoding;
this.data = data;
}
return data;
}
}
-
}
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 {
}
/**
- * 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 {
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());
}
}
/**
- * 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;
*/
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;
* 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;
}
/**
/**
* 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(
Integer.parseInt(NOT_AFTER_INTERVAL));
return calendar.getTime();
}
-
-
}
\ No newline at end of file
/**
* Returns ASN1Encodable attribute value.
- *
- * @return
*/
ASN1Encodable getValue() {
return value;
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 {
/**
public static final CrlIssuer CRL_ISSUER = new CrlIssuer();
/**
- * Creates new instance of CRL issuer.
+ * Private constructor to make class non-instantiable.
*/
private 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);
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
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;
}).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);
.parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
HashMap<String, Object> getUserInfo = ((ArrayList<HashMap<String, Object>>) payloadData
.get("ulist")).get(0);
+
assertTrue(getUserInfo.get("uid").equals(uuid));
}
*/
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;
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);
@AfterClass
public static void after() {
KEYSTORE_FILE.delete();
+ AccountDBManager.getInstance().deleteRecord(Constants.CERTIFICATE_TABLE, new HashMap<>());
}
@BeforeClass
Object[] args = invocation.getArguments();
CoapResponse resp = (CoapResponse) args[0];
mResponse = resp;
-
-
mLatch.countDown();
return null;
}
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);
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;
}
}
- 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;
- }
-
}
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;
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;
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;
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;
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;
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();
}
/**
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;
}
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();
}
@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();
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());
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;
}).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();
package org.iotivity.cloud.accountserver.resources.account.tokenrefresh;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import java.text.DateFormat;
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;
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 {
.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)
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");
}
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");
}
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");
}
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");
}
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,
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;
- }
}
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;
}).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();
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;
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;
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;
}
@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);
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
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";
}
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;
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) {
}
}
+ /**
+ * 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) {
}
}
+ /**
+ * API for getting device information.
+ *
+ * @param deviceId
+ * device id to get device
+ */
public Device queryDevice(String deviceId) {
Device device = null;
synchronized (mMapDevice) {
CoapDevicePool mDevicePool = new CoapDevicePool();
+ /**
+ *
+ * This class provides a set of APIs to manage life cycle of coap message.
+ *
+ */
@Sharable
class CoapLifecycleHandler extends ChannelDuplexHandler {
@Override
}
}
+ /**
+ * 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<>();
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;
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;
}
}
+ /**
+ * 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);
}
}
- // This is optional method for packet handling
@Override
public void onDefaultRequestReceived(Device srcDevice, IRequest request)
throws ServerException {
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;
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<>();
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;
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;
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;
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");
}
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;
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<>();
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;
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");
}
}
null, ContentFormat.APPLICATION_CBOR,
convertedPayload);
- mRDServer.sendRequest(mRequest, new PublishResponseHandler(
- mSrcDevice));
+ mRDServer.sendRequest(mRequest,
+ new PublishResponseHandler(mSrcDevice));
break;
default:
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) {
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);
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;
}
}
} 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);
}
}
}
- 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;
}
@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
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<>();
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 {
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();
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
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));
// 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() {
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);
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()) {
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<>();
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;
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);
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);
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;
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);
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);
return true;
}
+ /**
+ * API to close Kafka consumer connection
+ */
public void closeConnection() {
if (mConsumerStarted == true) {
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);
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;
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);
return true;
}
+ /**
+ * API to close Kafka producer connection
+ */
public void closeConnection() {
mProducer.close();
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();
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);
}
private IResponse handleGetRequest(Device srcDevice, IRequest request) {
// DISCOVER
- if (request.getUriPathSegments().size() == getUriPathSegments()
- .size()) {
+ if (request.getUriPathSegments().size() == getUriPathSegments().size()) {
return discoverTopic(request);
}
// 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");
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);
}
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);
}
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();
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;
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();
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);
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
}
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());
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();
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) {
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;
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));
}
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<>();
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) {
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<>();
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<>();
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;
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;
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;
}
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;
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;
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);
}).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 {
if (latchSubscriber.getCount() == 0) {
assertTrue(methodCheck(resp, ResponseStatus.CONTENT));
assertTrue(hashmapCheck(resp, "message"));
+
+ DeleteTopic(mMockDevice, topic);
}
return resp;
}
*/
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";
}
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 {
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;
}
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
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;
/**
*
* @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 {
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();
}
}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // 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);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // 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;
+ }
+
+}
*/
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;
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-
-}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-}
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));
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;
}
+
}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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);
- }
-}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-
-}
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.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));
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;
- }
}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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();
- }
-}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // 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);
+ }
+}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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();
- }
-}
*/
package org.iotivity.cloud.rdserver.resources.presence.device;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.iotivity.cloud.base.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
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();
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);
}
}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-
-}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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
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() {
switch (request.getMethod()) {
case GET:
- response = handleRegisterRequest(srcDevice, request);
+ response = handleGetRequest(srcDevice, request);
break;
default:
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);
}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // 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;
- }
-}
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;
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;
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
mResponse = resp;
return null;
}
- }).when(mockDevice).sendResponse(Mockito.anyObject());
+ }).when(mMockDevice).sendResponse(Mockito.anyObject());
}
@After
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
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;
}).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));
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;
}).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));
}
private boolean checkPayloadProperty(IResponse response,
- String propertyName) {
+ String propertyName, String propertyValue) {
HashMap<String, Object> payloadData = mCbor
.parsePayloadFromCbor(response.getPayload(), HashMap.class);
.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;
}
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
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());
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
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,
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
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<>();
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<>();
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>() {
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());
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
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
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
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
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) {
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());
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
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,
'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)
void foundDevice(shared_ptr<OC::OCResource> resource)
{
+ cout << "Found device called!" << endl;
+
vector<string> rt = resource->getResourceTypes();
cout << "Device found: " << resource->uri() << endl;
}
}
+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;
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;
{
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;
}
}
--- /dev/null
+#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;
+}
{
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;
}
}
{
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;
}
}
#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, };
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, };
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, };
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);
}
{
currLightResource = &gLightInstance[0];
}
- else if (ehRequest->resource == gLightInstance[1].handle)
- {
- currLightResource = &gLightInstance[1];
- }
if (OC_REST_PUT == ehRequest->method)
{
{
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;
}
void ProcessObserveRegister(OCEntityHandlerRequest *ehRequest)
{
cout << "Received observation registration request with observation Id "
- << ehRequest->obsInfo.obsId << endl;
+ << ehRequest->obsInfo.obsId << endl;
if (!observeThreadStarted)
{
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)
}
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)
// 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;
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
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;
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;
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;
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;
}
// 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) {
@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();
}
}