From 846d7a0f59b2e1723b3e1538fbe32e7289917077 Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Wed, 8 Feb 2023 11:17:02 +0000 Subject: [PATCH] Add support to perform group operations (#59) ## Purpose * Fixes https://roadmap.entgra.net/issues/8916 ## Description * Created a new API to check whether groups has relevant(Android, iOS, Windows) device types. Co-authored-by: Arshana Co-authored-by: prathabanKavin Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/59 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../service/api/DeviceManagementService.java | 10 +-- .../service/api/GroupManagementService.java | 61 +++++++++++++++++++ .../impl/DeviceManagementServiceImpl.java | 7 +-- .../impl/GroupManagementServiceImpl.java | 18 ++++++ .../impl/DeviceManagementServiceImplTest.java | 4 +- .../common/group/mgt/DeviceTypesOfGroups.java | 60 ++++++++++++++++++ .../GroupManagementProviderService.java | 8 +++ .../GroupManagementProviderServiceImpl.java | 59 ++++++++++++++++++ .../src/main/resources/conf/mdm-ui-config.xml | 1 + 9 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceTypesOfGroups.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 585e4ffecf..3304be7c14 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -1209,7 +1209,7 @@ public interface DeviceManagementService { @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/{type}/{id}/features") + @Path("/device-type/{type}/features") @ApiOperation( produces = MediaType.APPLICATION_JSON, httpMethod = "GET", @@ -1280,14 +1280,6 @@ public interface DeviceManagementService { @PathParam("type") @Size(max = 45) String type, - @ApiParam( - name = "id", - value = "The device identifier of the device.\n" + - "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.", - required = true) - @PathParam("id") - @Size(max = 45) - String id, @ApiParam( name = "If-Modified-Since", value = "Checks if the requested variant was modified, since the specified date-time. \n" + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java index 1162c55f45..96b3188f70 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java @@ -192,6 +192,13 @@ import java.util.List; key = "perm:groups:device", roles = {"Internal/devicemgt-user"}, permissions = {"/device-mgt/groups/devices/view"} + ), + @Scope( + name = "View whether the groups has relevant device types", + description = "View whether the groups has relevant device types", + key = "perm:groups:devices-types", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/groups/devices/types"} ) } ) @@ -1185,4 +1192,58 @@ public interface GroupManagementService { @QueryParam("requireGroupProps") boolean requireGroupProps); + @Path("/device-types") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Getting Details whether the groups has relevant device type or not", + notes = "Getting Details whether the groups has relevant device type or not.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:devices-types") + }) + }, + nickname = "getGroupByGroupNameFilter" + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device types of groups.", + response = DeviceGroup.class, + responseHeaders = { + @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 = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Error occurred", + 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 fetching the group details.", + response = ErrorResponse.class) + }) + Response getGroupHasDeviceTypes( + @ApiParam( + name = "identifiers", + value = "GET list of identifiers.", + required = true) + List identifiers); + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 7570227203..3bcdeafbab 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -890,16 +890,14 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { } @GET - @Path("/{type}/{id}/features") + @Path("/device-type/{type}/features") @Override public Response getFeaturesOfDevice( @PathParam("type") @Size(max = 45) String type, - @PathParam("id") @Size(max = 45) String id, @HeaderParam("If-Modified-Since") String ifModifiedSince) { List features = new ArrayList<>(); DeviceManagementProviderService dms; try { - RequestValidationUtil.validateDeviceIdentifier(type, id); dms = DeviceMgtAPIUtils.getDeviceManagementService(); FeatureManager fm; try { @@ -913,8 +911,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { features = fm.getFeatures(); } } catch (DeviceManagementException e) { - String msg = "Error occurred while retrieving the list of features of '" + type + "' device, which " + - "carries the id '" + id + "'"; + String msg = "Error occurred while retrieving the list of features of '" + type + "'"; log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java index 8927ea533d..898ffb6c23 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java @@ -48,6 +48,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceTypesOfGroups; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; @@ -66,6 +67,7 @@ import org.wso2.carbon.policy.mgt.common.PolicyManagementException; 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; @@ -429,4 +431,20 @@ public class GroupManagementServiceImpl implements GroupManagementService { } } + @POST + @Path("/device-types") + @Override + public Response getGroupHasDeviceTypes(List identifiers) { + try { + DeviceTypesOfGroups deviceTypesOfGroups = DeviceMgtAPIUtils.getGroupManagementProviderService() + .getDeviceTypesOfGroups(identifiers); + + return Response.status(Response.Status.OK).entity(deviceTypesOfGroups).build(); + } catch (GroupManagementException e) { + String msg = "Only numbers can exists in a group ID or Invalid Group ID provided."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index 7b995660ad..db085319f0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -590,7 +590,7 @@ public class DeviceManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); Response response = this.deviceManagementService - .getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + .getFeaturesOfDevice(TEST_DEVICE_TYPE, null); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -601,7 +601,7 @@ public class DeviceManagementServiceImplTest { Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())) .thenThrow(new DeviceTypeNotFoundException()); Response response = this.deviceManagementService - .getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + .getFeaturesOfDevice(TEST_DEVICE_TYPE, null); Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceTypesOfGroups.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceTypesOfGroups.java new file mode 100644 index 0000000000..66bde2dc83 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceTypesOfGroups.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Entgra (pvt) Ltd. (https://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 org.wso2.carbon.device.mgt.common.group.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +@ApiModel(value = "DeviceTypesOfGroups", description = "This class carries whether the groups has device type or not.") +public class DeviceTypesOfGroups implements Serializable { + + private static final long serialVersionUID = 5562356373277828099L; + @ApiModelProperty(name = "hasAndroid", value = "groups has Android devices.") + private boolean hasAndroid; + @ApiModelProperty(name = "id", value = "groups has iOS devices.") + private boolean hasIos; + @ApiModelProperty(name = "hasAndroid", value = "groups has Windows devices.") + private boolean hasWindows; + + public boolean isHasAndroid() { + return hasAndroid; + } + + public void setHasAndroid(boolean hasAndroid) { + this.hasAndroid = hasAndroid; + } + + public boolean isHasIos() { + return hasIos; + } + + public void setHasIos(boolean hasIos) { + this.hasIos = hasIos; + } + + public boolean isHasWindows() { + return hasWindows; + } + + public void setHasWindows(boolean hasWindows) { + this.hasWindows = hasWindows; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java index 5028f2560b..8f12f8a1df 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java @@ -41,6 +41,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceTypesOfGroups; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; @@ -335,4 +336,11 @@ public interface GroupManagementProviderService { */ boolean isDeviceMappedToGroup(int groupId, DeviceIdentifier deviceIdentifier) throws GroupManagementException; + /** + * + * @param identifiers identifiers of groups + * @return whether the groups has android, iOS, Windows device types + * @throws GroupManagementException + */ + DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java index aed9bc8782..9981333428 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -43,6 +43,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; @@ -51,6 +52,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.TrackerAlreadyExistException import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceTypesOfGroups; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; @@ -79,6 +81,7 @@ import java.util.stream.Collectors; public class GroupManagementProviderServiceImpl implements GroupManagementProviderService { private static final Log log = LogFactory.getLog(GroupManagementProviderServiceImpl.class); + private static final String DEVICE_STATUS_REMOVED = "REMOVED"; private final GroupDAO groupDAO; private final DeviceDAO deviceDAO; @@ -1379,4 +1382,60 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid createGroupWithChildren(nextParentGroup, childrenGroups, requireGroupProps, tenantId, depth, counter); } } + @Override + public DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException { + DeviceTypesOfGroups deviceTypesOfGroups = new DeviceTypesOfGroups(); + List groupsIDs = new ArrayList<>(); + try { + for (String id : identifiers) { + groupsIDs.add(Integer.parseInt(id)); + } + + List deviceIDs = new ArrayList<>(); + List allDevices = new ArrayList<>(); + for (Integer groupID : groupsIDs) { + DeviceGroup deviceGroup = getGroup(groupID, false); + if (deviceGroup == null) { + String errorMessage = "Invalid Group ID provided."; + log.error(errorMessage); + throw new GroupManagementException(errorMessage); + } + List devices = getAllDevicesOfGroup(deviceGroup.getName(), false); + for (Device device : devices) { + if (!DEVICE_STATUS_REMOVED.equals(device.getEnrolmentInfo().getStatus().toString()) + && !deviceIDs.contains(device.getDeviceIdentifier())) { + deviceIDs.add(device.getDeviceIdentifier()); + allDevices.add(device); + } + } + } + + for (Device device : allDevices) { + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID.equals(device.getType())) { + deviceTypesOfGroups.setHasAndroid(true); + break; + } + } + for (Device device : allDevices) { + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS.equals(device.getType())) { + deviceTypesOfGroups.setHasIos(true); + break; + } + } + for (Device device : allDevices) { + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_WINDOWS.equals(device.getType())) { + deviceTypesOfGroups.setHasWindows(true); + break; + } + } + + } catch (NumberFormatException e) { + String errorMessage = "Only numbers can exists in a group ID"; + log.error(errorMessage); + throw new GroupManagementException(errorMessage, e); + + } + + return deviceTypesOfGroups; + } } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index 9e2761a6c8..151d03081c 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -130,6 +130,7 @@ perm:groups:add perm:groups:device perm:groups:devices-count + perm:groups:devices-types perm:groups:remove perm:groups:groups perm:groups:groups-view