diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionInfo.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionInfo.java new file mode 100644 index 0000000000..648e8585f9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionInfo.java @@ -0,0 +1,52 @@ +/* Copyright (c) 2020, 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 org.wso2.carbon.device.application.mgt.common; + +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.ArrayList; +import java.util.List; + +public class ApplicationSubscriptionInfo { + + List devices; + List subscribers; + List errorDeviceIdentifiers; + String appSupportingDeviceTypeName; + + public List getDevices() { return devices; } + + public void setDevices(List devices) { this.devices = devices; } + + public List getSubscribers() { return subscribers; } + + public void setSubscribers(List subscribers) { this.subscribers = subscribers; } + + public List getErrorDeviceIdentifiers() { return errorDeviceIdentifiers; } + + public void setErrorDeviceIdentifiers(List errorDeviceIdentifiers) { + this.errorDeviceIdentifiers = errorDeviceIdentifiers; + } + + public String getAppSupportingDeviceTypeName() { return appSupportingDeviceTypeName; } + + public void setAppSupportingDeviceTypeName(String appSupportingDeviceTypeName) { + this.appSupportingDeviceTypeName = appSupportingDeviceTypeName; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java index 47545d4c83..c844ddaf08 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -29,6 +29,7 @@ import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationSubscriptionInfo; import org.wso2.carbon.device.application.mgt.common.ApplicationType; import org.wso2.carbon.device.application.mgt.common.DeviceSubscriptionData; import org.wso2.carbon.device.application.mgt.common.DeviceTypes; @@ -76,7 +77,6 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.ActivityStatus; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; -import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; @@ -108,7 +108,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { private LifecycleStateManager lifecycleStateManager; public SubscriptionManagerImpl() { - lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); + this.lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); } @@ -120,84 +120,16 @@ public class SubscriptionManagerImpl implements SubscriptionManager { log.debug("Install application release which has UUID " + applicationUUID + " to " + params.size() + " users."); } - try { - validateRequest(params, subType, action); - DeviceManagementProviderService deviceManagementProviderService = HelperUtil - .getDeviceManagementProviderService(); - GroupManagementProviderService groupManagementProviderService = HelperUtil - .getGroupManagementProviderService(); - String deviceTypeName = null; - List devices = new ArrayList<>(); - List subscribers = new ArrayList<>(); - List errorDeviceIdentifiers = new ArrayList<>(); - ApplicationInstallResponse applicationInstallResponse; - - //todo validate users, groups and roles - ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); - if (SubscriptionType.DEVICE.toString().equals(subType)) { - for (T param : params) { - DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param; - if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils - .isEmpty(deviceIdentifier.getType())) { - log.warn("Found a device identifier which has either empty identity of the device or empty" - + " device type. Hence ignoring the device identifier. "); - continue; - } - if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { - DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - if (!deviceType.getName().equals(deviceIdentifier.getType())) { - log.warn("Found a device identifier which is not matched with the supported device type " - + "of the application release which has UUID " + applicationUUID + " Application " - + "supported device type is " + deviceType.getName() + " and the " - + "identifier of which has a different device type is " + deviceIdentifier.getId()); - errorDeviceIdentifiers.add(deviceIdentifier); - continue; - } - } - devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false)); - } - } else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { - for (T param : params) { - String username = (String) param; - subscribers.add(username); - devices.addAll(deviceManagementProviderService.getDevicesOfUser(username)); - } - } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { - for (T param : params) { - String roleName = (String) param; - subscribers.add(roleName); - devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName)); - } - } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { - for (T param : params) { - String groupName = (String) param; - subscribers.add(groupName); - devices.addAll(groupManagementProviderService.getAllDevicesOfGroup(groupName, true)); - } - } - if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType()) && !SubscriptionType.DEVICE - .toString().equals(subType)) { - DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - deviceTypeName = deviceType.getName(); - //filter devices by device type - String tmpDeviceTypeName = deviceTypeName; - devices.removeIf(device -> !tmpDeviceTypeName.equals(device.getType())); - } + validateRequest(params, subType, action); + //todo validate users, groups and roles + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + ApplicationSubscriptionInfo applicationSubscriptionInfo = getAppSubscriptionInfo(applicationDTO, subType, params); + ApplicationInstallResponse applicationInstallResponse = performActionOnDevices(applicationSubscriptionInfo.getAppSupportingDeviceTypeName(), + applicationSubscriptionInfo.getDevices(), applicationDTO, subType, applicationSubscriptionInfo.getSubscribers(), action); - applicationInstallResponse = performActionOnDevices(deviceTypeName, devices, applicationDTO, - subType, subscribers, action); - applicationInstallResponse.setErrorDeviceIdentifiers(errorDeviceIdentifiers); - return applicationInstallResponse; - } catch (DeviceManagementException e) { - String msg = "Error occurred while getting devices of given users or given roles."; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } catch (GroupManagementException e) { - String msg = "Error occurred while getting devices of given groups"; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } + applicationInstallResponse.setErrorDeviceIdentifiers(applicationSubscriptionInfo.getErrorDeviceIdentifiers()); + return applicationInstallResponse; } @Override @@ -321,141 +253,73 @@ public class SubscriptionManagerImpl implements SubscriptionManager { @Override public void performEntAppSubscription(String applicationUUID, List params, String subType, String action, - boolean requiresUpdatingExternal) - throws ApplicationManagementException { + boolean requiresUpdatingExternal) throws ApplicationManagementException { if (log.isDebugEnabled()) { - log.debug("Google Ent app Install operation is received to application which has UUID " - + applicationUUID + " to perform on " + params.size() + " params."); + log.debug("Google Ent app Install operation is received to application which has UUID " + applicationUUID + + " to perform on " + params.size() + " params."); + } + if (params.isEmpty()) { + String msg = "In order to subscribe/unsubscribe application release, you should provide list of " + + "subscribers. But found an empty list of subscribers."; + log.error(msg); + throw new BadRequestException(msg); } - try { - if (params.isEmpty()) { - String msg = "In order to subscribe/unsubscribe application release, you should provide list of " - + "subscribers. But found an empty list of subscribers."; - log.error(msg); - throw new BadRequestException(msg); - } - - ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); - ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - int applicationReleaseId = applicationReleaseDTO.getId(); - if (!ApplicationType.PUBLIC.toString().equals(applicationDTO.getType())) { - String msg = "Application type is not public. Hence you can't perform google ent.install operation on " - + "this application. Application name " + applicationDTO.getName() + " Application Type " - + applicationDTO.getType(); - log.error(msg); - throw new BadRequestException(msg); - } - - List categories = getApplicationCategories(applicationDTO.getId()); - if (!categories.contains("GooglePlaySyncedApp")) { - String msg = "This is not google play store synced application. Hence can't perform enterprise app " - + "installation."; - log.error(msg); - throw new BadRequestException(msg); - } - - DeviceManagementProviderService deviceManagementProviderService = HelperUtil - .getDeviceManagementProviderService(); - - List devices = new ArrayList<>(); - List subscribers = new ArrayList<>(); - List appSubscribingDeviceIds; - List appReSubscribingDeviceIds = new ArrayList<>(); - List deviceIdentifiers = new ArrayList<>(); - //todo validate users, groups and roles - if (SubscriptionType.DEVICE.toString().equals(subType)) { - DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - for (T param : params) { - DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param; - if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils - .isEmpty(deviceIdentifier.getType())) { - log.warn("Found a device identifier which has either empty identity of the device or empty" - + " device type. Hence ignoring the device identifier. "); - continue; - } - if (!deviceType.getName().equals(deviceIdentifier.getType())) { - log.warn("Found a device identifier which is not matched with the supported device type " - + "of the application release which has UUID " + applicationUUID + " Application " - + "supported device type is " + deviceType.getName() + " and the " - + "identifier of which has a different device type is " + deviceIdentifier.getId()); - continue; - } - deviceIdentifiers.add(deviceIdentifier); - devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false)); - } - } else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { - for (T param : params) { - String username = (String) param; - subscribers.add(username); - devices.addAll(deviceManagementProviderService.getDevicesOfUser(username)); - } - } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { - for (T param : params) { - String roleName = (String) param; - subscribers.add(roleName); - devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName)); - } - } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { - GroupManagementProviderService groupManagementProviderService = HelperUtil - .getGroupManagementProviderService(); - for (T param : params) { - String groupName = (String) param; - subscribers.add(groupName); - devices.addAll(groupManagementProviderService.getAllDevicesOfGroup(groupName, false)); - } - } else { - String msg = "Found invalid subscription type " + subType+ " to install application release" ; - log.error(msg); - throw new BadRequestException(msg); - } + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + int applicationReleaseId = applicationReleaseDTO.getId(); + if (!ApplicationType.PUBLIC.toString().equals(applicationDTO.getType())) { + String msg = "Application type is not public. Hence you can't perform google ent.install operation on " + + "this application. Application name " + applicationDTO.getName() + " Application Type " + + applicationDTO.getType(); + log.error(msg); + throw new BadRequestException(msg); + } - /*If subscription type is not device we need to crete device identifiers object list by referring retrieved - list of devices.*/ - if (!SubscriptionType.DEVICE.toString().equalsIgnoreCase(subType)) { - DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - String deviceTypeName = deviceType.getName(); - //filter devices by device type - devices.removeIf(device -> !deviceTypeName.equals(device.getType())); - devices.forEach(device -> { - DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); - deviceIdentifier.setId(device.getDeviceIdentifier()); - deviceIdentifier.setType(device.getType()); - deviceIdentifiers.add(deviceIdentifier); - }); - } + List categories = getApplicationCategories(applicationDTO.getId()); + if (!categories.contains("GooglePlaySyncedApp")) { + String msg = "This is not google play store synced application. Hence can't perform enterprise app " + + "installation."; + log.error(msg); + throw new BadRequestException(msg); + } - if (requiresUpdatingExternal) { - //Installing the application - ApplicationPolicyDTO applicationPolicyDTO = new ApplicationPolicyDTO(); - applicationPolicyDTO.setApplicationDTO(applicationDTO); - applicationPolicyDTO.setDeviceIdentifierList(deviceIdentifiers); - applicationPolicyDTO.setAction(action.toUpperCase()); - installEnrollmentApplications(applicationPolicyDTO); - } + List appReSubscribingDeviceIds = new ArrayList<>(); + List deviceIdentifiers = new ArrayList<>(); - appSubscribingDeviceIds = devices.stream().map(Device::getId).collect(Collectors.toList()); - Map deviceSubscriptions = getDeviceSubscriptions(appSubscribingDeviceIds, - applicationReleaseId); - for (Map.Entry deviceSubscription: deviceSubscriptions.entrySet()){ - appReSubscribingDeviceIds.add(deviceSubscription.getKey()); - appSubscribingDeviceIds.remove(deviceSubscription.getKey()); - } + ApplicationSubscriptionInfo applicationSubscriptionInfo = getAppSubscriptionInfo(applicationDTO, subType, + params); + applicationSubscriptionInfo.getDevices().forEach(device -> { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(device.getDeviceIdentifier()); + deviceIdentifier.setType(device.getType()); + deviceIdentifiers.add(deviceIdentifier); + }); + + if (requiresUpdatingExternal) { + //Installing the application + ApplicationPolicyDTO applicationPolicyDTO = new ApplicationPolicyDTO(); + applicationPolicyDTO.setApplicationDTO(applicationDTO); + applicationPolicyDTO.setDeviceIdentifierList(deviceIdentifiers); + applicationPolicyDTO.setAction(action.toUpperCase()); + installEnrollmentApplications(applicationPolicyDTO); + } - updateSubscriptionsForEntInstall(applicationReleaseId, appSubscribingDeviceIds, appReSubscribingDeviceIds, - subscribers, subType, action); - } catch (DeviceManagementException e) { - String msg = "Error occurred while getting devices of given users or given roles."; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } catch (GroupManagementException e) { - String msg = "Error occurred while getting devices of given groups"; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); + List appSubscribingDeviceIds = applicationSubscriptionInfo.getDevices().stream().map(Device::getId) + .collect(Collectors.toList()); + Map deviceSubscriptions = getDeviceSubscriptions(appSubscribingDeviceIds, + applicationReleaseId); + for (Map.Entry deviceSubscription : deviceSubscriptions.entrySet()) { + appReSubscribingDeviceIds.add(deviceSubscription.getKey()); + appSubscribingDeviceIds.remove(deviceSubscription.getKey()); } + + updateSubscriptionsForEntInstall(applicationReleaseId, appSubscribingDeviceIds, appReSubscribingDeviceIds, + applicationSubscriptionInfo.getSubscribers(), subType, action); } - @Override public void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUIDs) + @Override + public void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUIDs) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -519,6 +383,105 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + /** + * Gets Application subscribing info by using requesting params + * + * @param applicationDTO Application DTO + * @param params list of subscribers. This list can be of either + * {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is equal + * to DEVICE or + * {@link String} if {@param subType} is USER, ROLE or GROUP + * @param subType subscription type. E.g. DEVICE, USER, ROLE, GROUP {@see { + * @param generic type of the method. + * @return {@link ApplicationSubscriptionInfo} + * @throws ApplicationManagementException if error occurred while getting Application subscription info + */ + private ApplicationSubscriptionInfo getAppSubscriptionInfo(ApplicationDTO applicationDTO, String subType, + List params) throws ApplicationManagementException { + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); + List devices = new ArrayList<>(); + List subscribers = new ArrayList<>(); + List errorDeviceIdentifiers = new ArrayList<>(); + String deviceTypeName = null; + + try { + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { + deviceTypeName = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()).getName(); + } + + if (SubscriptionType.DEVICE.toString().equals(subType)) { + for (T param : params) { + DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param; + if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils + .isEmpty(deviceIdentifier.getType())) { + log.warn("Found a device identifier which has either empty identity of the device or empty" + + " device type. Hence ignoring the device identifier. "); + continue; + } + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType()) && !deviceIdentifier + .getType().equals(deviceTypeName)) { + log.warn("Found a device identifier which is not matched with the supported device type " + + "of the application release which has UUID " + applicationDTO + .getApplicationReleaseDTOs().get(0).getUuid() + " Application " + + "supported device type is " + deviceTypeName + " and the identifier of which has a " + + "different device type is " + deviceIdentifier.getId()); + errorDeviceIdentifiers.add(deviceIdentifier); + continue; + } + devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false)); + } + } else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String username = (String) param; + subscribers.add(username); + devices.addAll(deviceManagementProviderService.getDevicesOfUser(username)); + } + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String roleName = (String) param; + subscribers.add(roleName); + devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName)); + } + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String groupName = (String) param; + subscribers.add(groupName); + devices.addAll(groupManagementProviderService.getAllDevicesOfGroup(groupName, true)); + } + } else { + String msg = "Found invalid subscription type " + subType+ " to install application release" ; + log.error(msg); + throw new BadRequestException(msg); + } + + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType()) && !SubscriptionType.DEVICE + .toString().equals(subType)) { + //filter devices by device type + String tmpDeviceTypeName = deviceTypeName; + devices.removeIf(device -> !tmpDeviceTypeName.equals(device.getType())); + } + + ApplicationSubscriptionInfo applicationSubscriptionInfo = new ApplicationSubscriptionInfo(); + applicationSubscriptionInfo.setDevices(devices); + applicationSubscriptionInfo.setSubscribers(subscribers); + applicationSubscriptionInfo.setErrorDeviceIdentifiers(errorDeviceIdentifiers); + applicationSubscriptionInfo.setAppSupportingDeviceTypeName(deviceTypeName); + return applicationSubscriptionInfo; + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting devices of given users or given roles or while getting device " + + "type info."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting devices of given groups"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + /** * This method is responsible to update subscription data for google enterprise install. * @@ -567,8 +530,6 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } - - /** * THis method is responsible to validate application install or uninstall request. * @@ -588,7 +549,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { boolean isValidSubType = Arrays.stream(SubscriptionType.values()) .anyMatch(sub -> sub.name().equalsIgnoreCase(subType)); if (!isValidSubType) { - String msg = "Found invalid subscription type " + subType+ " to install application release" ; + String msg = "Found invalid subscription type " + subType+ " to subscribe application release" ; log.error(msg); throw new BadRequestException(msg); } @@ -618,8 +579,10 @@ public class SubscriptionManagerImpl implements SubscriptionManager { ApplicationDTO applicationDTO, String subType, List subscribers, String action) throws ApplicationManagementException { + //Get app subscribing info of each device SubscribingDeviceIdHolder subscribingDeviceIdHolder = getSubscribingDeviceIdHolder(devices, applicationDTO.getApplicationReleaseDTOs().get(0).getId()); + List activityList = new ArrayList<>(); List deviceIdentifiers = new ArrayList<>(); List ignoredDeviceIdentifiers = new ArrayList<>(); @@ -704,14 +667,12 @@ public class SubscriptionManagerImpl implements SubscriptionManager { || Operation.Status.IN_PROGRESS.toString().equals(deviceSubscriptionDTO.getStatus())) { subscribingDeviceIdHolder.getSkippedDevices().put(deviceIdentifier, device.getId()); } else if (deviceSubscriptionDTO.isUnsubscribed()) { - if (Operation.Status.COMPLETED.toString().equals(deviceSubscriptionDTO.getStatus())) { - subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); - } else { + if (!Operation.Status.COMPLETED.toString().equals(deviceSubscriptionDTO.getStatus())) { /*We can't ensure whether app is uninstalled successfully or not hence allow to perform both install and uninstall operations*/ subscribingDeviceIdHolder.getAppReUnInstallableDevices().put(deviceIdentifier, device.getId()); - subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); } + subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); } else if (!deviceSubscriptionDTO.isUnsubscribed() && Operation.Status.COMPLETED.toString() .equals(deviceSubscriptionDTO.getStatus())) { subscribingDeviceIdHolder.getAppInstalledDevices().put(deviceIdentifier, device.getId()); @@ -1126,8 +1087,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, - String status) + public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, String status) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); DeviceManagementProviderService deviceManagementProviderService = HelperUtil diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java index bcfd052326..fcc7698169 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java @@ -20,24 +20,20 @@ package org.wso2.carbon.device.application.mgt.core.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; -import java.util.List; -import java.util.UUID; - /** * Utility methods used in the Application Management. */ public class HelperUtil { - private static Log log = LogFactory.getLog(HelperUtil.class); + private static final Log log = LogFactory.getLog(HelperUtil.class); private static DeviceManagementProviderService deviceManagementProviderService; private static GroupManagementProviderService groupManagementProviderService; - public static DeviceManagementProviderService getDeviceManagementProviderService() { + public static synchronized DeviceManagementProviderService getDeviceManagementProviderService() { if (deviceManagementProviderService == null) { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); deviceManagementProviderService = (DeviceManagementProviderService) ctx @@ -51,7 +47,7 @@ public class HelperUtil { return deviceManagementProviderService; } - public static GroupManagementProviderService getGroupManagementProviderService() { + public static synchronized GroupManagementProviderService getGroupManagementProviderService() { if (groupManagementProviderService == null) { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); groupManagementProviderService = (GroupManagementProviderService) ctx diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index 49eae0fc0d..21144caacf 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -17,14 +17,10 @@ "acorn": "^6.2.0", "antd": "^4.0.0", "axios": "^0.19.0", - "babel-eslint": "^9.0.0", + "babel-eslint": "^10.1.0", "d3": "^5.9.7", "dagre": "^0.8.4", "entgra-icons-react": "^1.0.0", - "eslint": "^5.16.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.16.0", "fetch": "^1.1.0", "imagemin": "^6.1.0", "keymirror": "^0.1.1", @@ -64,7 +60,9 @@ "eslint": "^5.16.0", "eslint-config-prettier": "4.3.0", "eslint-plugin-babel": "5.3.0", + "eslint-plugin-import": "^2.21.2", "eslint-plugin-jsx": "0.0.2", + "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-prettier": "3.1.0", "eslint-plugin-react": "7.14.2", "express": "^4.17.1", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json index 91b0a4158b..7f84052960 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json @@ -13,7 +13,7 @@ "acorn": "^6.2.0", "antd": "^4.0.0", "axios": "^0.18.1", - "babel-eslint": "^9.0.0", + "babel-eslint": "^10.1.0", "d3": "^5.9.7", "dagre": "^0.8.4", "imagemin": "^5.3.1", 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 73a07b7aad..bd04c963bd 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 @@ -504,15 +504,13 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { return Response.status(Response.Status.OK).entity(device).build(); } - @Path("/{deviceType}/{deviceId}/location-history") @GET - public Response getDeviceLocationInfo(@PathParam("deviceType") String deviceType, - @PathParam("deviceId") String deviceId, - @QueryParam("from") long from, @QueryParam("to") long to) { - - String errorMessage; - DeviceLocationHistory deviceLocationHistory = new DeviceLocationHistory(); - + @Path("/{deviceType}/{deviceId}/location-history") + public Response getDeviceLocationInfo( + @PathParam("deviceType") String deviceType, + @PathParam("deviceId") String deviceId, + @QueryParam("from") long from, + @QueryParam("to") long to) { try { RequestValidationUtil.validateDeviceIdentifier(deviceType, deviceId); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); @@ -520,81 +518,81 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); - deviceIdentifier.setId(deviceId); - deviceIdentifier.setType(deviceType); if (!deviceAccessAuthorizationService.isUserAuthorized(deviceIdentifier, authorizedUser)) { String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + deviceId + "'"; log.error(msg); - return Response.status(Response.Status.UNAUTHORIZED).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + return Response.status(Response.Status.UNAUTHORIZED).entity(new ErrorResponse.ErrorResponseBuilder() + .setCode(Response.Status.UNAUTHORIZED.getStatusCode()).setMessage(msg).build()).build(); } if (from == 0 || to == 0) { - errorMessage = "Invalid values for from/to"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage)).build(); + String msg = "Invalid values for from/to"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse.ErrorResponseBuilder() + .setCode(Response.Status.BAD_REQUEST.getStatusCode()).setMessage(msg)).build(); } - List> locationHistorySnapshotList = new ArrayList<>(); // Get the location history snapshots for the given period - List deviceLocationHistorySnapshots = dms.getDeviceLocationInfo(deviceIdentifier, from, to); + List deviceLocationHistorySnapshots = dms + .getDeviceLocationInfo(deviceIdentifier, from, to); OperationMonitoringTaskConfig operationMonitoringTaskConfig = dms.getDeviceMonitoringConfig(deviceType); int taskFrequency = operationMonitoringTaskConfig.getFrequency(); int operationRecurrentTimes = 0; List monitoringOperations = operationMonitoringTaskConfig.getMonitoringOperation(); - for (MonitoringOperation monitoringOperation : - monitoringOperations) { + for (MonitoringOperation monitoringOperation : monitoringOperations) { if (monitoringOperation.getTaskName().equals("DEVICE_LOCATION")) { operationRecurrentTimes = monitoringOperation.getRecurrentTimes(); break; } } + // Device Location operation frequency in milliseconds. Adding 100000 ms as an error long operationFrequency = taskFrequency * operationRecurrentTimes + 100000; + Queue deviceLocationHistorySnapshotsQueue = new LinkedList<>( + deviceLocationHistorySnapshots); + List> locationHistorySnapshotList = new ArrayList<>(); - Queue deviceLocationHistorySnapshotsQueue = new LinkedList<>(deviceLocationHistorySnapshots); - - while (deviceLocationHistorySnapshotsQueue.size() > 0) { + while (!deviceLocationHistorySnapshotsQueue.isEmpty()) { List snapshots = new ArrayList<>(); // Make a copy of remaining snapshots - List cachedSnapshots = new ArrayList<>(deviceLocationHistorySnapshotsQueue); + List cachedSnapshots = new ArrayList<>( + deviceLocationHistorySnapshotsQueue); for (int i = 0; i < cachedSnapshots.size(); i++) { DeviceLocationHistorySnapshot currentSnapshot = deviceLocationHistorySnapshotsQueue.poll(); snapshots.add(currentSnapshot); - if (deviceLocationHistorySnapshotsQueue.size() > 0) { + if (!deviceLocationHistorySnapshotsQueue.isEmpty()) { DeviceLocationHistorySnapshot nextSnapshot = deviceLocationHistorySnapshotsQueue.peek(); - if (nextSnapshot.getUpdatedTime().getTime() - currentSnapshot.getUpdatedTime().getTime() > operationFrequency) { + if (nextSnapshot.getUpdatedTime().getTime() - currentSnapshot.getUpdatedTime().getTime() + > operationFrequency) { break; } } } locationHistorySnapshotList.add(snapshots); } + DeviceLocationHistory deviceLocationHistory = new DeviceLocationHistory(); deviceLocationHistory.setLocationHistorySnapshots(locationHistorySnapshotList); - - + return Response.status(Response.Status.OK).entity(deviceLocationHistory).build(); } catch (DeviceManagementException e) { - errorMessage = "Error occurred while fetching the device information."; - log.error(errorMessage, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build()).build(); + String msg = "Error occurred while fetching the device information."; + log.error(msg, e); + return Response.serverError().entity(new ErrorResponse.ErrorResponseBuilder() + .setCode(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).setMessage(msg).build()).build(); } catch (DeviceAccessAuthorizationException e) { - errorMessage = "Error occurred while checking the device authorization."; - log.error(errorMessage, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build()).build(); - } catch (InputValidationException e){ - errorMessage = "Invalid device Id or device type"; - log.error(errorMessage, e); - return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage)).build(); + String msg = "Error occurred while checking the device authorization."; + log.error(msg, e); + return Response.serverError().entity(new ErrorResponse.ErrorResponseBuilder() + .setCode(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).setMessage(msg).build()).build(); + } catch (InputValidationException e) { + String msg = "Invalid device Id or device type"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse.ErrorResponseBuilder() + .setCode(Response.Status.BAD_REQUEST.getStatusCode()).setMessage(msg)).build(); } - return Response.status(Response.Status.OK).entity(deviceLocationHistory).build(); } @GET diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java index a9fc47691e..d58c4ce870 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java @@ -83,6 +83,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService { .validatePolicyDetails(policyWrapper); // validation failure results; if (!features.isEmpty()) { + log.error("Policy feature/s validation failed."); return Response.status(Response.Status.BAD_REQUEST).entity(features).build(); } PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); @@ -223,6 +224,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService { .validatePolicyDetails(policyWrapper); // validation failure results; if (!features.isEmpty()) { + log.error("Policy feature/s validation failed."); return Response.status(Response.Status.BAD_REQUEST).entity(features).build(); } PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); @@ -480,6 +482,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService { = RequestValidationUtil.validateProfileFeatures(profileFeaturesList); // validation failure results; if (!features.isEmpty()) { + log.error("Policy feature/s validation failed."); return Response.status(Response.Status.BAD_REQUEST).entity(features).build(); } return Response.status(Response.Status.OK).entity("Valid request").build(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java index 5553e02d22..d19e835848 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java @@ -47,10 +47,10 @@ public class GeoLocationBasedServiceImplTest { List geoClusters = new ArrayList<>(); geoClusters.add(new GeoCluster(new GeoCoordinate(1.5, 80.7), new GeoCoordinate(1.1, 79.5), new GeoCoordinate(1.9, 82.1), 3, - "tb32", "aegtew234", "android", "1234")); + "tb32", "aegtew234", "test1", "android", "1234")); geoClusters.add(new GeoCluster(new GeoCoordinate(10.2, 86.1), new GeoCoordinate(9.8, 84.7), new GeoCoordinate(11.1, 88.1), 4, - "t1gd", "swerty12s", "android", "1234")); + "t1gd", "swerty12s", "t2test", "android", "1234")); Mockito.doReturn(geoClusters).when(deviceManagementProviderService) .findGeoClusters(null, Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); Response response = geoLocationBasedService.getGeoDeviceLocations(null, 0.4, 15, 75.6, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationBean.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationBean.java new file mode 100644 index 0000000000..261d387e03 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationBean.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.device.details; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel( + value = "LocationBean", + description = "This class carries all information related IOS Device location." +) +public class LocationBean { + + @ApiModelProperty( + name = "latitude", + value = "Latitude of the IOS device Location.", + required = true + ) + private float latitude; + @ApiModelProperty( + name = "longitude", + value = "Longitude of the IOS device Location.", + required = true + ) + private float longitude; + @ApiModelProperty( + name = "operationId", + value = "Specific Id of the Location operation.", + required = true + ) + private String operationId; + + @ApiModelProperty( + name = "locationEvents", + value = "If this is a device initiated location publishing." + ) + private List locations; + + public List getLocationEvents() { + return locations; + } + + public void setLocationEvents(List locationEvents) { + this.locations = locationEvents; + } + + public String getOperationId() { + return operationId; + } + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + + public float getLatitude() { + return latitude; + } + + public void setLatitude(float latitude) { + this.latitude = latitude; + } + + public float getLongitude() { + return longitude; + } + + public void setLongitude(float longitude) { + this.longitude = longitude; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationEventBean.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationEventBean.java new file mode 100644 index 0000000000..6e1ef6c976 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/LocationEventBean.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.device.details; + +import io.swagger.annotations.ApiModelProperty; + +public class LocationEventBean { + + @ApiModelProperty( + name = "latitude", + value = "Latitude of the IOS device Location.", + required = true + ) + private String latitude; + + @ApiModelProperty( + name = "longitude", + value = "Longitude of the IOS device Location.", + required = true + ) + private String longitude; + + @ApiModelProperty( + name = "timestamp", + value = "Device Location time.", + required = true + ) + private String timestamp; + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 3d279928f6..a23346ac39 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -1733,6 +1733,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { " MAX(DEVICE_LOCATION.LONGITUDE) AS MAX_LONGITUDE," + " SUBSTRING(DEVICE_LOCATION.GEO_HASH,1,?) AS GEOHASH_PREFIX, COUNT(*) AS COUNT," + " MIN(DEVICE.DEVICE_IDENTIFICATION) AS DEVICE_IDENTIFICATION," + + " MIN(DEVICE.NAME) AS NAME," + " MIN(DEVICE_TYPE.NAME) AS TYPE, " + " MIN(DEVICE.LAST_UPDATED_TIMESTAMP) AS LAST_UPDATED_TIMESTAMP " + "FROM DM_DEVICE_LOCATION AS DEVICE_LOCATION,DM_DEVICE AS DEVICE, DM_DEVICE_TYPE AS DEVICE_TYPE " + @@ -1763,13 +1764,14 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { double min_longitude = rs.getDouble("MIN_LONGITUDE"); double max_longitude = rs.getDouble("MAX_LONGITUDE"); String device_identification = rs.getString("DEVICE_IDENTIFICATION"); + String device_name = rs.getString("NAME"); String device_type = rs.getString("TYPE"); String last_seen = rs.getString("LAST_UPDATED_TIMESTAMP"); long count = rs.getLong("COUNT"); String geohashPrefix = rs.getString("GEOHASH_PREFIX"); geoClusters.add(new GeoCluster(new GeoCoordinate(latitude, longitude), new GeoCoordinate(min_latitude, min_longitude), new GeoCoordinate(max_latitude, max_longitude), - count, geohashPrefix, device_identification, device_type, last_seen)); + count, geohashPrefix, device_identification, device_name, device_type, last_seen)); } } catch (SQLException e) { throw new DeviceManagementDAOException("Error occurred while retrieving information of " + @@ -1828,40 +1830,45 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } @Override - public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) - throws DeviceManagementDAOException { - - Connection conn; - PreparedStatement stmt = null; - ResultSet rs = null; + public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, + long to) throws DeviceManagementDAOException { List deviceLocationHistories = new ArrayList<>(); + String sql = "SELECT " + + "DEVICE_ID, " + + "TENANT_ID, " + + "DEVICE_ID_NAME, " + + "DEVICE_TYPE_NAME, " + + "LATITUDE, " + + "LONGITUDE, " + + "SPEED, " + + "HEADING, " + + "TIMESTAMP, " + + "GEO_HASH, " + + "DEVICE_OWNER, " + + "DEVICE_ALTITUDE, " + + "DISTANCE " + + "FROM DM_DEVICE_HISTORY_LAST_SEVEN_DAYS " + + "WHERE " + + "DEVICE_ID_NAME = ? AND " + + "DEVICE_TYPE_NAME = ? AND " + + "TIMESTAMP BETWEEN ? AND ?"; try { - conn = this.getConnection(); - - String sql = - "SELECT DEVICE_ID, TENANT_ID, DEVICE_ID_NAME, DEVICE_TYPE_NAME, LATITUDE, LONGITUDE, SPEED, " + - "HEADING, TIMESTAMP, GEO_HASH, DEVICE_OWNER, DEVICE_ALTITUDE, DISTANCE " + - "FROM DM_DEVICE_HISTORY_LAST_SEVEN_DAYS " + - "WHERE DEVICE_ID_NAME = ? " + - "AND DEVICE_TYPE_NAME = ? " + - "AND TIMESTAMP >= ? " + - "AND TIMESTAMP <= ?"; - - stmt = conn.prepareStatement(sql); - stmt.setString(1, deviceIdentifier.getId()); - stmt.setString(2, deviceIdentifier.getType()); - stmt.setLong(3, from); - stmt.setLong(4, to); - rs = stmt.executeQuery(); - while (rs.next()) { - deviceLocationHistories.add(DeviceManagementDAOUtil.loadDeviceLocation(rs)); + Connection conn = this.getConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, deviceIdentifier.getId()); + stmt.setString(2, deviceIdentifier.getType()); + stmt.setLong(3, from); + stmt.setLong(4, to); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + deviceLocationHistories.add(DeviceManagementDAOUtil.loadDeviceLocation(rs)); + } + } } } catch (SQLException e) { - String errMessage = "Error occurred while obtaining the DB connection to get device location information"; - log.error(errMessage, e); - throw new DeviceManagementDAOException(errMessage, e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, rs); + String msg = "Error occurred while obtaining the DB connection to get device location information"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } return deviceLocationHistories; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 63df06538d..f4bda81221 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -30,6 +30,8 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.impl.AbstractDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import org.wso2.carbon.device.mgt.core.geo.GeoCluster; +import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import java.sql.Connection; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index 7aa74a1f1c..1d0d9c246c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -968,6 +968,7 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { + ") AS GEOHASH_PREFIX, " + "COUNT(*) AS COUNT, " + "MIN(DEVICE.DEVICE_IDENTIFICATION) AS DEVICE_IDENTIFICATION, " + + "MIN(DEVICE.NAME) AS NAME, " + "MIN(DEVICE_TYPE.NAME) AS TYPE, " + "MIN(DEVICE.LAST_UPDATED_TIMESTAMP) AS LAST_UPDATED_TIMESTAMP, " + "COUNT(DEVICE_LOCATION.GEO_HASH) " @@ -1004,6 +1005,7 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { double min_longitude = rs.getDouble("MIN_LONGITUDE"); double max_longitude = rs.getDouble("MAX_LONGITUDE"); String device_identification = rs.getString("DEVICE_IDENTIFICATION"); + String device_name = rs.getString("NAME"); String device_type = rs.getString("TYPE"); String last_seen = rs.getString("LAST_UPDATED_TIMESTAMP"); long count = rs.getLong("COUNT"); @@ -1011,7 +1013,7 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { geoClusters.add(new GeoCluster(new GeoCoordinate(latitude, longitude), new GeoCoordinate(min_latitude, min_longitude), new GeoCoordinate(max_latitude, max_longitude), count, geohashPrefix, - device_identification, device_type, last_seen)); + device_identification, device_name, device_type, last_seen)); } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java index 6fa306f20b..e4838aaf6e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java @@ -9,18 +9,20 @@ public class GeoCluster { private long count; private String geohashPrefix; private String deviceIdentification; + private String deviceName; private String deviceType; private String lastSeen; public GeoCluster(GeoCoordinate coordinates, GeoCoordinate southWestBound, GeoCoordinate northEastBound, long count, - String geohashPrefix, String deviceIdentification, String deviceType, String lastSeen){ + String geohashPrefix, String deviceIdentification, String deviceName, String deviceType, String lastSeen){ this.coordinates=coordinates; this.southWestBound=southWestBound; this.northEastBound=northEastBound; this.count=count; this.geohashPrefix=geohashPrefix; this.deviceIdentification=deviceIdentification; + this.deviceName=deviceName; this.deviceType=deviceType; this.lastSeen = lastSeen; @@ -50,6 +52,10 @@ public class GeoCluster { return deviceIdentification; } + public String getDeviceName() { + return deviceName; + } + public String getDeviceType() { return deviceType; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java index 4c3690f5d0..44bb2a3064 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -20,15 +20,16 @@ package org.wso2.carbon.device.mgt.core.otp.mgt.dao; import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; +import java.util.List; + public interface OTPManagementDAO { /** * Save OTP token data and tenant details of registering user - * @param oneTimePinDTO OTPMailDTO - * @return Primary key of the newly adding data raw + * @param oneTimePinDTOList OTPMailDTO * @throws OTPManagementDAOException if error occurred whule storing data */ - int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException; + void addOTPData(List oneTimePinDTOList) throws OTPManagementDAOException; /** * Get OTP data for requesting One Time Token diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java index 273cf6c1a5..58b55197a0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -32,17 +32,20 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.util.Calendar; +import java.util.List; public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPManagementDAO { private static final Log log = LogFactory.getLog(GenericOTPManagementDAOImpl.class); @Override - public int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException { + public void addOTPData(List oneTimePinDTOList) throws OTPManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to create an OTP data entry"); log.debug("OTP Details : "); - log.debug("OTP key : " + oneTimePinDTO.getOtpToken() + " Email : " + oneTimePinDTO.getEmail()); + for(OneTimePinDTO oneTimePinDTO: oneTimePinDTOList){ + log.debug("OTP key : " + oneTimePinDTO.getOtpToken() + " Email : " + oneTimePinDTO.getEmail()); + } } String sql = "INSERT INTO DM_OTP_DATA " @@ -57,29 +60,25 @@ public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPM Connection conn = this.getDBConnection(); Calendar calendar = Calendar.getInstance(); Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); - try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - stmt.setString(1, oneTimePinDTO.getOtpToken()); - stmt.setString(2, oneTimePinDTO.getEmail()); - stmt.setString(3, oneTimePinDTO.getEmailType()); - stmt.setString(4, oneTimePinDTO.getMetaInfo()); - stmt.setTimestamp(5, timestamp); - stmt.setInt(6, oneTimePinDTO.getTenantId()); - stmt.setString(7, oneTimePinDTO.getUsername()); - stmt.executeUpdate(); - try (ResultSet rs = stmt.getGeneratedKeys()) { - if (rs.next()) { - return rs.getInt(1); - } - return -1; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (OneTimePinDTO oneTimePinDTO : oneTimePinDTOList) { + stmt.setString(1, oneTimePinDTO.getOtpToken()); + stmt.setString(2, oneTimePinDTO.getEmail()); + stmt.setString(3, oneTimePinDTO.getEmailType()); + stmt.setString(4, oneTimePinDTO.getMetaInfo()); + stmt.setTimestamp(5, timestamp); + stmt.setInt(6, oneTimePinDTO.getTenantId()); + stmt.setString(7, oneTimePinDTO.getUsername()); + stmt.addBatch(); } + stmt.executeBatch(); } } catch (DBConnectionException e) { - String msg = "Error occurred while obtaining the DB connection to create an opt entry for email " - + oneTimePinDTO.getEmail(); + String msg = "Error occurred while obtaining the DB connection to create an opt entry."; log.error(msg, e); throw new OTPManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "Error occurred while executing SQL to create an otp entry for email " + oneTimePinDTO.getEmail(); + String msg = "Error occurred while executing SQL to create an otp entry"; log.error(msg, e); throw new OTPManagementDAOException(msg, e); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java index 9b25987e84..c80502ec4f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -61,6 +61,8 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.UUID; +import java.util.ArrayList; +import java.util.Collections; public class OTPManagementServiceImpl implements OTPManagementService { @@ -82,12 +84,7 @@ public class OTPManagementServiceImpl implements OTPManagementService { otpWrapper.getUsername(), tenant, -1234); try { ConnectionManagerUtil.beginDBTransaction(); - if (this.otpManagementDAO.addOTPData(oneTimePinDTO) == -1) { - ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "OTP data saving failed. Please, contact Administrator"; - log.error(msg); - throw new OTPManagementException(msg); - } + this.otpManagementDAO.addOTPData(Collections.singletonList(oneTimePinDTO)); Properties props = new Properties(); props.setProperty("first-name", tenant.getAdminFirstName()); props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); @@ -98,12 +95,12 @@ public class OTPManagementServiceImpl implements OTPManagementService { log.error(msg, e); throw new OTPManagementException(msg, e); } catch (DBConnectionException e) { - String msg = "Error occurred while getting database connection."; + String msg = "Error occurred while getting database connection to add OPT data."; log.error(msg, e); throw new OTPManagementException(msg, e); } catch (OTPManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occurred while saving the OTP data. Email address: " + oneTimePinDTO.getEmail(); + String msg = "Error occurred while saving the OTP data for given email" ; log.error(msg, e); throw new OTPManagementException(msg, e); } finally { @@ -219,24 +216,44 @@ public class OTPManagementServiceImpl implements OTPManagementService { } int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); OneTimePinDTO oneTimePinDTO; + List oneTimePinDTOList = new ArrayList<>(); Properties props = new Properties(); props.setProperty("enrollment-steps", enrollmentSteps.toString()); try { + ConnectionManagerUtil.beginDBTransaction(); for (String username : deviceEnrollmentInvitation.getUsernames()) { String emailAddress = DeviceManagerUtil.getUserClaimValue( username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS); oneTimePinDTO = createOneTimePin(emailAddress, OTPEmailTypes.DEVICE_ENROLLMENT.toString(), username, null, tenantId); + oneTimePinDTOList.add(oneTimePinDTO); props.setProperty("first-name", DeviceManagerUtil. getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME)); props.setProperty("username", username); props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); sendMail(props, emailAddress, DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE); } + this.otpManagementDAO.addOTPData(oneTimePinDTOList); + ConnectionManagerUtil.commitDBTransaction(); } catch (UserStoreException e) { String msg = "Error occurred while getting claim values to invite user"; log.error(msg, e); throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to add OPT data."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "SQL Error occurred when adding OPT data to send device enrollment Invitation."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while saving the OTP data."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 5e28129390..f313477937 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -3051,26 +3051,21 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } @Override - public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) - throws DeviceManagementException { - + public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, + long to) throws DeviceManagementException { if (log.isDebugEnabled()) { log.debug("Get device location information"); } - List deviceLocationHistory; - String errMessage; - try { DeviceManagementDAOFactory.openConnection(); deviceLocationHistory = deviceDAO.getDeviceLocationInfo(deviceIdentifier, from, to); - } catch (DeviceManagementDAOException e) { - errMessage = "Error occurred in getDeviceLocationInfo"; + String errMessage = "Error occurred in getDeviceLocationInfo"; log.error(errMessage, e); throw new DeviceManagementException(errMessage, e); } catch (SQLException e) { - errMessage = "Error occurred while opening a connection to the data source"; + String errMessage = "Error occurred while opening a connection to the data source"; log.error(errMessage, e); throw new DeviceManagementException(errMessage, e); } finally { 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 e9c88e3321..e201cb9635 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 @@ -148,6 +148,8 @@ perm:user:permission-view perm:ios:view-configuration perm:ios:manage-configuration + perm:ios:dep-view + perm:ios:dep-add perm:windows:view-configuration perm:windows:manage-configuration perm:android:lock-devices diff --git a/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf b/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf index 6e7e6d01df..7887868228 100644 --- a/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf +++ b/features/ui-request-interceptor/io.entgra.ui.request.interceptor.feature/src/main/resources/p2.inf @@ -3,3 +3,4 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../depl org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/publisher-ui-request-handler.war,overwrite:true);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/store-ui-request-handler.war,overwrite:true);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/entgra-ui-request-handler.war,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/io.entgra.ui.request.interceptor_${feature.version}/webapps/ui-request-handler.war,target:${installFolder}/../../deployment/server/webapps/mdm-reports-ui-request-handler.war,overwrite:true);\