From 295921b2897929ed7b6bd420b1e363a6023b7df2 Mon Sep 17 00:00:00 2001 From: charitha Date: Tue, 3 Jan 2017 11:35:08 +0530 Subject: [PATCH] Fixed following issues: https://wso2.org/jira/browse/IOTS-218 https://wso2.org/jira/browse/IOTS-236 https://wso2.org/jira/browse/IOTS-263 https://wso2.org/jira/browse/IOTS-173 --- .../jaxrs/beans/DeviceToGroupsAssignment.java | 56 ++++++ .../service/api/GroupManagementService.java | 112 ++++++++++++ .../impl/GroupManagementServiceImpl.java | 47 ++++- .../app/pages/cdmf.page.devices/devices.hbs | 12 +- .../cdmf.page.devices/public/js/listing.js | 165 +++++++++++------- .../listing.hbs | 56 ++++-- .../cdmf.unit.device.types.listing/listing.js | 3 + .../public/js/listing.js | 7 - 8 files changed, 359 insertions(+), 99 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java new file mode 100644 index 0000000000..ef696f0c27 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceToGroupsAssignment extends BasePaginatedResult { + + @ApiModelProperty(value = "List of device group ids.") + @JsonProperty("deviceGroupIds") + private List deviceGroupIds = new ArrayList<>(); + + @ApiModelProperty(value = "Device identifier of the device needed to be assigned with group") + @JsonProperty("deviceIdentifier") + private DeviceIdentifier deviceIdentifier; + + + public List getDeviceGroupIds() { + return deviceGroupIds; + } + + public void setDeviceGroupIds(List deviceGroupIds) { + this.deviceGroupIds = deviceGroupIds; + } + + public DeviceIdentifier getDeviceIdentifier() { + return deviceIdentifier; + } + + public void setDeviceIdentifier(DeviceIdentifier deviceIdentifier) { + this.deviceIdentifier = deviceIdentifier; + } + +} 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 a982a3c3d5..9d1b255e96 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 @@ -37,6 +37,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; @@ -774,4 +775,115 @@ public interface GroupManagementService { required = true) @Valid List deviceIdentifiers); + @Path("/device/assign") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Assign devices to groups", + notes = "Add existing device to device groups.", + tags = "Device Group Management", + authorizations = { + @Authorization( + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/groups/devices/add", + description = "Add devices")} + ) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully assign the device to groups.", + 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 = "No groups 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 adding devices to the group.", + response = ErrorResponse.class) + }) + Response updateDeviceAssigningToGroups( + @ApiParam( + name = "deviceToGroupsAssignment", + value = "Device to groups assignment", + required = true) + @Valid DeviceToGroupsAssignment deviceToGroupsAssignment); + + @Path("/device") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "List of groups that have the device", + notes = "List of groups that have the device.", + tags = "Device Group Management", + authorizations = { + @Authorization( + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/groups/devices/view", + description = "Add devices")} + ) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK.", + 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 = "No groups 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.", + response = ErrorResponse.class) + }) + Response getGroups( + @ApiParam( + name = "deviceId", + value = "Id of the device.") + @QueryParam("deviceId") String deviceId, + @ApiParam( + name = "deviceType", + value = "Type of the device.") + @QueryParam("deviceType") String deviceType); + } 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 4d7f4319fa..4811e9b902 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 @@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.Device; @@ -35,12 +36,14 @@ import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import javax.ws.rs.core.Response; +import java.util.ArrayList; import java.util.List; public class GroupManagementServiceImpl implements GroupManagementService { @@ -243,7 +246,8 @@ public class GroupManagementServiceImpl implements GroupManagementService { } } - @Override public Response removeDevicesFromGroup(int groupId, List deviceIdentifiers) { + @Override + public Response removeDevicesFromGroup(int groupId, List deviceIdentifiers) { try { DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers); return Response.status(Response.Status.OK).build(); @@ -256,4 +260,45 @@ public class GroupManagementServiceImpl implements GroupManagementService { } } + @Override + public Response updateDeviceAssigningToGroups(DeviceToGroupsAssignment deviceToGroupsAssignment) { + try { + List deviceIdentifiers = new ArrayList<>(); + deviceIdentifiers.add(deviceToGroupsAssignment.getDeviceIdentifier()); + GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); + List deviceGroups = service.getGroups(deviceToGroupsAssignment.getDeviceIdentifier()); + for (DeviceGroup group : deviceGroups) { + Integer groupId = group.getGroupId(); + if (deviceToGroupsAssignment.getDeviceGroupIds().contains(groupId)) { + deviceToGroupsAssignment.getDeviceGroupIds().remove(groupId); + } else if (!CarbonConstants.REGISTRY_SYSTEM_USERNAME.equals(group.getOwner())) { + DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers); + } + } + for (int groupId : deviceToGroupsAssignment.getDeviceGroupIds()) { + DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers); + } + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while assigning device to groups."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceNotFoundException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Override + public Response getGroups(String deviceId, String deviceType) { + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); + List deviceGroups = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(deviceIdentifier); + return Response.status(Response.Status.OK).entity(deviceGroups).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while removing devices from group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.hbs index 2b50aa21c3..863c85842f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.hbs @@ -233,17 +233,7 @@ - - -
- diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js index 9121f1d3a9..d5457db01f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js @@ -261,7 +261,7 @@ function loadDevices(searchType, searchParam) { return '
'; + row.deviceType) + '"/>
'; } }, { @@ -347,31 +347,31 @@ function loadDevices(searchType, searchParam) { if ((!groupName || !groupId) && groupingEnabled(row.deviceType)) { html += - '' + - '' + - ''; + '' + + '' + + ''; } html += - '' + - '' + - '' + - ''; + '' + + '' + + '' + + ''; html += - '' + - '' + - '' + - ''; + '' + + '' + + '' + + ''; } return html; } @@ -427,16 +427,16 @@ function loadDevices(searchType, searchParam) { $(data.devices).each(function (index) { objects.push( - { - model: getPropertyValue(data.devices[index].properties, "DEVICE_MODEL"), - vendor: getPropertyValue(data.devices[index].properties, "VENDOR"), - user: data.devices[index].enrolmentInfo.owner, - status: data.devices[index].enrolmentInfo.status, - ownership: data.devices[index].enrolmentInfo.ownership, - deviceType: data.devices[index].type, - deviceIdentifier: data.devices[index].deviceIdentifier, - name: data.devices[index].name - } + { + model: getPropertyValue(data.devices[index].properties, "DEVICE_MODEL"), + vendor: getPropertyValue(data.devices[index].properties, "VENDOR"), + user: data.devices[index].enrolmentInfo.owner, + status: data.devices[index].enrolmentInfo.status, + ownership: data.devices[index].enrolmentInfo.ownership, + deviceType: data.devices[index].type, + deviceIdentifier: data.devices[index].deviceIdentifier, + name: data.devices[index].name + } ); }); @@ -449,20 +449,20 @@ function loadDevices(searchType, searchParam) { }; $('#device-grid').datatables_extended_serverside_paging( - null, - serviceURL, - dataFilter, - columns, - fnCreatedRow, - function () { - $(".icon .text").res_text(0.2); - $('#device-grid').removeClass('hidden'); - $("#loading-content").remove(); - attachDeviceEvents(); - }, { - "placeholder": "Search By Device Name", - "searchKey": "name" - } + null, + serviceURL, + dataFilter, + columns, + fnCreatedRow, + function () { + $(".icon .text").res_text(0.2); + $('#device-grid').removeClass('hidden'); + $("#loading-content").remove(); + attachDeviceEvents(); + }, { + "placeholder": "Search By Device Name", + "searchKey": "name" + } ); $(deviceCheckbox).click(function () { @@ -556,6 +556,34 @@ function hidePopup() { $('.modal-backdrop').remove(); } +function markAlreadyAssignedGroups(deviceId, deviceType) { + var successCallback = function (data, textStatus, xhr) { + data = JSON.parse(data); + if (xhr.status == 200) { + if (data.length > 0) { + for (var i = 0; i < data.length; i++) { + $('.groupCheckBoxes').each( + function () { + if (data[i].id == $(this).data('groupid')) { + $(this).attr('checked', true); + } + } + ); + } + } else { + return; + } + } else { + displayErrors(xhr); + } + }; + + invokerUtil.get("/api/device-mgt/v1.0/groups/device?deviceId=" + deviceId + "&deviceType=" + deviceType, + successCallback, function (message) { + displayErrors(message); + }); +} + /** * Following functions should be triggered after AJAX request is made. */ @@ -572,33 +600,48 @@ function attachDeviceEvents() { var deviceType = $(this).data("devicetype"); $(modalPopupContent).html($('#group-device-modal-content').html()); $('#user-groups').html( - '
'); + '
'); $("a#group-device-yes-link").hide(); showPopup(); var serviceURL; if ($.hasPermission("LIST_ALL_GROUPS")) { - serviceURL = "/api/device-mgt/v1.0/groups"; + serviceURL = "/api/device-mgt/v1.0/admin/groups?limit=100"; } else if ($.hasPermission("LIST_GROUPS")) { //Get authenticated users groups - serviceURL = "/api/device-mgt/v1.0/groups/user/" + currentUser + "/all"; + serviceURL = "/api/device-mgt/v1.0/groups?limit=100"; } invokerUtil.get(serviceURL, function (data) { var groups = JSON.parse(data); - var str = '
' + + '' + groups.deviceGroups[i].name + + ''; + } } - str += ''; - $('#user-groups').html(str); + $('#user-groups').html(html); + markAlreadyAssignedGroups(deviceId, deviceType); $("a#group-device-yes-link").show(); $("a#group-device-yes-link").click(function () { - var selectedGroup = $('#assign-group-selector').val(); - serviceURL = "/api/device-mgt/v1.0/groups/id/" + selectedGroup + "/devices/add"; - var deviceIdentifiers = [{"id": deviceId, "type": deviceType}]; - invokerUtil.post(serviceURL, deviceIdentifiers, function (data) { + var deviceIdentifier = {"id": deviceId, "type": deviceType}; + var deviceGroupIds = []; + $('.modal .groupCheckBoxes').each( + function () { + if ($(this).is(':checked')) { + deviceGroupIds.push($(this).data('groupid')); + } + } + ); + var deviceToGroupsAssignment = { + deviceIdentifier: deviceIdentifier, + deviceGroupIds: deviceGroupIds + }; + serviceURL = "/api/device-mgt/v1.0/groups/device/assign"; + invokerUtil.post(serviceURL, deviceToGroupsAssignment, function (data) { $(modalPopupContent).html($('#group-associate-device-200-content').html()); setTimeout(function () { hidePopup(); @@ -640,8 +683,8 @@ function attachDeviceEvents() { showPopup(); $("a#remove-device-yes-link").click(function () { - if(groupId && groupName) { - var deviceIdentifiers = [{"id": deviceId,"type": deviceType}]; + if (groupId && groupName) { + var deviceIdentifiers = [{"id": deviceId, "type": deviceType}]; serviceURL = "/api/device-mgt/v1.0/groups/id/" + groupId + "/devices/remove"; invokerUtil.post(serviceURL, deviceIdentifiers, function (message) { $(modalPopupContent).html($('#remove-device-from-group-200-content').html()); @@ -733,6 +776,6 @@ function displayDeviceErrors(jqXHR) { function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), - results = regex.exec(location.search); + results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs index 08ab1c8095..5069d083d4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs @@ -16,26 +16,44 @@ under the License. }} -
-
- Device Types +{{#if virtualDeviceTypesList}} +
+
+ Device Types +
-
- -
- - - - - - - - - - -
By Device Type
-
+
+ + + + + + + + + + +
By Device Type
+
+{{else}} +
+{{/if}}
{{#if virtualDeviceTypesList}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js index 62ca011b0b..1e1cefcb83 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js @@ -29,6 +29,9 @@ function onRequest(context) { if (typesListResponse["status"] == "success") { var deviceTypes = typesListResponse.content.deviceTypes; if (deviceTypes) { + if (deviceTypes.length > 0){ + viewModel.hasDeviceTypes = true; + } var deviceTypesList = [], virtualDeviceTypesList = []; for (var i = 0; i < deviceTypes.length; i++) { var deviceType = deviceTypes[i]; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/public/js/listing.js index 1fbbe479c2..ba9a4be94a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/public/js/listing.js @@ -142,13 +142,6 @@ function loadDevices(searchType, searchParam){ } } else { $('#device-type-grid').addClass('hidden'); - $('#device-listing-status-msg').html( - '

' + - '

No device type is available to be displayed.

' + - '' + - ' ' + - 'Quick Startup Guide
'); } $(".icon .text").res_text(0.2);