[IOT-1527] GroupManager according to the revised group resource model
authoryeonghun.nam <yeonghun.nam@samsung.com>
Tue, 25 Oct 2016 07:35:52 +0000 (16:35 +0900)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Tue, 17 Jan 2017 02:30:06 +0000 (02:30 +0000)
1. GroupManager to manage group management requests
  - GET oic/acl/group/<gid>
  - POST oic/acl/group/<gid>
  - POST oic/acl/group/<gid>?op=add
  - POST oic/acl/group/<gid>?op=delete
  - DELETE oic/acl/group/<gid>
2. User Authorization based group management

patch #28 #1: resources are not recorded to the group if devices regarding to the resources are already registered to the group
patch #28 #2: verification logic is added; when a device is registered to the parent group, recources of the device can be registered to subgroups

Change-Id: I5d90a0eea537e43fe06789db1897c90a766e01c5
Signed-off-by: yeonghun.nam <yeonghun.nam@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/13609
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
(cherry picked from commit a59953bbc30e99b58eec487d035ead886bb51185)
Reviewed-on: https://gerrit.iotivity.org/gerrit/14549
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16075

cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/account/AccountManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/group/GroupManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteManager.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/AccountResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/group/GroupResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/account/AclGroup.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceDirectory.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceFind.java

index 2eaaf89..296669a 100644 (file)
@@ -40,6 +40,7 @@ import org.iotivity.cloud.accountserver.db.TokenTable;
 import org.iotivity.cloud.accountserver.db.UserTable;
 import org.iotivity.cloud.accountserver.oauth.OAuthProviderFactory;
 import org.iotivity.cloud.accountserver.resources.acl.group.GroupBrokerManager;
+import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager;
 import org.iotivity.cloud.accountserver.resources.acl.id.AclResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
@@ -571,22 +572,7 @@ public class AccountManager {
         AccountDBManager.getInstance().deleteRecord(Constants.TOKEN_TABLE,
                 condition);
         // delete device ID from all groups in the DB
-        // GroupManager.getInstance().removeGroupDeviceinEveryGroup(uid, di);
-
-        // TODO remove device record from the ACL table
-        HashMap<String, Object> getAcl = new HashMap<>();
-
-        getAcl = AclResource.getInstance().getAclid(di);
-        if (getAcl == null || getAcl.containsKey(Constants.KEYFIELD_ACLID)) {
-            throw new BadRequestException("getAcl is invalid");
-        }
-
-        if (getAcl.get(Constants.KEYFIELD_ACLID) == null) {
-            throw new BadRequestException("getAcl is null");
-        }
-
-        AclResource.getInstance()
-                .deleteAcl((String) getAcl.get(Constants.KEYFIELD_ACLID));
+        GroupManager.getInstance().deleteDevicesFromAllGroup(di);
     }
 
 }
index dacbba4..f0e87d7 100644 (file)
  */
 package org.iotivity.cloud.accountserver.resources.acl.group;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
+
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.db.AccountDBManager;
+import org.iotivity.cloud.accountserver.db.GroupTable;
+import org.iotivity.cloud.accountserver.util.TypeCastingManager;
+import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
+import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
+import org.iotivity.cloud.util.Log;
 
 /**
  *
@@ -30,30 +41,800 @@ import java.util.HashMap;
  */
 
 public class GroupManager {
-    public void verifyAuthorization(String mid, String gid,
-            HashMap<String, Object> properties) {
+    private static GroupManager            mGrManager          = new GroupManager();
+    private TypeCastingManager<GroupTable> mTypeGroup          = new TypeCastingManager<GroupTable>();
+    private GroupPolicyManager             mGroupPolicyManager = new GroupPolicyManager();
+    private GroupAclManager                mGroupAclManager    = GroupAclManager
+            .getInstance();
+
+    /**
+     * Function to get GroupManager as a singleton
+     * 
+     * @return GroupManager as a singleton
+     */
+    public static GroupManager getInstance() {
+        return mGrManager;
+    }
+
+    /**
+     * API to replace group name to the group
+     * 
+     * @param gid
+     *            group id
+     * @param gname
+     *            group name
+     */
+    public void replaceGnameToGroup(String gid, String gname) {
+        replaceProperties(gid, Constants.KEYFIELD_GROUP_NAME, gname);
+    }
+
+    /**
+     * API to replace owner id to the group
+     * 
+     * @param gid
+     *            group id
+     * @param owner
+     *            owner id
+     */
+    public void replaceOwnerToGroup(String gid, String owner) {
+        replaceProperties(gid, Constants.KEYFIELD_GROUP_OWNER, owner);
+    }
+
+    /**
+     * API to add members to the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            user uuid list
+     */
+    public void addMembersToGroup(String gid, ArrayList<String> members) {
+        addProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, members);
+    }
+
+    /**
+     * API to add masters to the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            user uuid list
+     */
+    public void addMastersToGroup(String gid, ArrayList<String> masters) {
+        addProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, masters);
+        addProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, masters);
+    }
+
+    /**
+     * API to add resources to the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            resource list
+     */
+    public void addResourcesToGroup(String gid, ArrayList<Object> resources) {
+        ArrayList<Object> addedResources = new ArrayList<>();
+        // filter added resource list : if the device is already to the
+        // group, the resource is not added to the group
+        for (Object resource : resources) {
+            String deviceId = getDeviceIdFromResource(
+                    (HashMap<String, Object>) resource);
+            ArrayList<String> devices = getGroupTable(gid).getDevices();
+            if (devices == null) {
+                addedResources.add(resource);
+            } else {
+                if (!devices.contains(deviceId)) {
+                    addedResources.add(resource);
+                }
+            }
+        }
+        addProperties(gid, Constants.KEYFIELD_GROUP_RESOURCES, addedResources);
+    }
+
+    /**
+     * API to add devices to the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            device list
+     */
+    public void addDevicesToGroup(String gid, ArrayList<String> devices) {
+        // if resources regarding to the device is already registered, delete
+        // resources in advance
+        deleteResourcesOfDevices(gid, devices);
+        addProperties(gid, Constants.KEYFIELD_GROUP_DEVICES, devices);
+    }
+
+    /**
+     * API to delete member list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            member uuid list
+     */
+    public void deleteMembersFromGroup(String gid, ArrayList<String> members) {
+        // delete devices owned by deleted members
+        GroupTable groupTable = getGroupTable(gid);
+        ArrayList<String> devices = groupTable.getDevices();
+        ArrayList<String> deletedDevices = new ArrayList<String>();
+        for (String device : devices) {
+            if (members.contains(findDeviceOwner(device))) {
+                deletedDevices.add(device);
+            }
+        }
+        deleteDevicesFromGroup(gid, deletedDevices);
+
+        deleteProperties(gid, Constants.KEYFIELD_GROUP_MEMBERS, members);
+        deleteProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, members);
+    }
+
+    /**
+     * API to delete device and resources of each device from all groups
+     * 
+     * @param device
+     *            device id to be deleted from all groups
+     */
+    public void deleteDevicesFromAllGroup(String device) {
+        ArrayList<HashMap<String, Object>> groupList = readGroupList(
+                Constants.KEYFIELD_GROUP_MEMBERS, findDeviceOwner(device));
+        if (groupList == null) {
+            return;
+        }
+        ArrayList<String> devices = new ArrayList<>();
+        devices.add(device);
+        for (HashMap<String, Object> group : groupList) {
+            // deleteProperties((String) group.get(Constants.REQ_GROUP_ID),
+            // Constants.KEYFIELD_GROUP_DEVICES, devices);
+            deleteDevicesFromGroup((String) group.get(Constants.REQ_GROUP_ID),
+                    devices);
+        }
+    }
+
+    private ArrayList<HashMap<String, Object>> readGroupList(String key,
+            String value) {
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(key, value);
+        ArrayList<HashMap<String, Object>> records = AccountDBManager
+                .getInstance().selectRecord(Constants.GROUP_TABLE, condition);
+        return records;
+    }
+
+    /**
+     * API to delete master list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            master uuid list
+     */
+    public void deleteMastersFromGroup(String gid, ArrayList<String> masters) {
+        deleteProperties(gid, Constants.KEYFIELD_GROUP_MASTERS, masters);
+    }
+
+    /**
+     * API to delete resource list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            resource list
+     */
+    public void deleteResourcesFromGroup(String gid,
+            ArrayList<Object> deletedResources) {
+        deleteProperties(gid, Constants.KEYFIELD_GROUP_RESOURCES,
+                deletedResources);
+    }
+
+    /**
+     * API to delete device list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param values
+     *            device list
+     */
+    public void deleteDevicesFromGroup(String gid, ArrayList<String> devices) {
+        // delete resources owned by deleted members
+        deleteResourcesOfDevices(gid, devices);
+        deleteProperties(gid, Constants.KEYFIELD_GROUP_DEVICES, devices);
+    }
+
+    /**
+     * API to verify if the member user is eligible to add/delete/replace the
+     * requested property values
+     * 
+     * @param gid
+     *            group id
+     * @param mid
+     *            user uuid
+     * @param properties
+     *            property key/value map to check
+     * @param operation
+     *            user operation
+     */
+    public void verifyPostRequestAuthz(String gid, String mid,
+            HashMap<String, Object> properties, UserOperation operation) {
+        ArrayList<String> keySet = new ArrayList<String>();
+        keySet.addAll(properties.keySet());
+        mGroupPolicyManager.verifyOperationAuthorization(gid, mid, operation,
+                keySet);
+        switch (operation) {
+            case ADD:
+                verifyPostAddPolicy(gid, mid, properties);
+                break;
+            case DELETE:
+                verifyPostDeletePolicy(gid, mid, properties);
+                break;
+            case REPLACE:
+                verifyPostReplacePolicy(gid, mid, properties);
+                break;
+            default:
+                throw new PreconditionFailedException(
+                        operation + " is not supported");
+        }
+    }
+
+    /**
+     * API to get added property value list to the group among the entire value
+     * list to update
+     * 
+     * @param gid
+     *            group id
+     * @param property
+     *            property to update
+     * @param values
+     *            value list to update
+     * @return property value list to be added to the group
+     */
+    public <T> ArrayList<T> getAddPropertyValues(String gid, String property,
+            ArrayList<T> values) {
+        GroupTable groupTable = getGroupTable(gid);
+        ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
+        ArrayList<T> addedValues = new ArrayList<>();
+        for (int i = 0; i < values.size(); i++) {
+            if (!propertyValues.contains(values.get(i))) {
+                addedValues.add(values.get(i));
+            }
+        }
+        return addedValues;
+    }
+
+    /**
+     * API to get deleted property value list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param property
+     *            property to update
+     * @param values
+     *            value list to update
+     * @return property value list to be deleted from the group
+     */
+    public <T> ArrayList<T> getDeletePropertyValues(String gid, String property,
+            ArrayList<T> values) {
+        GroupTable groupTable = getGroupTable(gid);
+        ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
+        ArrayList<T> deletedValues = new ArrayList<>();
+        for (int i = 0; i < propertyValues.size(); i++) {
+            if (!values.contains(propertyValues.get(i))) {
+                deletedValues.add(propertyValues.get(i));
+            }
+        }
+        return deletedValues;
+    }
+
+    /**
+     * API to verify if the user is eligible to get the group information
+     * 
+     * @param gid
+     *            group id
+     * @param mid
+     *            user uuid
+     */
+    public void verifyGetRequestAuthz(String gid, String mid) {
+        verifyMemberExistanceInGroup(gid, mid);
+    }
+
+    /**
+     * API to verify if the user is eligible to delete the group
+     * 
+     * @param gid
+     *            group id
+     * @param mid
+     *            user uuid
+     */
+    public void verifyDeleteRequestAuthz(String gid, String mid) {
+        ArrayList<String> property = new ArrayList<>();
+        property.add(Constants.KEYFIELD_GROUP);
+        mGroupPolicyManager.verifyOperationAuthorization(gid, mid,
+                UserOperation.DELETE, property);
+    }
+
+    /**
+     * API to delete a group
+     * 
+     * @param gmid
+     *            An unique identifier of member who must be a group master.
+     *            Group master can be user or resource client.
+     * @param gid
+     *            An unique identifier of the group created under user entity
+     *            who requested for group creation.
+     */
+    public void deleteGroup(String gid) {
+        GroupTable groupTable = getGroupTable(gid);
+        String parentGid = groupTable.getParent();
+        // delete subgroup ID of the parent group
+        if (parentGid != null && !parentGid.isEmpty()) {
+            ArrayList<Object> gidList = new ArrayList<Object>();
+            gidList.add(gid);
+            deleteProperties(parentGid, Constants.KEYFIELD_GROUP_SUBGROUPS,
+                    gidList);
+        }
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(Constants.KEYFIELD_GID, gid);
+        // delete group from the table
+        AccountDBManager.getInstance().deleteRecord(Constants.GROUP_TABLE,
+                condition);
+        ArrayList<String> subgroups = (ArrayList<String>) groupTable
+                .getSubgroups();
+        // delete subgroups
+        if (subgroups != null) {
+            for (String subgroup : subgroups) {
+                deleteGroup(subgroup);
+                mGroupAclManager.removeAceByGroup(subgroup);
+            }
+        }
+    }
+
+    /**
+     * API to get the group information from the db
+     * 
+     * @param gid
+     *            group id
+     * @return group information payload
+     */
+    public HashMap<String, Object> getGroupInfo(String gid) {
+        GroupTable grouptable = getGroupTable(gid);
+        return mTypeGroup.convertObjectToMap(grouptable);
+    }
 
+    /**
+     * API to add property value list to the group
+     * 
+     * @param gid
+     *            group id
+     * @param property
+     *            property
+     * @param values
+     *            value list
+     */
+    private <T> void addProperties(String gid, String property,
+            ArrayList<T> values) {
+        Log.d("added property name: " + property + ", values : " + values
+                + " , to group : " + gid);
+        if (values == null || values.isEmpty()) {
+            return;
+        }
+        GroupTable groupTable = getGroupTable(gid);
+        ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
+        if (propertyValues == null) {
+            propertyValues = new ArrayList<T>();
+        }
+        values.removeAll(propertyValues);
+        propertyValues.addAll(values);
+        groupTable.setPropertyValue(property, propertyValues);
+        AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
+                mTypeGroup.convertObjectToMap(groupTable));
+        updateAclist(property, values, UserOperation.ADD, groupTable);
     }
 
-    public void getGroupInfo(String gid, String mid) {
+    /**
+     * API to delete property value list from the group
+     * 
+     * @param gid
+     *            group id
+     * @param property
+     *            property
+     * @param values
+     *            value list
+     */
+    private <T> void deleteProperties(String gid, String property,
+            ArrayList<T> values) {
+        Log.d("deleted property name: " + property + ", values : " + values
+                + " , from group : " + gid);
+        GroupTable groupTable = getGroupTable(gid);
+        if (groupTable == null || values == null || values.isEmpty()) {
+            return;
+        }
+        ArrayList<T> propertyValues = groupTable.getPropertyValue(property);
+        if (propertyValues != null) {
+            if (propertyValues.removeAll(values) == false) {
+                return;
+            }
+        }
+        groupTable.setPropertyValue(property, propertyValues);
+        AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
+                mTypeGroup.convertObjectToMap(groupTable));
+        ArrayList<String> subgroups = (ArrayList<String>) groupTable
+                .getSubgroups();
+        updateAclist(property, values, UserOperation.DELETE, groupTable);
+        if (subgroups != null) {
+            for (int i = 0; i < subgroups.size(); i++) {
+                deleteProperties(subgroups.get(i), property, values);
+            }
+        }
+    }
 
+    /**
+     * API to replace property value list to the group
+     * 
+     * @param gid
+     *            group id
+     * @param property
+     *            property
+     * @param value
+     *            value string
+     */
+    private void replaceProperties(String gid, String property, String value) {
+        Log.d("replaced property name: " + property + ", value : " + value
+                + ", to group : " + gid);
+        if (value == null || value.isEmpty()) {
+            return;
+        }
+        GroupTable groupTable = getGroupTable(gid);
+        groupTable.setPropertyValue(property, value);
+        AccountDBManager.getInstance().updateRecord(Constants.GROUP_TABLE,
+                mTypeGroup.convertObjectToMap(groupTable));
     }
 
-    public void addProperties(String gid, HashMap<String, Object> properties) {
+    /**
+     * API to get group table as an instance of GroupTable class
+     * 
+     * @param gid
+     *            group id
+     * @return group table
+     */
+    public GroupTable getGroupTable(String gid) {
+        GroupTable getGroupTable = new GroupTable();
+        ArrayList<HashMap<String, Object>> groupList = AccountDBManager
+                .getInstance().selectRecord(Constants.GROUP_TABLE,
+                        getCondition(Constants.REQ_GROUP_ID, gid));
+        if (groupList.isEmpty()) {
+            return null;
+        }
+        getGroupTable = mTypeGroup.convertMaptoObject(groupList.get(0),
+                getGroupTable);
+        return getGroupTable;
+
+    }
+
+    private void deleteResourcesOfDevices(String gid,
+            ArrayList<String> devices) {
+        GroupTable groupTable = getGroupTable(gid);
+        ArrayList<Object> resources = groupTable.getResources();
+        if (resources == null) {
+            return;
+        }
+        ArrayList<Object> deletedResources = new ArrayList<>();
+        for (Object object : resources) {
+            HashMap<String, Object> resource = (HashMap<String, Object>) object;
+            String resourceHref = (String) resource
+                    .get(Constants.KEYFIELD_ACE_RESOURCE_HREF);
+            String splitHref[] = resourceHref.split("/");
+
+            String deviceId = new String();
+            for (int i = 0; i < splitHref.length; i++) {
+                if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
+                        && (i + 1) < splitHref.length) {
+                    deviceId = splitHref[i + 1];
 
+                    break;
+                }
+            }
+            if (devices.contains(deviceId)) {
+                deletedResources.add(resource);
+            }
+        }
+        deleteResourcesFromGroup(gid, deletedResources);
     }
 
-    public void deleteProperties(String gid,
+    private void verifyPostReplacePolicy(String gid, String mid,
             HashMap<String, Object> properties) {
+        ArrayList<String> updatedKeySet = new ArrayList<String>();
+        updatedKeySet.addAll(properties.keySet());
+        mGroupPolicyManager.verifyOperationAuthorization(gid, mid,
+                UserOperation.REPLACE, updatedKeySet);
+        for (String key : properties.keySet()) {
+            if (!(properties.get(key) instanceof String)) {
+                throw new BadRequestException(
+                        "replace property value should be an instance of String");
+            }
+        }
+    }
 
+    private void verifyMemberExistanceInGroup(String gid, String mid) {
+        GroupTable groupTable = getGroupTable(gid);
+        if (!groupTable.getMembers().contains(mid)) {
+            throw new BadRequestException("uid is not a member of the group");
+        }
     }
 
-    public void getAddProperties(String gid,
+    private void verifyPostAddPolicy(String gid, String mid,
             HashMap<String, Object> properties) {
+        for (String key : properties.keySet()) {
+            if (!(properties.get(key) instanceof List)) {
+                throw new BadRequestException(
+                        "add property value should be an instance of Array");
+            }
+            switch (key) {
+                case Constants.KEYFIELD_GROUP_DEVICES:
+                    verifyDeviceOwner(mid,
+                            (ArrayList<String>) properties.get(key));
+                    verifyExistanceInParentGroup(gid, key,
+                            (ArrayList<Object>) properties.get(key));
+                    break;
+                case Constants.KEYFIELD_GROUP_RESOURCES:
+                    verifyResourceFormat(
+                            Arrays.asList(Constants.KEYFIELD_RESOURCE_RT,
+                                    Constants.KEYFIELD_RESOURCE_IF,
+                                    Constants.KEYFIELD_ACE_RESOURCE_HREF),
+                            (ArrayList<HashMap<String, Object>>) properties
+                                    .get(key));
+                    verifyResourceOwner(mid,
+                            (ArrayList<HashMap<String, Object>>) properties
+                                    .get(key));
+                    verifyExistanceInParentGroup(gid, key,
+                            filterResourceExistanceInParentGroupDeviceProperty(
+                                    gid,
+                                    (ArrayList<HashMap<String, Object>>) properties
+                                            .get(key)));
+                    break;
+                case Constants.KEYFIELD_GROUP_MEMBERS:
+                case Constants.KEYFIELD_GROUP_MASTERS:
+                    // TODO verify if members are registered to the Account user
+                    // DB
+                    verifyExistanceInParentGroup(gid,
+                            Constants.KEYFIELD_GROUP_MEMBERS,
+                            (ArrayList<Object>) properties.get(key));
+                    break;
+                default:
+                    throw new PreconditionFailedException(
+                            key + " is not supported");
+            }
+        }
+    }
 
+    private void verifyResourceFormat(List<String> propertyList,
+            ArrayList<HashMap<String, Object>> resources) {
+        for (HashMap<String, Object> resource : resources) {
+            for (String property : propertyList) {
+                if (!resource.containsKey(property))
+                    throw new PreconditionFailedException(
+                            property + " property is not included");
+                switch (property) {
+                    case Constants.KEYFIELD_RESOURCE_RT:
+                    case Constants.KEYFIELD_RESOURCE_IF:
+                        if (!(resource.get(property) instanceof List)) {
+                            throw new BadRequestException(property
+                                    + " property values should be an instance of array");
+                        }
+                        break;
+                    case Constants.KEYFIELD_ACE_RESOURCE_HREF:
+                        if (resource.get(property) == null) {
+                            throw new BadRequestException(
+                                    property + " property is null");
+                        }
+                        break;
+                }
+            }
+        }
     }
 
-    public void getDeleteProperties(String gid,
+    private void verifyPostDeletePolicy(String gid, String mid,
             HashMap<String, Object> properties) {
+        for (String key : properties.keySet()) {
+            if (!(properties.get(key) instanceof List)) {
+                throw new BadRequestException(
+                        "delete property value should be an instance of Array");
+            }
+            switch (key) {
+                case Constants.REQ_UUID_ID:
+                    break;
+                case Constants.KEYFIELD_GROUP_DEVICES:
+                case Constants.KEYFIELD_GROUP_RESOURCES:
+                case Constants.KEYFIELD_GROUP_MEMBERS:
+                    if ((boolean) ((ArrayList<String>) properties.get(key))
+                            .contains(getGroupTable(gid).getOwner())) {
+                        throw new BadRequestException("cannot remove owner Id");
+                    }
+                case Constants.KEYFIELD_GROUP_MASTERS:
+                    verifyExistanceInParentGroup(gid, key,
+                            (ArrayList<Object>) properties.get(key));
+                    break;
+                default:
+                    throw new BadRequestException(
+                            key + " property is not supported to ");
+            }
+        }
+    }
+
+    private ArrayList<HashMap<String, Object>> filterResourceExistanceInParentGroupDeviceProperty(
+            String gid, ArrayList<HashMap<String, Object>> resources) {
+        GroupTable parentGroupTable = getParentGroupTable(gid);
+        if (parentGroupTable == null) {
+            return resources;
+        }
+        ArrayList<String> devices = parentGroupTable.getDevices();
+        if (devices == null) {
+            return resources;
+        }
+        for (HashMap<String, Object> resource : resources) {
+            // if the device is registered to the parent group, filter the
+            // resource list
+            String deviceId = getDeviceIdFromResource(resource);
+            if (devices.contains(deviceId)) {
+                resources.remove(resource);
+            }
+        }
+        return resources;
+    }
+
+    private GroupTable getParentGroupTable(String gid) {
+        try {
+            return getGroupTable(getGroupTable(gid).getParent());
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private <T> void verifyExistanceInParentGroup(String gid, String property,
+            ArrayList<T> values) {
+        GroupTable parentGroupTable = getParentGroupTable(gid);
+        if (parentGroupTable == null) {
+            return;
+        }
+
+        ArrayList<Object> groupValues = parentGroupTable
+                .getPropertyValue(property);
+        if (groupValues == null) {
+            throw new BadRequestException(
+                    "verifying parent group existance failed");
+        }
+        if (!groupValues.containsAll(values)) {
+            throw new BadRequestException(
+                    "verifying parent group existance failed");
+
+        }
+    }
+
+    private void verifyDeviceOwner(String mid, ArrayList<String> values) {
+        for (String deviceId : values) {
+            if (!findDeviceOwner(deviceId).equals(mid)) {
+                throw new BadRequestException("verifying device owner failed");
+            }
+        }
+    }
+
+    private void verifyResourceOwner(String mid,
+            ArrayList<HashMap<String, Object>> resources) {
+        for (HashMap<String, Object> resource : resources) {
+            String deviceId = getDeviceIdFromResource(resource);
+            if (!findDeviceOwner(deviceId).equals(mid)) {
+                throw new BadRequestException(
+                        "verifying resource owner failed");
+            }
+        }
+    }
+
+    private String getDeviceIdFromResource(HashMap<String, Object> resource) {
+        String resourceHref = (String) resource
+                .get(Constants.KEYFIELD_ACE_RESOURCE_HREF);
+        String splitHref[] = resourceHref.split("/");
+        for (int i = 0; i < splitHref.length; i++) {
+            if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
+                    && (i + 1) < splitHref.length) {
+                return splitHref[i + 1];
+            }
+        }
+        return null;
+    }
+
+    private String findDeviceOwner(String deviceId) {
+        return mGroupAclManager.getDeviceOwnerId(deviceId);
+    }
+
+    private String findResourceOwner(String resourceHref) {
+        String splitHref[] = resourceHref.split("/");
+        for (int i = 0; i < splitHref.length; i++) {
+            if (splitHref[i].equals(Constants.REQ_DEVICE_ID)
+                    && (i + 1) < splitHref.length) {
+                return findDeviceOwner(splitHref[i + 1]);
+            }
+        }
+        return null;
+    }
+
+    private HashMap<String, Object> getCondition(String property,
+            String value) {
+        HashMap<String, Object> condition = new HashMap<>();
+        condition.put(property, value);
+        return condition;
+    }
+
+    private <T> void updateAclist(String property, ArrayList<T> values,
+            UserOperation operation, GroupTable groupTable) {
+        switch (operation) {
+            case ADD:
+                addAclist(property, values, groupTable);
+                break;
+            case DELETE:
+                removeAclist(property, values, groupTable);
+                break;
+            default:
+                throw new BadRequestException(
+                        operation + " is not supported operation in the group");
+        }
+    }
+
+    private <T> void addAclist(String property, ArrayList<T> values,
+            GroupTable groupTable) {
+        String gid = groupTable.getGid();
+        int permission = 0;
+        for (Object gaclObject : groupTable.getGacl()) {
+            HashMap<String, Object> gacl = (HashMap<String, Object>) gaclObject;
+            permission = (int) gacl.get(Constants.KEYFIELD_ACE_PERMISSION);
+        }
+        switch (property) {
+            case Constants.KEYFIELD_GROUP_MEMBERS:
+                mGroupAclManager.addAceByMembers(gid, permission,
+                        (ArrayList<String>) values);
+                break;
+            case Constants.KEYFIELD_GROUP_DEVICES:
+                mGroupAclManager.addAceByDevices(gid, permission,
+                        (ArrayList<String>) values);
+                break;
+            case Constants.KEYFIELD_GROUP_RESOURCES:
+                mGroupAclManager.addAceByResources(gid, permission,
+                        (ArrayList<HashMap<String, Object>>) values);
+                break;
+            case Constants.KEYFIELD_GROUP_OWNER:
+            case Constants.KEYFIELD_GROUP_MASTERS:
+            case Constants.KEYFIELD_GROUP_SUBGROUPS:
+            case Constants.KEYFIELD_GROUP_GACL:
+                return;
+            default:
+                throw new BadRequestException(
+                        property + " is not supported property in the group");
+        }
+    }
+
+    private <T> void removeAclist(String property, ArrayList<T> values,
+            GroupTable groupTable) {
+        String gid = groupTable.getGid();
+        switch (property) {
+            case Constants.KEYFIELD_GROUP_MEMBERS:
+                mGroupAclManager.removeAceByMembers((ArrayList<String>) values,
+                        gid);
+                break;
+            case Constants.KEYFIELD_GROUP_DEVICES:
+                mGroupAclManager.removeAceByDevices((ArrayList<String>) values,
+                        gid);
+                break;
+            case Constants.KEYFIELD_GROUP_RESOURCES:
+                mGroupAclManager.removeAceByResources(
+                        (ArrayList<HashMap<String, Object>>) values, gid);
+                break;
+            case Constants.KEYFIELD_GROUP_OWNER:
+            case Constants.KEYFIELD_GROUP_MASTERS:
+            case Constants.KEYFIELD_GROUP_SUBGROUPS:
+            case Constants.KEYFIELD_GROUP_GACL:
+                return;
+            default:
+                throw new BadRequestException(
+                        property + " is not supported property in the group");
+        }
     }
-}
+}
\ No newline at end of file
index 27bd56c..529eef3 100644 (file)
@@ -23,12 +23,12 @@ package org.iotivity.cloud.accountserver.resources.acl.invite;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.InviteTable;
+import org.iotivity.cloud.accountserver.resources.acl.group.GroupBrokerManager;
 import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.base.device.Device;
@@ -123,10 +123,12 @@ public class InviteManager {
         /* add user into group */
         if (accepted) {
 
-            HashSet<String> midlist = new HashSet<String>();
+            ArrayList<String> midlist = new ArrayList<>();
             midlist.add(mid);
 
-            GroupManager.getInstance().addGroupMember(gid, midlist);
+            GroupManager.getInstance().addMembersToGroup(gid, midlist);
+            GroupBrokerManager.getInstance().notifyToObservers(
+                    GroupManager.getInstance().getGroupTable(gid).getMembers());
         }
 
         notifyToSubscriber(mid);
index f69d51c..9f62d55 100644 (file)
@@ -28,8 +28,10 @@ import static org.mockito.Mockito.mock;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 import org.iotivity.cloud.accountserver.Constants;
@@ -37,7 +39,10 @@ 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.resources.acl.group.GroupBrokerManager;
+import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager;
 import org.iotivity.cloud.accountserver.resources.acl.group.GroupResource;
+import org.iotivity.cloud.accountserver.resources.acl.id.AclResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.exception.ServerException;
@@ -60,9 +65,9 @@ import org.mockito.stubbing.Answer;
 public class AccountResourceTest {
     private static final String            REGISTER_URI              = Constants.ACCOUNT_FULL_URI;
     private static final String            GROUP_URI                 = Constants.GROUP_FULL_URI;
-    private static final String            DEVICE_ID                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
+    private static final String            DEVICE_ID                 = "DEVICE";
     private String                         mAuthProvider             = "Github";
-    private String                         mAuthCode                 = "b4878d614bbc5f8db463";
+    private String                         mAuthCode                 = "3af038b49edc4ebdc45c";
     private CoapDevice                     mMockDevice               = mock(
             CoapDevice.class);
     private Cbor<HashMap<String, Object>>  mCbor                     = new Cbor<>();
@@ -185,23 +190,6 @@ public class AccountResourceTest {
     }
 
     @Test
-    public void testDeleteDeviceDefaultGroupOnDefaultRequestReceived()
-            throws Exception {
-        getTestMethodName();
-        // register the token table and user table to the DB
-        String uuid = "u0001";
-        registerTokenUserInfo(uuid, DEVICE_ID);
-        createGroup(uuid, "Private");
-        // register three devices to the group
-        shareDevice(DEVICE_ID, uuid);
-        shareDevice(DEVICE_ID + "2", uuid);
-        shareDevice(DEVICE_ID + "3", uuid);
-        // delete one device
-        deleteDevice(DEVICE_ID, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
-    }
-
-    @Test
     public void testDeleteDeviceInEveryGroupOnDefaultRequestReceived()
             throws Exception {
         getTestMethodName();
@@ -211,23 +199,39 @@ public class AccountResourceTest {
         registerTokenUserInfo(uuid, DEVICE_ID);
         registerTokenInfo(uuid, DEVICE_ID + "2");
         registerTokenInfo(uuid, DEVICE_ID + "3");
-        // register token table for the resource client
         registerTokenInfo(uuid, DEVICE_ID + "4");
-        createGroup(uuid, "Private");
+        registerTokenInfo(uuid, DEVICE_ID + "5");
+        AclResource.getInstance().createAcl(uuid, DEVICE_ID);
+        AclResource.getInstance().createAcl(uuid, DEVICE_ID + "2");
+        AclResource.getInstance().createAcl(uuid, DEVICE_ID + "3");
+        AclResource.getInstance().createAcl(uuid, DEVICE_ID + "4");
+        AclResource.getInstance().createAcl(uuid, DEVICE_ID + "5");
+        GroupBrokerManager.getInstance().createGroup(uuid, uuid, null, null);
         // register three devices to the private group
-        shareDevice(DEVICE_ID, uuid);
-        shareDevice(DEVICE_ID + "2", uuid);
-        shareDevice(DEVICE_ID + "3", uuid);
-        // register resource servers to the public group
-        createGroup(uuid, "Public");
-        shareDevice(DEVICE_ID, mGroupId);
-        shareDevice(DEVICE_ID + "2", mGroupId);
-        shareDevice(DEVICE_ID + "3", mGroupId);
-        // register resource servers to the public group
-        createGroup(uuid, "Public");
-        shareDevice(DEVICE_ID, mGroupId);
-        shareDevice(DEVICE_ID + "2", mGroupId);
-        shareDevice(DEVICE_ID + "3", mGroupId);
+        GroupManager.getInstance().addDevicesToGroup(uuid,
+                new ArrayList<String>(Arrays.asList(DEVICE_ID, DEVICE_ID + "2",
+                        DEVICE_ID + "3")));
+        GroupBrokerManager.getInstance().createGroup(uuid, "group1", null,
+                null);
+        GroupManager.getInstance().addDevicesToGroup("group1",
+                new ArrayList<String>(Arrays.asList(DEVICE_ID, DEVICE_ID + "2",
+                        DEVICE_ID + "3")));
+        GroupBrokerManager.getInstance().createGroup(uuid, "group2", null,
+                null);
+        GroupManager.getInstance().addDevicesToGroup("group2",
+                new ArrayList<String>(Arrays.asList(DEVICE_ID, DEVICE_ID + "2",
+                        DEVICE_ID + "3")));
+        ArrayList<Object> resources = new ArrayList<>();
+        // add resource 1
+        resources.add(makeResources("/di/" + DEVICE_ID + "4" + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        resources.add(makeResources("/di/" + DEVICE_ID + "4" + "/a/switch/1",
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        resources.add(makeResources("/di/" + DEVICE_ID + "5" + "/a/fan/1",
+                Arrays.asList("core.fan"), Arrays.asList("oic.if.baseline")));
+        GroupManager.getInstance().addResourcesToGroup("group2", resources);
+
         // device delete for three resource servers
         deleteDevice(DEVICE_ID, uuid);
         assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
@@ -241,23 +245,6 @@ public class AccountResourceTest {
     }
 
     @Test
-    public void testDeleteClientOnDefaultRequestReceived() throws Exception {
-        getTestMethodName();
-        // register the token table and user table to the DB
-        String uuid = "u0001Client";
-        HashMap<String, Object> tokenInfo = mTokenTableCastingManager
-                .convertObjectToMap(makeTokenTable(uuid, DEVICE_ID));
-        HashMap<String, Object> userInfo = mUserTableCastingManager
-                .convertObjectToMap(makeUserTable(uuid));
-        AccountDBManager.getInstance()
-                .insertAndReplaceRecord(Constants.TOKEN_TABLE, tokenInfo);
-        AccountDBManager.getInstance().insertRecord(Constants.USER_TABLE,
-                userInfo);
-        deleteDevice(DEVICE_ID, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
-    }
-
-    @Test
     public void testGetUserInfoUsingUuidOnDefaultRequestReceived()
             throws Exception {
         getTestMethodName();
@@ -313,15 +300,8 @@ public class AccountResourceTest {
         return request;
     }
 
-    private void createGroup(String uuid, String gtype) throws Exception {
-        System.out.println("-----Create Group");
-        IRequest request = null;
-        request = createDefaultGroupRequest(uuid, gtype);
-        mGroupResource.onDefaultRequestReceived(mMockDevice, request);
-    }
-
     private void deleteDevice(String di, String uid) throws Exception {
-        System.out.println("-----Delete Device");
+        System.out.println("-----Delete Device " + di);
         IRequest request = null;
         request = deleteDeviceRequest(di, uid);
         mAccountResource.onDefaultRequestReceived(mMockDevice, request);
@@ -343,40 +323,19 @@ public class AccountResourceTest {
         mAccountResource.onDefaultRequestReceived(mMockDevice, request);
     }
 
-    private void shareDevice(String deviceId, String gid) throws Exception {
-        System.out.println("-----Share Device");
-        IRequest request = null;
-        request = createShareDeviceRequest(deviceId, gid);
-        mGroupResource.onDefaultRequestReceived(mMockDevice, request);
-    }
-
     private IRequest deleteDeviceRequest(String deviceId, String uid) {
         IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
                 REGISTER_URI, "di=" + deviceId + ";uid=" + uid);
         return request;
     }
 
-    private IRequest createDefaultGroupRequest(String uuid, String gtype) {
-        IRequest request = null;
-        HashMap<String, String> payloadData = new HashMap<String, String>();
-        payloadData.put("gmid", uuid);
-        payloadData.put("gtype", gtype);
-        request = MessageBuilder.createRequest(RequestMethod.POST, GROUP_URI,
-                null, ContentFormat.APPLICATION_CBOR,
-                mCbor.encodingPayloadToCbor(payloadData));
-        return request;
-    }
-
-    private IRequest createShareDeviceRequest(String deviceId, String gid) {
-        IRequest request = null;
-        HashMap<String, Object> payloadData = new HashMap<String, Object>();
-        ArrayList<String> diList = new ArrayList<>();
-        diList.add(deviceId);
-        payloadData.put("dilist", diList);
-        request = MessageBuilder.createRequest(RequestMethod.POST,
-                GROUP_URI + "/" + gid, null, ContentFormat.APPLICATION_CBOR,
-                mCbor.encodingPayloadToCbor(payloadData));
-        return request;
+    private HashMap<String, Object> makeResources(String href, List<String> rt,
+            List<String> itf) {
+        HashMap<String, Object> resource = new HashMap<String, Object>();
+        resource.put(Constants.KEYFIELD_ACE_RESOURCE_HREF, href);
+        resource.put(Constants.RS_INTERFACE, itf);
+        resource.put(Constants.KEYFIELD_RESOURCE_RT, rt);
+        return resource;
     }
 
     private IRequest signUpRequest(String deviceId, String authProvider,
index 36843d0..92766a1 100644 (file)
@@ -24,10 +24,11 @@ package org.iotivity.cloud.accountserver.resources.acl.group;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 import org.iotivity.cloud.accountserver.Constants;
@@ -38,10 +39,8 @@ 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.CoapRequest;
 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
-import org.iotivity.cloud.base.protocols.enums.Observe;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.util.Cbor;
@@ -54,26 +53,26 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 public class GroupResourceTest {
-    private static final String           GROUP_URI         = Constants.GROUP_FULL_URI;
-    private String                        mGid1             = "g1";
-    private String                        mGid2             = "g2";
-    private String                        mDi1              = "d1";
-    private String                        mDi2              = "d2";
-    private String                        mDi3              = "d3";
-    private String                        mUid1             = "u1";
-    private String                        mUid2             = "u2";
-    private String                        mUid3             = "u3";
-    private String                        mUid4             = "u4";
-    private String                        mGroupId          = null;
-    final CountDownLatch                  mLatch            = new CountDownLatch(
+    private static final String           GROUP_URI      = Constants.GROUP_FULL_URI;
+    private String                        mGid1          = "g1";
+    private String                        mGid2          = "g2";
+    private String                        mDi1           = "d1";
+    private String                        mDi2           = "d2";
+    private String                        mDi3           = "d3";
+    private String                        mDi4           = "d4";
+    private String                        mUid1          = "u1";
+    private String                        mUid2          = "u2";
+    private String                        mUid3          = "u3";
+    private String                        mUid4          = "u4";
+    private String                        mGroupId       = null;
+    final CountDownLatch                  mLatch         = new CountDownLatch(
             1);
-    private CoapDevice                    mMockDevice       = Mockito
+    private CoapDevice                    mMockDevice    = Mockito
             .mock(CoapDevice.class);
-    private Cbor<HashMap<String, Object>> mCbor             = new Cbor<>();
-    private IResponse                     mResponse         = null;
-    private IResponse                     mResponseObserver = null;
-    private GroupResource                 mGroupResource    = new GroupResource();
-    private HashMap<String, Object>       mPayload          = new HashMap<>();
+    private Cbor<HashMap<String, Object>> mCbor          = new Cbor<>();
+    private IResponse                     mResponse      = null;
+    private GroupResource                 mGroupResource = new GroupResource();
+    private HashMap<String, Object>       mPayload       = new HashMap<>();
 
     @Before
     public void setUp() throws Exception {
@@ -103,19 +102,26 @@ public class GroupResourceTest {
                 return null;
             }
         }).when(mMockDevice).sendResponse(Mockito.anyObject());
+
+        makeExampleGroup();
     }
 
     @After
     public void resetAccountDatabase() throws Exception {
         MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
+        mongoDB.deleteTable(Constants.USER_TABLE);
         mongoDB.createTable(Constants.USER_TABLE);
+        mongoDB.deleteTable(Constants.TOKEN_TABLE);
         mongoDB.createTable(Constants.TOKEN_TABLE);
+        mongoDB.deleteTable(Constants.GROUP_TABLE);
         mongoDB.createTable(Constants.GROUP_TABLE);
+        mongoDB.deleteTable(Constants.ACL_TABLE);
         mongoDB.createTable(Constants.ACL_TABLE);
+        mongoDB.deleteTable(Constants.ACE_TABLE);
         mongoDB.createTable(Constants.ACE_TABLE);
     }
 
-    // @Test
+    @Test
     public void testCreateGroup() throws Exception {
         getTestMethodName();
         createGroup(mMockDevice, mUid1, "myhome", null);
@@ -124,43 +130,31 @@ public class GroupResourceTest {
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testCreateSubGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        createGroup(mMockDevice, mUid1, "myroom", mGid1);
+        createGroup(mMockDevice, mUid1, "myroom2", mGid1);
         createGroup(mMockDevice, mUid1, "mybalcony", mGid1);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(hashmapCheck(mResponse, "gid"));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
     public void testCreateSubGroupNotExistParentGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, "g1", "myhome",
-                null);
         createGroup(mMockDevice, mUid1, "myhome", "NOT");
     }
 
-    // @Test
+    @Test
     public void testAddDeviceToGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> devices = new ArrayList<>();
-        devices.add("d1");
-        devices.add("d2");
-        devices.add("d3");
-        properties.put(Constants.KEYFIELD_DEVICES, devices);
+        devices.add(mDi1);
+        devices.add(mDi2);
+        devices.add(mDi3);
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
         addProperties(mMockDevice, mGid1, mUid1, properties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
@@ -169,14 +163,6 @@ public class GroupResourceTest {
     @Test(expected = ServerException.BadRequestException.class)
     public void testAddNotSupportedPropertyToGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> devices = new ArrayList<>();
         devices.add("d1");
@@ -186,253 +172,189 @@ public class GroupResourceTest {
         addProperties(mMockDevice, mGid1, mUid1, properties);
     }
 
-    // @Test
+    @Test
     public void testAddResourceToGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
         // add resource 1
-        resources.add(makeResources("/di/" + mDi1 + "/a/light/0", "core.light",
-                "oic.if.baseline"));
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
         resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        properties.put(Constants.KEYFIELD_RESOURCES, resources);
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
         addProperties(mMockDevice, mGid1, mUid1, properties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testAddDeviceToSubGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> devices = new ArrayList<>();
         devices.add(mDi1);
         devices.add(mDi2);
-        properties.put(Constants.KEYFIELD_DEVICES, devices);
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
         addProperties(mMockDevice, mGid1, mUid1, properties);
         addProperties(mMockDevice, mGid2, mUid1, properties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
     public void testAddDeviceToSubGroupNotByDeviceOwner() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid2, mDi1);
-        AclResource.getInstance().createAcl(mUid2, mDi2);
-        AclResource.getInstance().createAcl(mUid2, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> devices = new ArrayList<>();
         devices.add(mDi1);
         devices.add(mDi2);
         devices.add(mDi3);
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_DEVICES, devices);
-        properties.put(Constants.KEYFIELD_DEVICES, devices);
-        addProperties(mMockDevice, mGid2, mUid1, properties);
+        GroupManager.getInstance().addDevicesToGroup(mGid1, devices);
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
+        addProperties(mMockDevice, mGid2, mUid2, properties);
     }
 
-    // @Test
+    @Test
     public void testAddMembersToSubGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         addProperties(mMockDevice, mGid2, mUid1, properties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testAddMastersToSubGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
-
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         HashMap<String, Object> propertiesSubgroup = new HashMap<>();
         ArrayList<String> masters = new ArrayList<>();
         masters.add(mUid2);
         masters.add(mUid3);
-        propertiesSubgroup.put(Constants.KEYFIELD_MASTERS, masters);
+        propertiesSubgroup.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
         addProperties(mMockDevice, mGid2, mUid1, propertiesSubgroup);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testAddMastersToSubGroupByMaster() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MASTERS, members);
-        GroupManager.getInstance().addProperties(mGid2,
-                Constants.KEYFIELD_MASTERS, members);
+        GroupManager.getInstance().addMastersToGroup(mGid1, members);
+        GroupManager.getInstance().addMastersToGroup(mGid2, members);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         HashMap<String, Object> propertiesSubgroup = new HashMap<>();
         ArrayList<String> masters = new ArrayList<>();
         masters.add(mUid3);
-        propertiesSubgroup.put(Constants.KEYFIELD_MASTERS, masters);
+        propertiesSubgroup.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
         addProperties(mMockDevice, mGid2, mUid2, propertiesSubgroup);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testAddResourceToSubgroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
         // add resource 1
-        resources.add(makeResources("/di/" + mDi1 + "/a/light/0", "core.light",
-                "oic.if.baseline"));
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
         resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        properties.put(Constants.KEYFIELD_RESOURCES, resources);
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
         addProperties(mMockDevice, mGid1, mUid1, properties);
 
         HashMap<String, Object> subgroupProperties = new HashMap<>();
         ArrayList<HashMap<String, Object>> subgroupResources = new ArrayList<>();
         subgroupResources.add(makeResources("/di/" + mDi1 + "/a/light/0",
-                "core.light", "oic.if.baseline"));
-        subgroupProperties.put(Constants.KEYFIELD_RESOURCES, subgroupResources);
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        subgroupProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                subgroupResources);
         addProperties(mMockDevice, mGid2, mUid1, subgroupProperties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
     public void testAddResourceDiffRtToSubgroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
         // add resource 1
-        resources.add(makeResources("/di/" + mDi1 + "/a/light/0", "core.light",
-                "oic.if.baseline"));
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
         resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        properties.put(Constants.KEYFIELD_RESOURCES, resources);
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
         addProperties(mMockDevice, mGid1, mUid1, properties);
 
         HashMap<String, Object> subgroupProperties = new HashMap<>();
         ArrayList<HashMap<String, Object>> subgroupResources = new ArrayList<>();
         subgroupResources.add(makeResources("/di/" + mDi1 + "/a/light/0",
-                "core.none", "oic.if.baseline"));
-        subgroupProperties.put(Constants.KEYFIELD_RESOURCES, subgroupResources);
+                Arrays.asList("core.none"), Arrays.asList("oic.if.baseline")));
+        subgroupProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                subgroupResources);
         addProperties(mMockDevice, mGid2, mUid1, subgroupProperties);
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
+    public void testAddResourceGroupInvalidFormat() throws Exception {
+        getTestMethodName();
+        HashMap<String, Object> properties = new HashMap<>();
+        ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
+        // add resource 1
+        resources.add(makeResources("/di/" + mDi3 + "/a/light/0", "core.light",
+                "oic.if.baseline"));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
+        addProperties(mMockDevice, mGid1, mUid1, properties);
+    }
+
+    @Test(expected = ServerException.BadRequestException.class)
     public void testAddMembersToSubGroupUnauthorized() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         addProperties(mMockDevice, mGid2, mUid3, properties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
     public void testAddNotExistingDeviceToSubGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> devices = new ArrayList<>();
         devices.add(mDi1);
         devices.add(mDi2);
-        properties.put(Constants.KEYFIELD_DEVICES, devices);
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
         addProperties(mMockDevice, mGid1, mUid1, properties);
         devices.add(mDi3);
         addProperties(mMockDevice, mGid2, mUid1, properties);
@@ -440,172 +362,301 @@ public class GroupResourceTest {
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testPromoteMemberToMaster() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
 
         HashMap<String, Object> propertiesMaster = new HashMap<>();
         ArrayList<String> masters = new ArrayList<>();
         masters.add(mUid2);
         masters.add(mUid3);
-        propertiesMaster.put(Constants.KEYFIELD_MASTERS, masters);
+        propertiesMaster.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
         addProperties(mMockDevice, mGid1, mUid1, propertiesMaster);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test
+    @Test
     public void testGetGroup() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         getGroupInfo(mMockDevice, mGid1, mUid1);
         assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
-    // @Test(expected = ServerException.BadRequestException.class)
+    @Test(expected = ServerException.BadRequestException.class)
     public void testGetGroupByNonExistingUser() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
         members.add(mUid3);
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
         // add members to the parent group
-        GroupManager.getInstance().addProperties(mGid1,
-                Constants.KEYFIELD_MEMBERS, members);
+        GroupManager.getInstance().addMembersToGroup(mGid1, members);
         getGroupInfo(mMockDevice, mGid1, "NON_EXIST_USER");
     }
 
-    // @Test
+    @Test
     public void testAddMultipleProperties() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
-
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
         // add resource 1
-        resources.add(makeResources("/di/" + mDi1 + "/a/light/0", "core.light",
-                "oic.if.baseline"));
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
         resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        properties.put(Constants.KEYFIELD_RESOURCES, resources);
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
 
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
 
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
 
         ArrayList<String> masters = new ArrayList<>();
         masters.add(mUid3);
-        properties.put(Constants.KEYFIELD_MASTERS, masters);
+        properties.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
 
         addProperties(mMockDevice, mGid1, mUid1, properties);
 
         HashMap<String, Object> subgroupProperties = new HashMap<>();
         ArrayList<HashMap<String, Object>> subgroupResources = new ArrayList<>();
         subgroupResources.add(makeResources("/di/" + mDi1 + "/a/light/0",
-                "core.light", "oic.if.baseline"));
-        subgroupProperties.put(Constants.KEYFIELD_RESOURCES, subgroupResources);
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        subgroupProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                subgroupResources);
         addProperties(mMockDevice, mGid2, mUid1, subgroupProperties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
     @Test
-    public void testUpdateResources() throws Exception {
+    public void testDeleteMultipleProperties() throws Exception {
         getTestMethodName();
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
-                null);
-        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
-                mGid1);
-        AclResource.getInstance().createAcl(mUid1, mDi1);
-        AclResource.getInstance().createAcl(mUid1, mDi2);
-        AclResource.getInstance().createAcl(mUid1, mDi3);
 
+        HashMap<String, Object> properties = setExampleGroup();
+
+        properties.remove(Constants.KEYFIELD_GROUP_MEMBERS);
+
+        deleteProperties(mMockDevice, mGid1, mUid1, properties);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    @Test
+    public void testDeleteUnregisteredDevices() throws Exception {
+        getTestMethodName();
+
+        setExampleGroup();
+
+        HashMap<String, Object> properties = new HashMap<>();
+        ArrayList<String> devices = new ArrayList<String>();
+        devices.addAll(Arrays.asList(mDi3, mDi2));
+
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
+
+        deleteProperties(mMockDevice, mGid1, mUid1, properties);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    @Test
+    public void testAddResources() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        HashMap<String, Object> properties = new HashMap<>();
+        ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
+        resources.add(makeResources("/di/" + mDi3 + "/a/fan",
+                Arrays.asList("core.fan"), Arrays.asList("oic.if.baseline")));
+        resources.add(makeResources("/di/" + mDi4 + "/a/fan",
+                Arrays.asList("core.fan"), Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
+        addProperties(mMockDevice, mGid1, mUid1, properties);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    @Test
+    public void testDeleteGroup() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        deleteGroup(mMockDevice, mGid1, mUid1);
+        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    @Test(expected = ServerException.BadRequestException.class)
+    public void testDeleteGroupByMaster() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        deleteGroup(mMockDevice, mGid1, mUid2);
+    }
+
+    @Test(expected = ServerException.BadRequestException.class)
+    public void testDeleteGroupByUnregisteredUser() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        deleteGroup(mMockDevice, mGid1, "UNREGISTERED_USER");
+    }
+
+    @Test
+    public void testAddDeviceAndDeleteResources() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        HashMap<String, Object> properties = new HashMap<>();
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, Arrays.asList(mDi1));
+        addProperties(mMockDevice, mGid1, mUid1, properties);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    @Test
+    public void testUpdateResources() throws Exception {
+        getTestMethodName();
         HashMap<String, Object> properties = new HashMap<>();
         ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
         // add resource 1
-        resources.add(makeResources("/di/" + mDi1 + "/a/light/0", "core.light",
-                "oic.if.baseline"));
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
         resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        properties.put(Constants.KEYFIELD_RESOURCES, resources);
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
 
         ArrayList<String> members = new ArrayList<>();
         members.add(mUid2);
 
-        properties.put(Constants.KEYFIELD_MEMBERS, members);
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
 
         ArrayList<String> masters = new ArrayList<>();
         masters.add(mUid3);
-        properties.put(Constants.KEYFIELD_MASTERS, masters);
+        properties.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
 
         addProperties(mMockDevice, mGid1, mUid1, properties);
 
         HashMap<String, Object> subgroupProperties = new HashMap<>();
         ArrayList<HashMap<String, Object>> subgroupResources = new ArrayList<>();
         subgroupResources.add(makeResources("/di/" + mDi1 + "/a/light/0",
-                "core.light", "oic.if.baseline"));
-        subgroupProperties.put(Constants.KEYFIELD_RESOURCES, subgroupResources);
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        subgroupProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                subgroupResources);
         addProperties(mMockDevice, mGid2, mUid1, subgroupProperties);
 
         HashMap<String, Object> updatedProperties = new HashMap<>();
         ArrayList<HashMap<String, Object>> updatedResources = new ArrayList<>();
         updatedResources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
-                "core.switch", "oic.if.baseline"));
-        updatedProperties.put(Constants.KEYFIELD_GNAME, "mypark");
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        updatedProperties.put(Constants.KEYFIELD_GROUP_NAME, "mypark");
         ArrayList<String> updatedMasters = new ArrayList<>();
         updatedMasters.add(mUid4);
-        updatedProperties.put(Constants.KEYFIELD_MASTERS, updatedMasters);
-        updatedProperties.put(Constants.KEYFIELD_RESOURCES, updatedResources);
+        updatedProperties.put(Constants.KEYFIELD_GROUP_MASTERS, updatedMasters);
+        updatedProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                updatedResources);
         updateProperties(mMockDevice, mGid1, mUid1, updatedProperties);
         assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
         assertTrue(mLatch.await(2L, SECONDS));
     }
 
+    @Test
+    public void testUpdateProperties() throws Exception {
+        getTestMethodName();
+        setExampleGroup();
+        HashMap<String, Object> properties = new HashMap<>();
+        ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
+        // add resource 1
+        resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
+
+        ArrayList<String> members = new ArrayList<>();
+        members.add(mUid1);
+        members.add(mUid2);
+
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
+
+        ArrayList<String> masters = new ArrayList<>();
+        masters.add(mUid3);
+        properties.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
+
+        updateProperties(mMockDevice, mGid1, mUid1, properties);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        assertTrue(mLatch.await(2L, SECONDS));
+    }
+
+    private HashMap<String, Object> setExampleGroup() throws Exception {
+        HashMap<String, Object> properties = new HashMap<>();
+        ArrayList<HashMap<String, Object>> resources = new ArrayList<>();
+        // add resource 1
+        resources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        resources.add(makeResources("/di/" + mDi1 + "/a/switch/1",
+                Arrays.asList("core.switch"),
+                Arrays.asList("oic.if.baseline")));
+        resources.add(makeResources("/di/" + mDi1 + "/a/fan/1",
+                Arrays.asList("core.fan"), Arrays.asList("oic.if.baseline")));
+        properties.put(Constants.KEYFIELD_GROUP_RESOURCES, resources);
+
+        ArrayList<String> members = new ArrayList<>();
+        members.addAll(Arrays.asList(mUid2, mUid3, mUid4));
+        properties.put(Constants.KEYFIELD_GROUP_MEMBERS, members);
+
+        ArrayList<String> masters = new ArrayList<>();
+        masters.add(mUid3);
+        properties.put(Constants.KEYFIELD_GROUP_MASTERS, masters);
+
+        ArrayList<String> devices = new ArrayList<>();
+        devices.add(mDi3);
+        properties.put(Constants.KEYFIELD_GROUP_DEVICES, devices);
+
+        addProperties(mMockDevice, mGid1, mUid1, properties);
+
+        HashMap<String, Object> subgroupProperties = new HashMap<>();
+        ArrayList<HashMap<String, Object>> subgroupResources = new ArrayList<>();
+        subgroupResources.add(makeResources("/di/" + mDi1 + "/a/light/0",
+                Arrays.asList("core.light"), Arrays.asList("oic.if.baseline")));
+        subgroupProperties.put(Constants.KEYFIELD_GROUP_RESOURCES,
+                subgroupResources);
+        addProperties(mMockDevice, mGid2, mUid1, subgroupProperties);
+        return properties;
+    }
+
+    private void deleteGroup(CoapDevice device, String gid, String uid)
+            throws Exception {
+        System.out.println("-----Get group, gid : " + gid);
+        IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
+                GROUP_URI + "/" + gid, Constants.REQ_UUID_ID + "=" + uid);
+        mGroupResource.onDefaultRequestReceived(device, request);
+    }
+
+    private void makeExampleGroup() {
+        GroupBrokerManager.getInstance().createGroup(mUid1, mGid1, "myhome",
+                null);
+        GroupBrokerManager.getInstance().createGroup(mUid1, mGid2, "myroom",
+                mGid1);
+        AclResource.getInstance().createAcl(mUid1, mDi1);
+        AclResource.getInstance().createAcl(mUid1, mDi2);
+        AclResource.getInstance().createAcl(mUid1, mDi3);
+        AclResource.getInstance().createAcl(mUid1, mDi4);
+    }
+
     private <T> HashMap<String, Object> makePropertyMap(String property,
             T value) {
         HashMap<String, Object> map = new HashMap<String, Object>();
@@ -622,6 +673,15 @@ public class GroupResourceTest {
         return resource;
     }
 
+    private HashMap<String, Object> makeResources(String href, List<String> rt,
+            List<String> itf) {
+        HashMap<String, Object> resource = new HashMap<String, Object>();
+        resource.put(Constants.KEYFIELD_ACE_RESOURCE_HREF, href);
+        resource.put(Constants.RS_INTERFACE, itf);
+        resource.put(Constants.KEYFIELD_RESOURCE_RT, rt);
+        return resource;
+    }
+
     private void getGroupInfo(CoapDevice device, String gid, String uid)
             throws Exception {
         System.out.println("-----Get group, gid : " + gid);
@@ -665,201 +725,6 @@ public class GroupResourceTest {
         mGroupResource.onDefaultRequestReceived(device, request);
     }
 
-    // @Test
-    public void testFindMyGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "find";
-        createGroup(mMockDevice, uuid, "Public");
-        findGroup(mMockDevice, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-        assertTrue(hashmapCheck(mResponse, "gidlist"));
-        assertTrue(mLatch.await(2L, SECONDS));
-    }
-
-    // @Test(expected = ServerException.BadRequestException.class)
-    public void testCreateGroupNotSupportedType() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "delete";
-        createGroup(mMockDevice, uuid, "NotSupported");
-        deleteGroup(mMockDevice, uuid);
-    }
-
-    // @Test
-    public void testDeleteGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "delete";
-        createGroup(mMockDevice, uuid, "Public");
-        deleteGroup(mMockDevice, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.DELETED));
-        assertTrue(mLatch.await(2L, SECONDS));
-    }
-
-    // @Test(expected = ServerException.PreconditionFailedException.class)
-    public void testDeleteGroupWithoutGid() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "delete";
-        createGroup(mMockDevice, uuid, "Public");
-        deleteGroupWithoutGid(mMockDevice, uuid);
-    }
-
-    // @Test
-    public void testAddDeviceAndUserToGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "AddDeviceAndUser";
-        createGroup(mMockDevice, uuid, "Public");
-        ArrayList<String> midList = new ArrayList<>();
-        midList.add("member0001");
-        midList.add("member0002");
-        ArrayList<String> diList = new ArrayList<>();
-        diList.add("device0001");
-        diList.add("device0002");
-        addDeviceAndUser(mMockDevice, midList, diList);
-    }
-
-    // @Test
-    public void testDeleteDeviceAndUserToGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "AddDeviceAndUser";
-        createGroup(mMockDevice, uuid, "Public");
-        ArrayList<String> midList = new ArrayList<>();
-        midList.add("member0001");
-        midList.add("member0002");
-        ArrayList<String> diList = new ArrayList<>();
-        diList.add("device0001");
-        diList.add("device0002");
-        addDeviceAndUser(mMockDevice, midList, diList);
-        deleteDeviceAndUser(mMockDevice, midList, diList);
-    }
-
-    // @Test(expected = ServerException.BadRequestException.class)
-    public void testDeleteGroupInvalidGmid() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "delete";
-        createGroup(mMockDevice, uuid, "Public");
-        deleteGroup(mMockDevice, uuid + "invlidGmid");
-    }
-
-    // @Test
-    public void testJoinToinvitedGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "join";
-        createGroup(mMockDevice, uuid, "Public");
-        joinGroup(mMockDevice, "u0002");
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        assertTrue(mLatch.await(2L, SECONDS));
-    }
-
-    // @Test
-    public void testObserveGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "obs";
-        createGroup(mMockDevice, uuid, "Public");
-        observeGroup(mMockDevice, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-        assertTrue(hashmapCheck(mResponse, "gid"));
-        assertTrue(hashmapCheck(mResponse, "gmid"));
-        assertTrue(hashmapCheck(mResponse, "midlist"));
-        assertTrue(hashmapCheck(mResponse, "dilist"));
-        assertTrue(mLatch.await(2L, SECONDS));
-    }
-
-    // @Test
-    public void testObserveDeregisterGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "obs";
-        createGroup(mMockDevice, uuid, "Public");
-        observeGroup(mMockDevice, uuid);
-        observeDeregisterGroup(mMockDevice, uuid);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-    }
-
-    // @Test
-    public void testShareDeviceIntoGroup() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "share";
-        createGroup(mMockDevice, uuid, "Public");
-        shareDevice(mMockDevice, "d0002");
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        assertTrue(mLatch.await(2L, SECONDS));
-    }
-
-    // @Test
-    public void testShareDeviceNotification() throws Exception {
-        getTestMethodName();
-        String uuid = this.mUserUuid + "share";
-        String uuidGuest = "u0002guest";
-        CoapDevice mockDeviceGuest = mock(CoapDevice.class);
-        CountDownLatch memberLatch = new CountDownLatch(1);
-        Mockito.doAnswer(new Answer<Object>() {
-            @Override
-            public CoapResponse answer(InvocationOnMock invocation)
-                    throws Throwable {
-                Object[] args = invocation.getArguments();
-                CoapResponse resp = (CoapResponse) args[0];
-                System.out.println("\t----------new member payload : "
-                        + resp.getPayloadString());
-                System.out.println(
-                        "\t---------new member method : " + resp.getStatus());
-                memberLatch.countDown();
-                mResponseObserver = resp;
-                return resp;
-            }
-        }).when(mockDeviceGuest).sendResponse(Mockito.anyObject());
-        createGroup(mMockDevice, uuid, "Public");
-        joinGroup(mockDeviceGuest, uuidGuest);
-        observeGroup(mockDeviceGuest, uuidGuest);
-        shareDevice(mMockDevice, "d0002");
-        // assertion for the group master
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        // assertion for the observer
-        assertTrue(methodCheck(mResponseObserver, ResponseStatus.CONTENT));
-        assertTrue(mLatch.await(2L, SECONDS));
-        assertTrue(memberLatch.await(2L, SECONDS));
-    }
-
-    public void addDeviceAndUser(CoapDevice device, ArrayList<String> midList,
-            ArrayList<String> diList) throws Exception {
-        HashMap<String, Object> payloadData = new HashMap<>();
-        payloadData.put("midlist", midList);
-        payloadData.put("dilist", diList);
-        IRequest request = MessageBuilder.createRequest(RequestMethod.POST,
-                GROUP_URI + "/" + mGroupId, null,
-                ContentFormat.APPLICATION_CBOR,
-                mCbor.encodingPayloadToCbor(payloadData));
-        System.out.println("-----add Device and User : " + payloadData);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    public void deleteDeviceAndUser(CoapDevice device,
-            ArrayList<String> midList, ArrayList<String> diList)
-            throws Exception {
-        String midListString = "";
-        String didListString = "";
-        for (String mid : midList) {
-            midListString += "midlist=";
-            midListString += mid;
-            midListString += ";";
-        }
-        for (String di : diList) {
-            didListString += "dilist=";
-            didListString += di;
-            didListString += ";";
-        }
-        System.out.println("-----delete Device and User, Query: "
-                + midListString + didListString);
-        IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
-                GROUP_URI + "/" + mGroupId, midListString + didListString);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void shareDevice(CoapDevice device, String deviceId)
-            throws Exception {
-        System.out.println("-----Share Device");
-        IRequest request = null;
-        request = createShareDeviceRequest(deviceId);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
     private void createGroup(CoapDevice device, String uid, String gname,
             String parent) throws Exception {
         System.out.println("-----Create Group");
@@ -868,120 +733,13 @@ public class GroupResourceTest {
         mGroupResource.onDefaultRequestReceived(device, request);
     }
 
-    private void findGroup(CoapDevice device, String uuid) throws Exception {
-        System.out.println("-----Find Group");
-        IRequest request = null;
-        request = findGroupRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void observeDeregisterGroup(CoapDevice device, String uuid)
-            throws Exception {
-        System.out.println("-----Observe Deregister Group");
-        IRequest request = null;
-        request = observeDeregisterGroupRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void observeGroup(CoapDevice device, String uuid) throws Exception {
-        System.out.println("-----Observe Group");
-        IRequest request = null;
-        request = observeGroupRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void joinGroup(CoapDevice device, String uuid) throws Exception {
-        System.out.println("-----Join Group");
-        IRequest request = null;
-        request = joinGroupRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void deleteGroup(CoapDevice device, String uuid) throws Exception {
-        System.out.println("-----Delete Group");
-        IRequest request = null;
-        request = deleteGroupRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private void deleteGroupWithoutGid(CoapDevice device, String uuid)
-            throws Exception {
-        System.out.println("-----Delete Group");
-        IRequest request = null;
-        request = deleteGroupWithoutGidRequest(uuid);
-        mGroupResource.onDefaultRequestReceived(device, request);
-    }
-
-    private IRequest deleteGroupWithoutGidRequest(String uuid) {
-        IRequest request = null;
-        request = MessageBuilder.createRequest(RequestMethod.DELETE, GROUP_URI,
-                "gmid=" + uuid);
-        return request;
-    }
-
-    private IRequest deleteGroupRequest(String uuid) {
-        IRequest request = null;
-        request = MessageBuilder.createRequest(RequestMethod.DELETE, GROUP_URI,
-                "gid=" + mGroupId + ";" + "gmid=" + uuid);
-        return request;
-    }
-
-    private IRequest findGroupRequest(String uuid) {
-        IRequest request = null;
-        request = MessageBuilder.createRequest(RequestMethod.GET, GROUP_URI,
-                "mid=" + uuid);
-        return request;
-    }
-
-    private IRequest createShareDeviceRequest(String deviceId) {
-        IRequest request = null;
-        HashMap<String, Object> payloadData = new HashMap<String, Object>();
-        ArrayList<String> diList = new ArrayList<>();
-        diList.add(deviceId);
-        payloadData.put("dilist", diList);
-        request = MessageBuilder.createRequest(RequestMethod.POST,
-                GROUP_URI + "/" + mGroupId, null,
-                ContentFormat.APPLICATION_CBOR,
-                mCbor.encodingPayloadToCbor(payloadData));
-        return request;
-    }
-
-    private IRequest observeDeregisterGroupRequest(String uuid) {
-        IRequest request = null;
-        request = MessageBuilder.createRequest(RequestMethod.GET,
-                GROUP_URI + "/" + mGroupId, "mid=" + uuid);
-        ((CoapRequest) request).setObserve(Observe.UNSUBSCRIBE);
-        return request;
-    }
-
-    private IRequest observeGroupRequest(String uuid) {
-        IRequest request = null;
-        request = MessageBuilder.createRequest(RequestMethod.GET,
-                GROUP_URI + "/" + mGroupId, "mid=" + uuid);
-        ((CoapRequest) request).setObserve(Observe.SUBSCRIBE);
-        return request;
-    }
-
-    private IRequest joinGroupRequest(String uuid) {
-        IRequest request = null;
-        HashMap<String, Object> payloadData = new HashMap<String, Object>();
-        ArrayList<String> midList = new ArrayList<>();
-        midList.add(uuid);
-        payloadData.put("midlist", midList);
-        request = MessageBuilder.createRequest(RequestMethod.POST,
-                GROUP_URI + "/" + mGroupId, null,
-                ContentFormat.APPLICATION_CBOR,
-                mCbor.encodingPayloadToCbor(payloadData));
-        return request;
-    }
-
     private IRequest createGroupRequest(String uid, String gname,
             String parent) {
         IRequest request = null;
         HashMap<String, Object> payloadData = new HashMap<String, Object>();
         payloadData.put(Constants.REQ_UUID_ID, uid);
-        payloadData.put(Constants.KEYFIELD_GNAME, gname);
-        payloadData.put(Constants.KEYFIELD_PARENT, parent);
+        payloadData.put(Constants.KEYFIELD_GROUP_NAME, gname);
+        payloadData.put(Constants.KEYFIELD_GROUP_PARENT, parent);
         request = MessageBuilder.createRequest(RequestMethod.POST, GROUP_URI,
                 null, ContentFormat.APPLICATION_CBOR,
                 mCbor.encodingPayloadToCbor(payloadData));
index e7f84ce..5005264 100644 (file)
@@ -267,7 +267,7 @@ public class InviteResourceTest {
     @Test
     public void testDeleteInvitationForAccept() throws Exception {
 
-        createGroup(TEST_INVITE_USER, "Public");
+        createGroup(mMockDevice, TEST_INVITE_USER, "Public", null);
         sendInvitation(mInvitedGroupId, TEST_INVITED_USER);
 
         deleteInvitationWithQuery(mInvitedGroupId, TEST_INVITED_USER, true);
@@ -280,7 +280,7 @@ public class InviteResourceTest {
     @Test
     public void testDeleteInvitationForDeny() throws Exception {
 
-        createGroup(TEST_INVITE_USER, "Public");
+        createGroup(mMockDevice, TEST_INVITE_USER, "Public", null);
         sendInvitation(mInvitedGroupId, TEST_INVITED_USER);
 
         deleteInvitationWithQuery(mInvitedGroupId, TEST_INVITED_USER, false);
@@ -397,25 +397,24 @@ public class InviteResourceTest {
         mInviteResource.onDefaultRequestReceived(mMockDevice, request);
     }
 
-    private void createGroup(String gmid, String gtype) {
-
-        IRequest request = createGroupRequest(gmid, gtype);
-
-        mGroupResource.onDefaultRequestReceived(mMockDevice, request);
+    private void createGroup(CoapDevice device, String uid, String gname,
+            String parent) throws Exception {
+        System.out.println("-----Create Group");
+        IRequest request = null;
+        request = createGroupRequest(uid, gname, parent);
+        mGroupResource.onDefaultRequestReceived(device, request);
     }
 
-    private IRequest createGroupRequest(String uuid, String gtype) {
-
+    private IRequest createGroupRequest(String uid, String gname,
+            String parent) {
         IRequest request = null;
-
         HashMap<String, Object> payloadData = new HashMap<String, Object>();
-        payloadData.put("gmid", uuid);
-        payloadData.put("gtype", gtype);
-
+        payloadData.put(Constants.REQ_UUID_ID, uid);
+        payloadData.put(Constants.KEYFIELD_GROUP_NAME, gname);
+        payloadData.put(Constants.KEYFIELD_GROUP_PARENT, parent);
         request = MessageBuilder.createRequest(RequestMethod.POST, GROUP_URI,
                 null, ContentFormat.APPLICATION_CBOR,
                 mCbor.encodingPayloadToCbor(payloadData));
-
         return request;
     }
 }
\ No newline at end of file
index 8466203..a502fc4 100644 (file)
@@ -51,6 +51,8 @@ public class Constants extends OICConstants {
     public static final String REQ_REQUEST_METHOD  = "rm";
     public static final String REQ_REQUEST_URI     = "uri";
 
+    public static final String REQ_GROUP_DEVICES   = "devices";
+
     public static final String RESP_GRANT_POLICY   = "gp";
     public static final String RESP_ACL_ALLOWED    = "Allowed";
     public static final String RESP_ACL_DENIED     = "Denied";
@@ -58,4 +60,7 @@ public class Constants extends OICConstants {
     public static final String REQ_LINKS           = "links";
     public static final String REQ_HREF            = "href";
     public static final String REQ_CRL             = "crl";
+
+    public static final String KEYFIELD_GROUPS     = "groups";
+    public static final String KEYFIELD_DEVICES    = "devices";
 }
index e9bed77..d106e96 100644 (file)
@@ -30,8 +30,6 @@ import org.iotivity.cloud.base.device.IRequestChannel;
 import org.iotivity.cloud.base.exception.ServerException;
 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
 import org.iotivity.cloud.base.protocols.IRequest;
-import org.iotivity.cloud.base.protocols.MessageBuilder;
-import org.iotivity.cloud.base.protocols.enums.ContentFormat;
 import org.iotivity.cloud.base.resource.Resource;
 import org.iotivity.cloud.ciserver.Constants;
 import org.iotivity.cloud.util.Cbor;
@@ -66,46 +64,10 @@ public class AclGroup extends Resource {
                 if (payloadData == null) {
                     throw new BadRequestException("payload is null");
                 }
-                if (getUriPathSegments()
-                        .containsAll(request.getUriPathSegments())) {
-                    payloadData.put(Constants.REQ_GROUP_MASTER_ID,
-                            srcDevice.getUserId());
-                } else {
-                    if (payloadData.isEmpty()) {
-                        payloadData = new HashMap<>();
-                        payloadData.put(Constants.REQ_MEMBER_LIST,
-                                Arrays.asList(srcDevice.getUserId()));
-                    }
-                }
-                request = MessageBuilder.modifyRequest(request, null, null,
-                        ContentFormat.APPLICATION_CBOR,
-                        mCbor.encodingPayloadToCbor(payloadData));
                 break;
             case GET:
-                StringBuffer uriGetQuery = new StringBuffer();
-                uriGetQuery.append(
-                        Constants.REQ_MEMBER_ID + "=" + srcDevice.getUserId());
-                request = MessageBuilder.modifyRequest(request, null,
-                        uriGetQuery.toString(), null, null);
                 break;
             case DELETE:
-                StringBuffer additionalQuery = new StringBuffer();
-                if (getUriPathSegments()
-                        .containsAll(request.getUriPathSegments())) {
-                    additionalQuery.append(Constants.REQ_GROUP_MASTER_ID + "="
-                            + srcDevice.getUserId());
-                    String uriDeleteQuery = request.getUriQuery() + ";"
-                            + additionalQuery.toString();
-                    request = MessageBuilder.modifyRequest(request, null,
-                            uriDeleteQuery, null, null);
-                } else {
-                    if (request.getUriQuery() == null) {
-                        additionalQuery.append(Constants.REQ_MEMBER_LIST + "="
-                                + srcDevice.getUserId());
-                        request = MessageBuilder.modifyRequest(request, null,
-                                additionalQuery.toString(), null, null);
-                    }
-                }
                 break;
             default:
                 throw new BadRequestException(
index a2fa953..addbbe8 100644 (file)
@@ -78,11 +78,11 @@ public class ResourceDirectory extends Resource {
                 String di = payloadData.get(Constants.REQ_DEVICE_ID).toString();
 
                 HashMap<String, Object> requestPayload = new HashMap<>();
-
-                requestPayload.put(Constants.REQ_DEVICE_LIST,
+                requestPayload.put(Constants.USER_ID, srcDevice.getUserId());
+                requestPayload.put(Constants.REQ_GROUP_DEVICES,
                         Arrays.asList(di));
                 IRequest requestToAS = MessageBuilder.createRequest(
-                        RequestMethod.POST, uriPath.toString(), null,
+                        RequestMethod.POST, uriPath.toString(), "op=add",
                         ContentFormat.APPLICATION_CBOR,
                         mCbor.encodingPayloadToCbor(requestPayload));
 
index 320ebf8..656fafc 100644 (file)
@@ -21,6 +21,7 @@
  */
 package org.iotivity.cloud.ciserver.resources.proxy.rd;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -85,19 +86,24 @@ public class ResourceFind extends Resource {
                         return;
                     }
 
+                    ArrayList<String> devices = new ArrayList<>();
+
+                    devices = (ArrayList<String>) payloadData
+                            .get(Constants.KEYFIELD_DEVICES);
+
+                    System.out.println("devices : " + devices);
+
                     if (mRequest.getUriQuery() != null
                             && mRequest.getUriQueryMap()
                                     .containsKey(Constants.REQ_DEVICE_ID)) {
-                        if (!getResponseDeviceList(payloadData)
-                                .containsAll(mRequest.getUriQueryMap()
-                                        .get(Constants.REQ_DEVICE_ID))) {
+                        if (!devices.containsAll(mRequest.getUriQueryMap()
+                                .get(Constants.REQ_DEVICE_ID))) {
                             mSrcDevice.sendResponse(
                                     MessageBuilder.createResponse(mRequest,
                                             ResponseStatus.BAD_REQUEST));
                         }
                     } else {
-                        String additionalQuery = makeAdditionalQuery(
-                                payloadData);
+                        String additionalQuery = makeAdditionalQuery(devices);
                         mRequest = MessageBuilder.modifyRequest(mRequest, null,
                                 (mRequest.getUriQuery() != null
                                         ? mRequest.getUriQuery() : "")
@@ -114,11 +120,9 @@ public class ResourceFind extends Resource {
             }
         }
 
-        private String makeAdditionalQuery(
-                HashMap<String, Object> payloadData) {
+        private String makeAdditionalQuery(ArrayList<String> deviceList) {
 
             StringBuilder additionalQuery = new StringBuilder();
-            List<String> deviceList = getResponseDeviceList(payloadData);
 
             if (deviceList == null) {
                 return null;
@@ -157,8 +161,7 @@ public class ResourceFind extends Resource {
             mRDServer.sendRequest(request, srcDevice);
         } else {
             StringBuffer uriQuery = new StringBuffer();
-            uriQuery.append(
-                    Constants.REQ_MEMBER_ID + "=" + srcDevice.getUserId());
+            uriQuery.append(Constants.USER_ID + "=" + srcDevice.getUserId());
 
             StringBuffer uriPath = new StringBuffer();
             uriPath.append(Constants.PREFIX_OIC + "/");