Add hierarchical grouping feature

remotes/1728937285237262521/tmp_refs/heads/master
Thilina Sandaruwan 2 years ago committed by pasindu
parent ce4276c93a
commit 88356c57aa

@ -26,6 +26,13 @@ import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.swagger.annotations.*;
import org.apache.axis2.transport.http.HTTPConstants;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceToGroupsAssignment;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import javax.validation.Valid;
import javax.ws.rs.*;
@ -159,6 +166,13 @@ import java.util.List;
key = "perm:groups:devices-types",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/groups/devices/types"}
),
@Scope(
name = "View whether the groups has relevant device types",
description = "View whether the groups has relevant device types",
key = "perm:groups:add",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/groups/device-types"}
)
}
)
@ -1206,4 +1220,77 @@ public interface GroupManagementService {
required = true)
List<String> identifiers);
@POST
@Path("/roles/share")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Consolidated API for Creating a Device Group, Adding Devices, and Sharing",
notes = "This API can be used to create a new device group, add devices to the group, and share the group with user roles.",
tags = "Device Group Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:add")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "Created. \n Device group has successfully been created.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The URL of the created group."),
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body."),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests.")
}
),
@ApiResponse(
code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location " +
"header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Current logged in user is not authorized to perform the operation.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Group not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while creating the group or adding devices or sharing the group.",
response = ErrorResponse.class)
})
Response createGroupWithRoles(@ApiParam(
name = "group",
value = "Define the group object with data.",
required = true)
@Valid DeviceGroupRoleWrapper group
);
}

@ -27,8 +27,16 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.swagger.annotations.*;
import org.apache.axis2.transport.http.HTTPConstants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -358,4 +366,79 @@ public interface GroupManagementAdminService {
required = true)
@Valid DeviceGroup group);
@POST
@Path("/roles/share")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Consolidated API for Creating a Device Group, Adding Devices, and Sharing",
notes = "This API can be used to create a new device group, add devices to the group, and share the group with user roles.",
tags = "Device Group Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:add")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "Created. \n Device group has successfully been created.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The URL of the created group."),
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body."),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests.")
}
),
@ApiResponse(
code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location " +
"header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Current logged in user is not authorized to perform the operation.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Group not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while creating the group or adding devices or sharing the group.",
response = ErrorResponse.class)
})
Response createGroupWithRoles(@ApiParam(
name = "group",
value = "Define the group object with data.",
required = true)
@Valid DeviceGroupRoleWrapper group
);
}

@ -18,6 +18,27 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupConstants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceTypesOfGroups;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceToGroupsAssignment;
@ -39,6 +60,14 @@ import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import javax.ws.rs.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@ -416,4 +445,38 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
}
@POST
@Path("/roles/share")
@Override
public Response createGroupWithRoles(DeviceGroupRoleWrapper groups) {
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (groups == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
groups.setOwner(owner);
groups.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE);
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().createGroupWithRoles(groups, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS);
DeviceGroup group = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroup(groups.getName(), owner.isEmpty());
if (group != null) {
DeviceMgtAPIUtils.getGroupManagementProviderService().manageGroupSharing(group.getGroupId(), groups.getUserRoles());
return Response.status(Response.Status.CREATED).entity(group.getGroupId()).build();
} else {
String msg = "Error occurred while retrieving newly created group.";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} catch (GroupManagementException e) {
String msg = "Error occurred while adding new group.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + groups.getName() + ".";
log.warn(msg);
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
}

@ -29,9 +29,25 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupConstants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceGroupList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.admin.GroupManagementAdminService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.RequestValidationUtil;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@ -144,4 +160,29 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
return Response.status(Response.Status.CONFLICT).entity(msg).build();
}
}
@POST
@Path("/roles/share")
@Override
public Response createGroupWithRoles(DeviceGroupRoleWrapper group) {
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (group == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
group.setOwner(owner);
group.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE);
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().createGroupWithRoles(group, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS);
DeviceMgtAPIUtils.getGroupManagementProviderService().manageGroupSharing(group.getGroupId(), group.getUserRoles());
return Response.status(Response.Status.CREATED).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while adding new group.";
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + group.getName() + ".";
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
}

@ -0,0 +1,155 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.common.group.mgt;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiParam;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* Holds Device Group details and expose to external access
*/
@ApiModel(value = "DeviceGroupRoleWrapper", description = "This class carries all information related to a managed device group.")
public class DeviceGroupRoleWrapper implements Serializable {
private static final long serialVersionUID = 1998121711L;
@ApiModelProperty(name = "id", value = "ID of the device group in the device group information database.")
private int id;
@ApiModelProperty(name = "description", value = "The device group description that can be set on the device group by the user.",
required = true)
private String description;
@ApiModelProperty(name = "name", value = "The device group name that can be set on the device group by the user.",
required = true)
private String name;
private String owner;
@ApiModelProperty(name = "status", value = "The status of group that needs updating/retrieval.")
private String status;
@ApiModelProperty(name = "parentGroupId", value = "Group ID of parent group")
private int parentGroupId;
@ApiModelProperty(name = "parentPath", value = "Path of parent group")
private String parentPath;
@ApiModelProperty(name = "childrenGroups", value = "Children groups")
private List<DeviceGroup> childrenGroups;
@ApiModelProperty(name = "userRoles", value = "User roles")
private List<String> userRoles;
// @ApiModelProperty(name = "DeviceGroupRoleWrapper", value = "Device group role wrapper")
// private List<DeviceGroupRoleWrapper> DeviceGroupRoleWrapper;
public DeviceGroupRoleWrapper() {}
public DeviceGroupRoleWrapper(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
private Map<String,String> groupProperties;
public int getGroupId() {
return id;
}
public void setGroupId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Map<String,String> getGroupProperties() {
return groupProperties;
}
public void setGroupProperties(Map<String,String> groupProperties) {
this.groupProperties = groupProperties;
}
public int getParentGroupId() {
return parentGroupId;
}
public void setParentGroupId(int parentGroupId) {
this.parentGroupId = parentGroupId;
}
public String getParentPath() {
return parentPath;
}
public void setParentPath(String parentPath) {
this.parentPath = parentPath;
}
public List<DeviceGroup> getChildrenGroups() {
return childrenGroups;
}
public void setChildrenGroups(List<DeviceGroup> childrenGroups) {
this.childrenGroups = childrenGroups;
}
public List<String> getUserRoles() {
return userRoles;
}
public void setUserRoles(List<String> userRoles) {
this.userRoles = userRoles;
}
}

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import java.util.List;
import java.util.Map;
@ -40,6 +41,21 @@ public interface GroupDAO {
*/
int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException;
/**
* Add properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
* device group Payload is ignored in the add/update logic instead the internal groupId reference is used.
*
* @param groups to be added.
* @param tenantId of the group.
* @return sql execution result.
* @throws GroupManagementDAOException
*/
int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException;
/**
* Add properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
@ -50,8 +66,22 @@ public interface GroupDAO {
* @return sql execution result.
* @throws GroupManagementDAOException
*/
boolean addGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId) throws GroupManagementDAOException;
/**
* Update properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with
* device group Payload is ignored in the add/update logic instead the internal groupId reference is used.
*
* @param groups to be updated.
* @param tenantId of the group.
* @return sql execution result.
* @throws GroupManagementDAOException
*/
boolean addGroupPropertiesWithRoles(DeviceGroupRoleWrapper groups, int groupId, int tenantId) throws GroupManagementDAOException;
/**
* Update properties for device group.
* Note that groupId parameter is considered seperately due to the groupId parameter passed with

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.core.dao.impl;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
@ -49,7 +50,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE TENANT_ID = ?";
if (StringUtils.isNotBlank(request.getGroupName())) {
sql += " AND GROUP_NAME LIKE ?";
@ -111,7 +112,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE TENANT_ID = ?";
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP WHERE TENANT_ID = ?";
if (StringUtils.isNotBlank(request.getGroupName())) {
sql += " AND GROUP_NAME LIKE ?";
}
@ -175,11 +176,11 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (deviceGroup.getStatus() == null || deviceGroup.getStatus().isEmpty()) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) "
+ "VALUES (?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) "
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID, STATUS) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
hasStatus = true;
}
stmt = conn.prepareStatement(sql, new String[]{"ID"});
@ -188,8 +189,9 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(3, deviceGroup.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, deviceGroup.getParentPath());
stmt.setInt(6, deviceGroup.getParentGroupId());
if (hasStatus) {
stmt.setString(6, deviceGroup.getStatus());
stmt.setString(7, deviceGroup.getStatus());
}
stmt.executeUpdate();
@ -206,6 +208,48 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
public int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs;
int groupId = -1;
boolean hasStatus = false;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (groups.getStatus() == null || groups.getStatus().isEmpty()) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID, STATUS) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
hasStatus = true;
}
stmt = conn.prepareStatement(sql, new String[]{"ID"});
stmt.setString(1, groups.getDescription());
stmt.setString(2, groups.getName());
stmt.setString(3, groups.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, groups.getParentPath());
stmt.setInt(6, groups.getParentGroupId());
if (hasStatus) {
stmt.setString(7, groups.getStatus());
}
stmt.executeUpdate();
rs = stmt.getGeneratedKeys();
if (rs.next()) {
groupId = rs.getInt(1);
}
return groupId;
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while adding deviceGroup '" +
groups.getName() + "'", e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, null);
}
}
public boolean addGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
@ -234,6 +278,34 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
return status;
}
public boolean addGroupPropertiesWithRoles(DeviceGroupRoleWrapper groups, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
PreparedStatement stmt = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
stmt = conn.prepareStatement(
"INSERT INTO GROUP_PROPERTIES(GROUP_ID, PROPERTY_NAME, " +
"PROPERTY_VALUE, TENANT_ID) VALUES (?, ?, ?, ?)");
for (Map.Entry<String, String> entry : groups.getGroupProperties().entrySet()) {
stmt.setInt(1, groupId);
stmt.setString(2, entry.getKey());
stmt.setString(3, entry.getValue());
stmt.setInt(4, tenantId);
stmt.addBatch();
}
stmt.executeBatch();
status = true;
} catch (SQLException e) {
String msg = "Error occurred while adding properties for group '" +
groups.getName() + "' values : " + groups.getGroupProperties();
throw new GroupManagementDAOException(msg, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
public boolean updateGroupProperties(DeviceGroup deviceGroup, int groupId, int tenantId)
throws GroupManagementDAOException {
boolean status;
@ -491,7 +563,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
ResultSet resultSet = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE ID = ? "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP WHERE ID = ? "
+ "AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
@ -514,7 +586,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
public List<DeviceGroup> getChildrenGroups(String parentPath, int tenantId) throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, parentPath + "%");
@ -539,7 +611,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
public List<DeviceGroup> getRootGroups(int tenantId) throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "/");
@ -567,7 +639,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupBuilders = new ArrayList<>();
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS, G.PARENT_PATH FROM DM_GROUP G " +
String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS, G.PARENT_PATH, G.PARENT_GROUP_ID FROM DM_GROUP G " +
"INNER JOIN DM_DEVICE_GROUP_MAP GM ON G.ID = GM.GROUP_ID " +
"WHERE GM.DEVICE_ID = ? AND GM.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
@ -705,7 +777,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql =
"SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
"SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE LOWER(GROUP_NAME) = LOWER(?) AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, groupName);
@ -876,7 +948,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP g, " +
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID P FROM DM_GROUP g, " +
"(SELECT GROUP_ID FROM DM_ROLE_GROUP_MAP WHERE ROLE IN (";
int index = 0;
@ -990,7 +1062,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List<DeviceGroup> deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH, PARENT_GROUP_ID FROM DM_GROUP "
+ "WHERE OWNER = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, username);

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.core.dao.impl.group;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException;
@ -49,7 +50,7 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if(StringUtils.isEmpty(deviceGroup.getStatus())) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) " +
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, PARENT_GROUP_ID) " +
"VALUES (?, ?, ?, ?) RETURNING ID";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) " +
@ -79,6 +80,45 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
}
}
public int addGroupWithRoles(DeviceGroupRoleWrapper groups, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs;
int groupId = -1;
boolean hasStatus = false;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if(StringUtils.isEmpty(groups.getStatus())) {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) " +
"VALUES (?, ?, ?, ?) RETURNING ID";
} else {
sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) " +
"VALUES (?, ?, ?, ?, ?) RETURNING ID";
hasStatus = true;
}
stmt = conn.prepareStatement(sql);
stmt.setString(1, groups.getDescription());
stmt.setString(2, groups.getName());
stmt.setString(3, groups.getOwner());
stmt.setInt(4, tenantId);
stmt.setString(5, groups.getParentPath());
if(hasStatus) {
stmt.setString(6, groups.getStatus());
}
stmt.execute();
rs = stmt.getGeneratedKeys();
if (rs.next()) {
groupId = rs.getInt(1);
}
return groupId;
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while adding deviceGroup '" +
groups.getName() + "'", e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, null);
}
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {

@ -87,6 +87,7 @@ public final class GroupManagementDAOUtil {
group.setOwner(resultSet.getString("OWNER"));
group.setStatus(resultSet.getString("STATUS"));
group.setParentPath(resultSet.getString("PARENT_PATH"));
group.setParentGroupId(resultSet.getInt("PARENT_GROUP_ID"));
return group;
}

@ -43,6 +43,17 @@ public interface GroupManagementProviderService {
void createGroup(DeviceGroup deviceGroup, String defaultRole,
String[] defaultPermissions) throws GroupManagementException, GroupAlreadyExistException;
/**
* Add new device group and create default role with default permissions.
*
* @param groups to add
* @param defaultRole of the deviceGroup
* @param defaultPermissions of the default role
* @throws GroupManagementException
*/
void createGroupWithRoles(DeviceGroupRoleWrapper groups, String defaultRole,
String[] defaultPermissions )throws GroupManagementException, GroupAlreadyExistException, RoleDoesNotExistException;
/**
* Update existing device group.
*

@ -19,6 +19,23 @@
package io.entgra.device.mgt.core.device.mgt.core.service;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupConstants;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceTypesOfGroups;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
@ -41,6 +58,11 @@ import org.wso2.carbon.user.api.UserStoreManager;
import java.sql.SQLException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@ -125,6 +147,68 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
}
}
public void createGroupWithRoles(DeviceGroupRoleWrapper groups, String defaultRole, String[] defaultPermissions)
throws GroupManagementException, GroupAlreadyExistException {
if (groups == null) {
String msg = "Received incomplete data for createGroup";
log.error(msg);
throw new GroupManagementException(msg);
}
if (log.isDebugEnabled()) {
log.debug("Creating group '" + groups.getName() + "'");
}
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
GroupManagementDAOFactory.beginTransaction();
DeviceGroup existingGroup = this.groupDAO.getGroup(groups.getName(), tenantId);
if (existingGroup == null) {
if (groups.getParentGroupId() == 0) {
groups.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
} else {
DeviceGroup immediateParentGroup = groupDAO.getGroup(groups.getParentGroupId(), tenantId);
if (immediateParentGroup == null) {
String msg = "Parent group with group ID '" + groups.getParentGroupId()
+ "' does not exist. Hence creating of group '" + groups.getName()
+ "' was not success";
log.error(msg);
throw new GroupManagementException(msg);
}
String parentPath = DeviceManagerUtil.createParentPath(immediateParentGroup);
groups.setParentPath(parentPath);
}
int updatedGroupID = this.groupDAO.addGroupWithRoles(groups, tenantId);
if (groups.getGroupProperties() != null && groups.getGroupProperties().size() > 0) {
this.groupDAO.addGroupPropertiesWithRoles(groups, updatedGroupID, tenantId);
}
GroupManagementDAOFactory.commitTransaction();
} else {
throw new GroupAlreadyExistException("Group exist with name " + groups.getName());
}
} catch (GroupManagementDAOException e) {
GroupManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while adding deviceGroup '" + groups.getName() + "' to database.";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while initiating transaction.";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (GroupAlreadyExistException ex) {
throw ex;
} catch (Exception e) {
String msg = "Error occurred in creating group '" + groups.getName() + "'";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
GroupManagementDAOFactory.closeConnection();
}
if (log.isDebugEnabled()) {
log.debug("DeviceGroup added: " + groups.getName());
}
}
/**
* {@inheritDoc}
*/

@ -16,6 +16,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(45) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);

@ -47,7 +47,7 @@
<artifactId>testng</artifactId>
</dependency>
<dependency>
<groupId>org. wso2.tomcat</groupId>
<groupId>org.wso2.tomcat</groupId>
<artifactId>tomcat</artifactId>
</dependency>
<dependency>

@ -66,6 +66,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(255) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);
DROP TABLE IF EXISTS DM_ROLE_GROUP_MAP;

@ -25,6 +25,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(255) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);

@ -41,6 +41,7 @@ IF NOT EXISTS(SELECT *
OWNER VARCHAR(255) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);

@ -29,6 +29,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(255) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
)
ENGINE = InnoDB;

@ -52,6 +52,7 @@ CREATE TABLE DM_GROUP (
OWNER VARCHAR2(255) DEFAULT NULL,
PARENT_PATH VARCHAR2(255) DEFAULT NULL,
TENANT_ID NUMBER(10) DEFAULT 0,
PARENT_GROUP_ID NUMBER(10) DEFAULT 0,
CONSTRAINT PK_DM_GROUP PRIMARY KEY (ID)
)
/

@ -23,6 +23,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
OWNER VARCHAR(45) DEFAULT NULL,
PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PARENT_GROUP_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
)
;

Loading…
Cancel
Save