From 7c593d83fa2b443e317ff4ee3b9d99b08e5132c2 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Sun, 19 May 2019 01:27:58 +0530 Subject: [PATCH] Add APIs for subscription management --- .../common/ApplicationInstallResponse.java | 35 +- .../common/ApplicationInstallResponseTmp.java | 71 ++++ .../mgt/common/SubsciptionType.java | 22 ++ .../mgt/common/dto/DeviceSubscriptionDTO.java | 13 +- .../mgt/common/dto/GroupSubscriptionDTO.java | 63 ++++ .../mgt/common/dto/RoleSubscriptionDTO.java | 67 ++++ .../mgt/common/dto/UserSubscriptionDTO.java | 31 ++ .../common/response/ApplicationRelease.java | 30 +- .../common/services/SubscriptionManager.java | 15 +- .../mgt/core/dao/SubscriptionDAO.java | 27 +- .../GenericApplicationReleaseDAOImpl.java | 2 +- .../GenericSubscriptionDAOImpl.java | 335 ++++++++++++++++-- .../mgt/core/impl/ApplicationManagerImpl.java | 20 +- .../mgt/core/impl/MAMDeviceConnectorImpl.java | 4 +- .../mgt/core/impl/ReviewManagerImpl.java | 1 - .../core/impl/SubscriptionManagerImpl.java | 296 +++++++++++++--- .../application/mgt/core/util/APIUtil.java | 66 ++-- .../application/mgt/core/util/DAOUtil.java | 31 +- .../services/SubscriptionManagementAPI.java | 322 ++++++++++++++++- .../impl/ReviewManagementAPIImpl.java | 1 - .../impl/SubscriptionManagementAPIImpl.java | 148 +++++++- .../operation/mgt/OperationManagerImpl.java | 240 +++++++------ .../operation/mgt/util/DeviceIDHolder.java | 6 +- .../mgt/core/util/DeviceManagerUtil.java | 11 +- .../dbscripts/cdm/application-mgt/h2.sql | 15 +- .../dbscripts/cdm/application-mgt/mysql.sql | 15 + 26 files changed, 1568 insertions(+), 319 deletions(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubsciptionType.java create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java index fa0c56b2d7..e1ca9df104 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java @@ -26,18 +26,19 @@ import java.util.List; public class ApplicationInstallResponse { @ApiModelProperty( - name = "successfulDevices", + name = "installedDevices", value = "List of successful devices", dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" ) - private List successfulDevices; + private List installedDevices; + @ApiModelProperty( - name = "failedDevices", - value = "List of failed devices", + name = "alreadyInstalledDevices", + value = "List of devices that application release is already installed.", dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" ) - private List failedDevices; + private List alreadyInstalledDevices; @ApiModelProperty( name = "activity", @@ -45,20 +46,12 @@ public class ApplicationInstallResponse { ) private Activity activity; - public List getSuccessfulDevices() { - return successfulDevices; - } - - public void setSuccessfulDevices(List successfulDevices) { - this.successfulDevices = successfulDevices; - } - - public List getFailedDevices() { - return failedDevices; + public List getInstalledDevices() { + return installedDevices; } - public void setFailedDevices(List failedDevices) { - this.failedDevices = failedDevices; + public void setInstalledDevices(List installedDevices) { + this.installedDevices = installedDevices; } public Activity getActivity() { @@ -68,4 +61,12 @@ public class ApplicationInstallResponse { public void setActivity(Activity activity) { this.activity = activity; } + + public List getAlreadyInstalledDevices() { + return alreadyInstalledDevices; + } + + public void setAlreadyInstalledDevices(List alreadyInstalledDevices) { + this.alreadyInstalledDevices = alreadyInstalledDevices; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java new file mode 100644 index 0000000000..506fa3eb2a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018, 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.application.mgt.common; + +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; + +import java.util.List; + +public class ApplicationInstallResponseTmp { + @ApiModelProperty( + name = "successfulDevices", + value = "List of successful devices", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List successfulDevices; + + @ApiModelProperty( + name = "failedDevices", + value = "List of failed devices", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List failedDevices; + + @ApiModelProperty( + name = "activity", + value = "Activity corresponding to the operation" + ) + private Activity activity; + + public List getSuccessfulDevices() { + return successfulDevices; + } + + public void setSuccessfulDevices(List successfulDevices) { + this.successfulDevices = successfulDevices; + } + + public List getFailedDevices() { + return failedDevices; + } + + public void setFailedDevices(List failedDevices) { + this.failedDevices = failedDevices; + } + + public Activity getActivity() { + return activity; + } + + public void setActivity(Activity activity) { + this.activity = activity; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubsciptionType.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubsciptionType.java new file mode 100644 index 0000000000..2cee2c5b88 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubsciptionType.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, 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; + +public enum SubsciptionType { + USER, ROLE, DEVICE_GROUP +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java index c523c66a53..c2ea605ab0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java @@ -26,8 +26,9 @@ public class DeviceSubscriptionDTO { private Timestamp subscribedTimestamp; private boolean isUnsubscribed; private String unsubscribedBy; - private Timestamp unsubscribedTimestapm; + private Timestamp unsubscribedTimestamp; private String subscribedFrom; + private String status; private int deviceId; public int getId() { return id; } @@ -52,16 +53,20 @@ public class DeviceSubscriptionDTO { public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } - public Timestamp getUnsubscribedTimestapm() { return unsubscribedTimestapm; } + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } - public void setUnsubscribedTimestapm(Timestamp unsubscribedTimestapm) { - this.unsubscribedTimestapm = unsubscribedTimestapm; + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; } public String getSubscribedFrom() { return subscribedFrom; } public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + public String getStatus() { return status; } + + public void setStatus(String status) { this.status = status; } + public int getDeviceId() { return deviceId; } public void setDeviceId(int deviceId) { this.deviceId = deviceId; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java new file mode 100644 index 0000000000..1d1640a247 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java @@ -0,0 +1,63 @@ +/* Copyright (c) 2019, 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.dto; + +import java.sql.Timestamp; + +public class GroupSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private int groupdId; + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getSubscribedBy() { return subscribedBy; } + + public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + + public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } + + public boolean isUnsubscribed() { return isUnsubscribed; } + + public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + + public String getUnsubscribedBy() { return unsubscribedBy; } + + public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } + + public String getSubscribedFrom() { return subscribedFrom; } + + public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + + public int getGroupdId() { return groupdId; } + + public void setGroupdId(int groupdId) { this.groupdId = groupdId; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java new file mode 100644 index 0000000000..9d06179024 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java @@ -0,0 +1,67 @@ +/* Copyright (c) 2019, 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.dto; + +import java.sql.Timestamp; + +public class RoleSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private String roleName; + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getSubscribedBy() { return subscribedBy; } + + public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + + public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { return isUnsubscribed; } + + public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + + public String getUnsubscribedBy() { return unsubscribedBy; } + + public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public String getSubscribedFrom() { return subscribedFrom; } + + public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + + public String getRoleName() { return roleName; } + + public void setRoleName(String roleName) { this.roleName = roleName; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java new file mode 100644 index 0000000000..277b04e97d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, 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.dto; + +import java.sql.Timestamp; + +public class UserSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private String userName; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java index b4d8f5a426..78be9b6bbc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java @@ -21,6 +21,8 @@ package org.wso2.carbon.device.application.mgt.common.response; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import java.util.List; + @ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") public class ApplicationRelease { @@ -48,17 +50,9 @@ public class ApplicationRelease { value = "icon file storing location") private String iconPath; - @ApiModelProperty(name = "screenshotPath1", - value = "Screenshot storing location") - private String screenshotPath1; - - @ApiModelProperty(name = "screenshotPath2", + @ApiModelProperty(name = "screenshots", value = "Screenshot storing location") - private String screenshotPath2; - - @ApiModelProperty(name = "screenshotPath3", - value = "Screenshot storing location") - private String screenshotPath3; + private List screenshots; @ApiModelProperty(name = "releaseType", value = "Release type of the application release", @@ -163,18 +157,6 @@ public class ApplicationRelease { public void setIconPath(String iconPath) { this.iconPath = iconPath; } - public String getScreenshotPath1() { return screenshotPath1; } - - public void setScreenshotPath1(String screenshotPath1) { this.screenshotPath1 = screenshotPath1; } - - public String getScreenshotPath2() { return screenshotPath2; } - - public void setScreenshotPath2(String screenshotPath2) { this.screenshotPath2 = screenshotPath2; } - - public String getScreenshotPath3() { return screenshotPath3; } - - public void setScreenshotPath3(String screenshotPath3) { this.screenshotPath3 = screenshotPath3; } - public boolean isSharedWithAllTenants() { return isSharedWithAllTenants; } public void setSharedWithAllTenants(boolean sharedWithAllTenants) { isSharedWithAllTenants = sharedWithAllTenants; } @@ -190,4 +172,8 @@ public class ApplicationRelease { public double getRating() { return rating; } public void setRating(double rating) { this.rating = rating; } + + public List getScreenshots() { return screenshots; } + + public void setScreenshots(List screenshots) { this.screenshots = screenshots; } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java index e5c360d508..036b442024 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java @@ -19,6 +19,7 @@ package org.wso2.carbon.device.application.mgt.common.services; import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponseTmp; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; @@ -32,17 +33,17 @@ public interface SubscriptionManager { * To install an application to given list of devices. * @param applicationUUID ID of the application to install * @param deviceList list of device ID's to install the application - * @return {@link ApplicationInstallResponse} object which contains installed application and devices + * @return {@link ApplicationInstallResponseTmp} object which contains installed application and devices * @throws ApplicationManagementException if unable to install the application to the given devices */ - ApplicationInstallResponse installApplicationForDevices(String applicationUUID, List deviceList) + ApplicationInstallResponseTmp installApplicationForDevices(String applicationUUID, List deviceList) throws ApplicationManagementException; /** * To install an application to given list of users. * @param applicationUUID ID of the application to install * @param userList list of users to install the application - * @return {@link ApplicationInstallResponse} object which contains installed application and devices + * @return {@link ApplicationInstallResponseTmp} object which contains installed application and devices * @throws ApplicationManagementException if unable to install the application to devices belong to given users */ ApplicationInstallResponse installApplicationForUsers(String applicationUUID, List userList) @@ -52,20 +53,20 @@ public interface SubscriptionManager { * To install an application to given list of roles. * @param applicationUUID ID of the application to install * @param roleList list of roles to install the application - * @return {@link ApplicationInstallResponse} object which contains installed application and devices + * @return {@link ApplicationInstallResponseTmp} object which contains installed application and devices * @throws ApplicationManagementException if unable to install the application to devices belong to given roles */ - ApplicationInstallResponse installApplicationForRoles(String applicationUUID, List roleList) + ApplicationInstallResponseTmp installApplicationForRoles(String applicationUUID, List roleList) throws ApplicationManagementException; /** * To install an application to given list of roles. * @param applicationUUID ID of the application to install * @param deviceGroupList list of device groups to install the application - * @return {@link ApplicationInstallResponse} object which contains installed application and devices + * @return {@link ApplicationInstallResponseTmp} object which contains installed application and devices * @throws ApplicationManagementException if unable to install the application to devices belong to given groups */ - ApplicationInstallResponse installApplicationForGroups(String applicationUUID, List deviceGroupList) + ApplicationInstallResponseTmp installApplicationForGroups(String applicationUUID, List deviceGroupList) throws ApplicationManagementException; /** diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java index a4183eb4b3..6947616888 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java @@ -25,7 +25,9 @@ import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManageme import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * This interface provides the list of operations that are supported with subscription database. @@ -43,9 +45,17 @@ public interface SubscriptionDAO { * @param releaseId id of the {@link ApplicationReleaseDTO} * @throws ApplicationManagementDAOException If unable to add a mapping between device and application */ - void subscribeDeviceToApplication(int tenantId, String subscribedBy, List deviceList, int appId, + void subscribeDeviceToApplicationTmp(int tenantId, String subscribedBy, List deviceList, int appId, int releaseId, String installStatus) throws ApplicationManagementDAOException; + List subscribeDeviceToApplication(String subscribedBy, List deviceIds, String subscribedFrom, + String installStatus, int releaseId, int tenantId ) throws ApplicationManagementDAOException; + + List updateDeviceSubscription(String subscribedBy, List deviceIds, + String subscribedFrom, String installStatus, int releaseId, int tenantId) throws ApplicationManagementDAOException; + + void addOperationMapping (int operationId, List deviceSubscriptionId, int tenantId) throws ApplicationManagementDAOException; + /** * Adds a mapping between user and the application which the application is installed on. This mapping will be * added when an enterprise installation triggered to the user. @@ -53,11 +63,10 @@ public interface SubscriptionDAO { * @param tenantId id of the tenant * @param subscribedBy username of the user who subscribe the application * @param userList list of user names of the users whose devices are subscribed to the application - * @param appId id of the {@link ApplicationDTO} which installs * @param releaseId id of the {@link ApplicationReleaseDTO} * @throws ApplicationManagementDAOException If unable to add a mapping between device and application */ - void subscribeUserToApplication(int tenantId, String subscribedBy, List userList, int appId, int releaseId) + void subscribeUserToApplication(int tenantId, String subscribedBy, List userList, int releaseId) throws ApplicationManagementDAOException; /** @@ -91,4 +100,16 @@ public interface SubscriptionDAO { List getDeviceSubscriptions(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; + Map getDeviceSubscriptions(List deviceIds, int tenantId) throws + ApplicationManagementDAOException; + + List getSubscribedUsernames(List users, int tenantId) throws + ApplicationManagementDAOException; + + void updateUserSubscription(int tenantId, String updateBy, boolean isUnsubscribed, List userList, + int releaseId) throws ApplicationManagementDAOException; + + List getSubscribedDeviceIds(List deviceIds, int tenantId) throws ApplicationManagementDAOException; + + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java index a7b96f5b89..2065f8ac55 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -254,7 +254,7 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements statement.setInt(2, tenantId); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - return DAOUtil.loadAppRelease(resultSet); + return DAOUtil.constructAppReleaseDTO(resultSet); } return null; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index b59ca1f7b2..b1904b68fd 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -32,13 +32,19 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.StringJoiner; public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO { private static Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class); @Override - public void subscribeDeviceToApplication(int tenantId, String subscribedBy, List deviceList, int appId, + public void subscribeDeviceToApplicationTmp(int tenantId, String subscribedBy, List deviceList, int appId, int releaseId, String installStatus) throws ApplicationManagementDAOException { Connection conn; PreparedStatement stmt = null; @@ -72,36 +78,158 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public void subscribeUserToApplication(int tenantId, String subscribedBy, List userList, int appId, - int releaseId) throws ApplicationManagementDAOException { + public List subscribeDeviceToApplication(String subscribedBy, List deviceIds, + String subscribedFrom, String installStatus, int releaseId, int tenantId) + throws ApplicationManagementDAOException { Connection conn; - PreparedStatement stmt = null; try { + String sql = "INSERT INTO " + + "AP_DEVICE_SUBSCRIPTION(" + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "SUBSCRIBED_FROM, " + + "STATUS, " + + "DM_DEVICE_ID, " + + "AP_APP_RELEASE_ID," + + "TENANT_ID) " + + "VALUES (?, ?, ?, ?, ?, ?, ?)"; conn = this.getDBConnection(); - long time = System.currentTimeMillis() / 1000; - String sql = "INSERT INTO AP_USER_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, " - + "USER_NAME, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)"; - stmt = conn.prepareStatement(sql); - for (String user : userList) { - stmt = conn.prepareStatement(sql); - stmt.setInt(1, tenantId); - stmt.setString(2, subscribedBy); - stmt.setLong(3, time); - stmt.setString(4, user); - stmt.setInt(5, releaseId); - stmt.setInt(6, appId); - stmt.addBatch(); - if (log.isDebugEnabled()) { - log.debug("Adding a mapping to user[" + user + "] to the application [" + appId + "], release[" - + releaseId + "]"); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (Integer deviceId : deviceIds) { + stmt.setString(1, subscribedBy); + stmt.setTimestamp(2, timestamp); + stmt.setString(3, subscribedFrom); + stmt.setString(4, installStatus); + stmt.setInt(5, deviceId); + stmt.setInt(6, releaseId); + stmt.setInt(7, tenantId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a mapping to device[" + deviceId + "] to the application release[" + releaseId + + "]"); + } } + stmt.executeBatch(); + } + } catch (SQLException | DBConnectionException e) { + throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB", + e); + } + + return deviceIds; + } + + @Override + public List updateDeviceSubscription(String subscribedBy, List deviceIds, + String subscribedFrom, String installStatus, int releaseId, int tenantId) throws ApplicationManagementDAOException { + + Connection conn; + try { + conn = this.getDBConnection(); + String sql = "UPDATE AP_USER_SUBSCRIPTION " + + "SET " + + "SUBSCRIBED_BY = ?, " + + "SUBSCRIBED_TIMESTAMP = ?, " + + "SUBSCRIBED_FROM = ?, " + + "STATUS = ? " + + "WHERE " + + "DM_DEVICE_ID = ? AND " + + "AP_APP_RELEASE_ID = ? AND " + + "TENANT_ID = ?"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (Integer deviceId : deviceIds) { + stmt.setString(1, subscribedBy); + stmt.setTimestamp(2, timestamp); + stmt.setString(3, subscribedFrom); + stmt.setString(4, installStatus); + stmt.setInt(5, deviceId); + stmt.setInt(6, releaseId); + stmt.setInt(7, tenantId); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the device subscriptions of application."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the device subscriptions of application."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } + + + return deviceIds; + } + + @Override public void addOperationMapping(int operationId, List deviceSubscriptionIds, int tenantId) + throws ApplicationManagementDAOException { + Connection conn; + try { + String sql = "INSERT INTO " + + "AP_APP_SUB_OP_MAPPING(" + + "OPERATION_ID, " + + "AP_DEVICE_SUBSCRIPTION_ID, " + + "TENANT_ID) " + + "VALUES (?, ?, ?, ?, ?)"; + conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer subId : deviceSubscriptionIds) { + stmt.setInt(1, operationId); + stmt.setInt(2, subId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a operation mapping for subscription id " + subId); + } + } + stmt.executeBatch(); + } + } catch (SQLException | DBConnectionException e) { + throw new ApplicationManagementDAOException("Error occurred while adding operation subscription mapping to DB", + e); + } + + } + + @Override + public void subscribeUserToApplication(int tenantId, String subscribedBy, List userList, int releaseId) + throws ApplicationManagementDAOException { + Connection conn; + try { + String sql = "INSERT INTO " + + "AP_USER_SUBSCRIPTION(" + + "TENANT_ID, " + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "USER_NAME, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?)"; + conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (String user : userList) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + stmt.setInt(1, tenantId); + stmt.setString(2, subscribedBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, user); + stmt.setInt(5, releaseId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a mapping to user[" + user + "] to the application release[" + releaseId + "]"); + } + } + stmt.executeBatch(); } - stmt.executeBatch(); } catch (SQLException | DBConnectionException e) { throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB", e); - } finally { - DAOUtil.cleanupResources(stmt, null); } } @@ -216,4 +344,165 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + @Override + public Map getDeviceSubscriptions(List deviceIds, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions for given device ids."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + Map deviceSubscriptionDTOHashMap = new HashMap<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.SUBSCRIBED_FROM AS SUBSCRIBED_FROM, " + + "DS.DM_DEVICE_ID AS DEVICE_ID, " + + "DS.STATUS AS STATUS " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.DM_DEVICE_ID IN (", ") AND TENANT_ID = ?"); + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + DeviceSubscriptionDTO deviceSubscriptionDTO = DAOUtil.constructDeviceSubscriptionDTO(rs); + deviceSubscriptionDTOHashMap.put(deviceSubscriptionDTO.getId(), deviceSubscriptionDTO); + } + } + } + return deviceSubscriptionDTOHashMap; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Error occurred while obtaining the DB connection when getting device subscriptions for given " + + "device Ids.", e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException("SWL Error occurred while getting device subscriptions for given" + + " device Ids.", e); + } + } + + @Override + public List getSubscribedUsernames(List users, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for given list of user names."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedUsers = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT US.USER_NAME AS USER " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE US.USER_NAME IN (", ") AND TENANT_ID = ?"); + users.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String username : users) { + ps.setObject(index++, username); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER")); + } + } + } + return subscribedUsers; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Error occurred while obtaining the DB connection when getting subscribed users for given " + + "user names.", e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException("SWL Error occurred while getting suscribed users for given" + + " user names.", e); + } + } + + @Override public List getSubscribedDeviceIds(List deviceIds, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received to DAO Layer to get already subscribed dvice Ids for given list of device Ids."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedDevices = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT DS.DM_DEVICE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE US.DM_DEVICE_ID IN (", ") AND TENANT_ID = ?"); + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedDevices.add(rs.getInt("DM_DEVICE_I")); + } + } + } + return subscribedDevices; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Error occurred while obtaining the DB connection when getting subscribed device Ids for given " + + "device Id list.", e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException("SWL Error occurred while getting subscribed device ids for " + + "given devie Id list.", e); + } } + + @Override + public void updateUserSubscription(int tenantId, String updateBy, boolean isUnsubscribed, + List userList, int releaseId) throws ApplicationManagementDAOException { + Connection conn; + try { + conn = this.getDBConnection(); + String sql = "UPDATE AP_USER_SUBSCRIPTION SET "; + + if (isUnsubscribed){ + sql += "UNSUBSCRIBED = true, UNSUBSCRIBED_BY = ?, UNSUBSCRIBED_TIMESTAMP "; + } else { + sql += "SUBSCRIBED_BY = ?, SUBSCRIBED_TIMESTAMP =? "; + } + + sql += "WHERE USER_NAME = ? AND AP_APP_RELEASE_ID = ? AND AND TENANT_ID = ?"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (String username : userList) { + stmt.setString(1, updateBy); + stmt.setTimestamp(2, timestamp); + stmt.setString(3, username); + stmt.setInt(4, releaseId); + stmt.setInt(5, tenantId); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the user subscriptions of application."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the user subscriptions of application."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index c7161a2393..33e3855cdf 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -2565,7 +2565,9 @@ public class ApplicationManagerImpl implements ApplicationManager { private ApplicationRelease releaseDtoToRelease(ApplicationReleaseDTO applicationReleaseDTO){ String artifactDownloadEndpoint = ConfigurationManager.getInstance().getConfiguration() .getArtifactDownloadEndpoint(); - String basePath = artifactDownloadEndpoint + Constants.FORWARD_SLASH + applicationReleaseDTO.getUuid(); + String basePath = artifactDownloadEndpoint + Constants.FORWARD_SLASH + applicationReleaseDTO.getUuid() + + Constants.FORWARD_SLASH; + List screenshotPaths = new ArrayList<>(); ApplicationRelease applicationRelease = new ApplicationRelease(); applicationRelease.setDescription(applicationReleaseDTO.getDescription()); applicationRelease.setVersion(applicationReleaseDTO.getVersion()); @@ -2580,22 +2582,20 @@ public class ApplicationManagerImpl implements ApplicationManager { applicationRelease.setSupportedOsVersions(applicationReleaseDTO.getSupportedOsVersions()); applicationRelease.setRating(applicationReleaseDTO.getRating()); applicationRelease - .setInstallerPath(basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getInstallerName()); - applicationRelease.setIconPath(basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName()); - applicationRelease.setBannerPath(basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getBannerName()); + .setInstallerPath(basePath + applicationReleaseDTO.getInstallerName()); + applicationRelease.setIconPath(basePath + applicationReleaseDTO.getIconName()); + applicationRelease.setBannerPath(basePath + applicationReleaseDTO.getBannerName()); if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName1())) { - applicationRelease.setScreenshotPath1( - basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getScreenshotName1()); + screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName1()); } if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName2())) { - applicationRelease.setScreenshotPath2( - basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getScreenshotName2()); + screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName2()); } if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName3())) { - applicationRelease.setScreenshotPath3( - basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getScreenshotName3()); + screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName3()); } + applicationRelease.setScreenshots(screenshotPaths); return applicationRelease; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/MAMDeviceConnectorImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/MAMDeviceConnectorImpl.java index 1497412cc0..1599d1a7fb 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/MAMDeviceConnectorImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/MAMDeviceConnectorImpl.java @@ -70,13 +70,13 @@ public class MAMDeviceConnectorImpl implements DeviceConnector{ try { subscriptionDAO.subscribeUserToApplication(appOperation.getTenantId(), appOperation.getSubscribedBy(), - userList, appOperation.getApplication().getId(), appOperation.getAppReleaseId()); + userList, appOperation.getAppReleaseId()); for (String username: userList) { List devices = getDeviceManagementService().getDevicesOfUser(username); List deviceIdentifiers = convertDeviceToDeviceIdentifier(devices); // getDeviceManagementService().addOperation(appOperation.getApplication().getDeviceTypeName(), // operationEKA, devices); - subscriptionDAO.subscribeDeviceToApplication(appOperation.getTenantId(), appOperation.getSubscribedBy(), + subscriptionDAO.subscribeDeviceToApplicationTmp(appOperation.getTenantId(), appOperation.getSubscribedBy(), devices, appOperation.getApplication().getId(), appOperation.getAppReleaseId(), String.valueOf(AppOperation.InstallState.PENDING)); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java index 6751eef668..440502102c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java @@ -46,7 +46,6 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.application.mgt.core.util.Constants; import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.TreeMap; 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 355fb24193..48ae6181c0 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 @@ -21,15 +21,28 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.AppOperation; -import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationType; +import org.wso2.carbon.device.application.mgt.common.SubsciptionType; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponseTmp; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.application.mgt.core.util.HelperUtil; import org.wso2.carbon.device.mgt.common.Device; @@ -39,14 +52,18 @@ import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; 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.DeviceManagementConstants; +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; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -59,69 +76,225 @@ public class SubscriptionManagerImpl implements SubscriptionManager { private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class); private static final String INSTALL_APPLICATION = "INSTALL_APPLICATION"; private SubscriptionDAO subscriptionDAO; + private ApplicationDAO applicationDAO; + private LifecycleStateManager lifecycleStateManager; public SubscriptionManagerImpl() { + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); } @Override - public ApplicationInstallResponse installApplicationForDevices(String applicationUUID, - List deviceList) throws ApplicationManagementException { + public ApplicationInstallResponseTmp installApplicationForDevices(String applicationUUID, + List deviceIdentifiers) throws ApplicationManagementException { if (log.isDebugEnabled()) { - log.debug("Install application: " + applicationUUID + " to " + deviceList.size() + "devices."); + log.debug("Install application which has UUID: " + applicationUUID + " to " + deviceIdentifiers.size() + + "devices."); } - ApplicationManager applicationManager = DataHolder.getInstance().getApplicationManager(); - ApplicationDTO application = applicationManager.getApplicationByRelease(applicationUUID); + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + validateAppInstallingForDevicesRequest(applicationDTO, deviceIdentifiers); + return installToDevicesTmp(applicationDTO, deviceIdentifiers); + } - return installApplication(application, deviceList); + private ApplicationDTO getApplicationDTO(String uuid) throws ApplicationManagementException { + ApplicationDTO applicationDTO; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + applicationDTO = this.applicationDAO.getApplicationByUUID(uuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't fond an application for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + if (!lifecycleStateManager.getInstallableState() + .equals(applicationDTO.getApplicationReleaseDTOs().get(0).getCurrentState())) { + String msg = "You are trying to install an application which is not in the installable state of " + + "its Life-Cycle. hence you are not permitted to install this application. If you " + + "required to install this particular application, please change the state of " + + "application release from : " + applicationDTO.getApplicationReleaseDTOs().get(0) + .getCurrentState() + " to " + lifecycleStateManager.getInstallableState(); + log.error(msg); + throw new ForbiddenException(msg); + } + return applicationDTO; + } catch (LifecycleManagementException e) { + String msg = "Error occured when getting life-cycle state from life-cycle state manager."; + log.error(msg); + throw new ApplicationManagementException(msg); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application data for application release UUID: " + uuid; + log.error(msg); + throw new ApplicationManagementException(msg); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private void validateAppInstallingForDevicesRequest(ApplicationDTO applicationDTO, + List deviceIdentifiers) throws ApplicationManagementException { + DeviceType deviceType = null; + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { + deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + } + + for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) { + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType()) && deviceType != null + && !deviceType.getName().equals(deviceIdentifier.getType())) { + String msg = + "Found a device identifier which is not matched with the application device Type. Application " + + "device type is " + deviceType.getName() + + " and identifier which has different device" + " type is " + deviceIdentifier.getId(); + log.error(msg); + throw new BadRequestException(msg); + } + } } @Override - public ApplicationInstallResponse installApplicationForUsers(String applicationUUID, List userList) - throws ApplicationManagementException { + public ApplicationInstallResponse installApplicationForUsers(String applicationUUID, + List userList) throws ApplicationManagementException { if (log.isDebugEnabled()) { - log.debug("Install application: " + applicationUUID + " to " + userList.size() + " users."); + log.debug("Install application release which has UUID " + applicationUUID + " to " + userList.size() + + " users."); } - ApplicationManager applicationManager = DataHolder.getInstance().getApplicationManager(); - ApplicationDTO application = applicationManager.getApplicationByRelease(applicationUUID); - List deviceList = new ArrayList<>(); + + //todo check valid user list + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + DeviceType appDeviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + List operationTriggeredDeviceIdentifiers = new ArrayList<>(); + Map compatibleDevices = new HashMap<>(); + List operationTriggeredDeviceIds = new ArrayList<>(); + List installedDeviceIdentifiers = new ArrayList<>(); + for (String user : userList) { try { - List devicesOfUser = HelperUtil.getDeviceManagementProviderService().getDevicesOfUser(user); - devicesOfUser.stream() - .map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType())) - .forEach(deviceList::add); - if (log.isDebugEnabled()) { - log.debug(devicesOfUser.size() + " found for the provided user list"); + List userDevices = HelperUtil.getDeviceManagementProviderService().getDevicesOfUser(user); + List filteredDeviceIds = new ArrayList<>(); + List filteredDevices = new ArrayList<>(); + + for (Device device : userDevices) { + if (appDeviceType.getName().equals(device.getType())) { + filteredDevices.add(device); + filteredDeviceIds.add(device.getId()); + } + } + Map deviceSubscriptions = getDeviceSubscriptions(filteredDeviceIds); + for (Device device : filteredDevices) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), + device.getType()); + DeviceSubscriptionDTO deviceSubscriptionDTO = deviceSubscriptions.get(device.getId()); + if (deviceSubscriptionDTO != null && !deviceSubscriptionDTO.isUnsubscribed() + && Operation.Status.COMPLETED.toString().equals(deviceSubscriptionDTO.getStatus())) { + installedDeviceIdentifiers.add(deviceIdentifier); + } else { + compatibleDevices.put(deviceIdentifier, device.getId()); + } } } catch (DeviceManagementException e) { - throw new ApplicationManagementException("Error when extracting the device list of user[" + user + "].", - e); + String msg = "Error occurred when extracting the device list of user[" + user + "]."; + log.error(msg); + throw new ApplicationManagementException(msg, e); } } + Activity activity = installToDevices(applicationDTO, new ArrayList<>(compatibleDevices.keySet()), + appDeviceType.getName()); + + List activityStatuses = activity.getActivityStatus(); + for (ActivityStatus status : activityStatuses) { + if (status.getStatus().equals(ActivityStatus.Status.PENDING)){ + operationTriggeredDeviceIds.add(compatibleDevices.get(status.getDeviceIdentifier())); + operationTriggeredDeviceIdentifiers.add(status.getDeviceIdentifier()); + } + } + ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); + applicationInstallResponse.setActivity(activity); + applicationInstallResponse.setAlreadyInstalledDevices(installedDeviceIdentifiers); + applicationInstallResponse.setInstalledDevices(operationTriggeredDeviceIdentifiers); + + int operationId = Integer + .parseInt(activity.getActivityId().split(DeviceManagementConstants.OperationAttributes.ACTIVITY)[1]); + addDeviceSubscriptionForUser(applicationDTO.getApplicationReleaseDTOs().get(0).getId(), + operationTriggeredDeviceIds, userList, operationId); + return applicationInstallResponse; + } - ApplicationInstallResponse response = installApplication(application, deviceList); - + private void addDeviceSubscriptionForUser(int applicationReleaseId, List deviceIds, List userList, int operationId) + throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - int applicationReleaseId = application.getApplicationReleaseDTOs().get(0).getId(); + try { + ConnectionManagerUtil.beginDBTransaction(); + List deviceResubscribingIds = new ArrayList<>(); + List deviceSubscriptingIds; + + List subscribedUsers = subscriptionDAO.getSubscribedUsernames(userList, tenantId); + if (!subscribedUsers.isEmpty()) { + subscriptionDAO + .updateUserSubscription(tenantId, subscriber, false, subscribedUsers, applicationReleaseId); + userList.removeAll(subscribedUsers); + } + subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, userList, applicationReleaseId); + + List subscribedDevices = subscriptionDAO.getSubscribedDeviceIds(deviceIds, tenantId); + if (!subscribedDevices.isEmpty()) { + deviceResubscribingIds = subscriptionDAO + .updateDeviceSubscription(subscriber, deviceIds, SubsciptionType.USER.toString(), + Operation.Status.PENDING.toString(), applicationReleaseId, tenantId); + deviceIds.removeAll(subscribedDevices); + } + deviceSubscriptingIds = subscriptionDAO + .subscribeDeviceToApplication(subscriber, deviceIds, SubsciptionType.USER.toString(), + Operation.Status.PENDING.toString(), applicationReleaseId, tenantId); + deviceSubscriptingIds.addAll(deviceResubscribingIds); + subscriptionDAO.addOperationMapping(operationId, deviceSubscriptingIds, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred when adding subscription data for application release UUID: " + applicationReleaseId; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to add new device subscriptions to application."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = + "SQL Error occurred when adding new device subscription to application release which has UUID: " + + applicationReleaseId; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private Map getDeviceSubscriptions (List filteredDeviceIds) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { ConnectionManagerUtil.openDBConnection(); - subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, userList, application.getId(), - applicationReleaseId); + return this.subscriptionDAO + .getDeviceSubscriptions(filteredDeviceIds, tenantId); } catch (ApplicationManagementDAOException e) { - //todo - throw new ApplicationManagementException(""); + String msg = "Error occured when getting device subscriptions for given device IDs"; + log.error(msg); + throw new ApplicationManagementException(msg); + } catch (DBConnectionException e) { + String msg = "Error occured while getting database connection for getting device subscriptions."; + log.error(msg); + throw new ApplicationManagementException(msg); } finally { ConnectionManagerUtil.closeDBConnection(); } - return response; } @Override - public ApplicationInstallResponse installApplicationForRoles(String applicationUUID, List roleList) + public ApplicationInstallResponseTmp installApplicationForRoles(String applicationUUID, List roleList) throws ApplicationManagementException { if (log.isDebugEnabled()) { log.debug("Install application: " + applicationUUID + " to " + roleList.size() + " roles."); @@ -144,7 +317,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } - ApplicationInstallResponse response = installApplication(application, deviceList); + ApplicationInstallResponseTmp response = installToDevicesTmp(application, deviceList); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); @@ -165,7 +338,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public ApplicationInstallResponse installApplicationForGroups(String applicationUUID, List deviceGroupList) + public ApplicationInstallResponseTmp installApplicationForGroups(String applicationUUID, List deviceGroupList) throws ApplicationManagementException { if (log.isDebugEnabled()) { log.debug("Install application: " + applicationUUID + " to " + deviceGroupList.size() + " groups."); @@ -191,7 +364,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } - ApplicationInstallResponse response = installApplication(application, deviceList); + ApplicationInstallResponseTmp response = installToDevicesTmp(application, deviceList); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); @@ -211,18 +384,36 @@ public class SubscriptionManagerImpl implements SubscriptionManager { return response; } - @Override - public List uninstallApplication(String applicationUUID, List deviceList) - throws ApplicationManagementException { + @Override public List uninstallApplication(String applicationUUID, + List deviceList) throws ApplicationManagementException { return null; } - private ApplicationInstallResponse installApplication(ApplicationDTO application, + private Activity installToDevices(ApplicationDTO application, + List deviceIdentifierList, String deviceType) throws ApplicationManagementException { + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + try { + Operation operation = generateOperationPayloadByDeviceType(deviceType, application); + //todo refactor add operation code to get successful operations + return deviceManagementProviderService + .addOperation(deviceType, operation, deviceIdentifierList); + } catch (OperationManagementException e) { + throw new ApplicationManagementException("Error occurred while adding the application install " + + "operation to devices", e); + } catch (InvalidDeviceException e) { + //This exception should not occur because the validation has already been done. + throw new ApplicationManagementException("The list of device identifiers are invalid"); + } + } + + + private ApplicationInstallResponseTmp installToDevicesTmp(ApplicationDTO application, List deviceIdentifierList) throws ApplicationManagementException { DeviceManagementProviderService deviceManagementProviderService = HelperUtil .getDeviceManagementProviderService(); - ApplicationInstallResponse response = validateDevices(deviceIdentifierList, application.getType()); + ApplicationInstallResponseTmp response = validateDevices(deviceIdentifierList); /* Group the valid device list by device type. Following lambda expression produces a map containing device type as the key and the list of device identifiers as the corresponding value. @@ -260,7 +451,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { log.error("Unable to fetch device for device identifier: " + deviceIdentifier.toString()); } } - subscriptionDAO.subscribeDeviceToApplication(tenantId, subscriber, deviceList, application.getId(), + subscriptionDAO.subscribeDeviceToApplicationTmp(tenantId, subscriber, deviceList, application.getId(), applicationReleaseId, String.valueOf(AppOperation.InstallState.UNINSTALLED)); } catch (ApplicationManagementDAOException e) { //todo @@ -292,30 +483,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager { * whether the device is enrolled in the system. * * @param deviceIdentifierList List of {@link DeviceIdentifier} which the validation happens - * @param appPlatform type of the application - * @return {@link ApplicationInstallResponse} which contains compatible and incompatible device identifiers + * @return {@link ApplicationInstallResponseTmp} which contains compatible and incompatible device identifiers */ - private ApplicationInstallResponse validateDevices(List deviceIdentifierList, - String appPlatform) { - ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); + private ApplicationInstallResponseTmp validateDevices(List deviceIdentifierList) { + ApplicationInstallResponseTmp applicationInstallResponseTmp = new ApplicationInstallResponseTmp(); List failedDevices = new ArrayList<>(); List compatibleDevices = new ArrayList<>(); for (DeviceIdentifier deviceIdentifier : deviceIdentifierList) { try { - if (appPlatform == null || !(appPlatform.equals("WEB_CLIP") || appPlatform - .equals(deviceIdentifier.getType()))) { - log.error("Device with ID: [" + deviceIdentifier.getId() + "] of type: [" - + deviceIdentifier.getType() + "] is not compatible with the application of type: [" - + appPlatform + "]"); - failedDevices.add(deviceIdentifier); - continue; - } - if (!DeviceManagerUtil.isValidDeviceIdentifier(deviceIdentifier)) { log.error("Device with ID: [" + deviceIdentifier.getId() + "] is not valid to install the " + "application."); - applicationInstallResponse.getFailedDevices().add(deviceIdentifier); + applicationInstallResponseTmp.getFailedDevices().add(deviceIdentifier); } } catch (DeviceManagementException e) { log.error("Error occurred while validating the device: [" + deviceIdentifier.getId() + "]", e); @@ -323,9 +503,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } compatibleDevices.add(deviceIdentifier); } - applicationInstallResponse.setFailedDevices(failedDevices); - applicationInstallResponse.setSuccessfulDevices(compatibleDevices); + applicationInstallResponseTmp.setFailedDevices(failedDevices); + applicationInstallResponseTmp.setSuccessfulDevices(compatibleDevices); - return applicationInstallResponse; + return applicationInstallResponseTmp; } + + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java index d4cc2f72c7..0e84edef81 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java @@ -25,9 +25,13 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.Filter; import org.wso2.carbon.device.application.mgt.common.services.*; import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; import javax.ws.rs.core.Response; - +import java.util.List; /** * Holds util methods required for ApplicationDTO-Mgt API component. @@ -165,29 +169,41 @@ public class APIUtil { return appmDataHandler; } -// public static Filter constructFilter( String appName, String appType, String appCategory, String tags, -// boolean isFullMatch, String releaseState, int offset, int limit, String sortBy) { -// Filter filter = new Filter(); -// filter.setOffset(offset); -// filter.setLimit(limit); -// filter.setSortBy(sortBy); -// filter.setFullMatch(isFullMatch); -// if (!StringUtils.isEmpty(appName)) { -// filter.setAppName(appName); -// } -// if (!StringUtils.isEmpty(appType)) { -// filter.setAppType(appType); -// } -// if (!StringUtils.isEmpty(appCategory)) { -// filter.setAppCategories(appCategory); -// } -// if (!StringUtils.isEmpty(tags)) { -// filter.setAppCategories(appCategory); -// } -// if (!StringUtils.isEmpty(releaseState)) { -// filter.setAppReleaseState(releaseState); -// } -// return filter; -// } + public static DeviceType getDeviceTypeData(T deviceTypeAttr) + throws BadRequestException, UnexpectedServerErrorException { + List deviceTypes; + try { + deviceTypes = DAOUtil.getDeviceManagementService().getDeviceTypes(); + + if(deviceTypeAttr instanceof String){ + for (DeviceType dt : deviceTypes) { + if (dt.getName().equals(deviceTypeAttr)) { + return dt; + } + } + } else if (deviceTypeAttr instanceof Integer){ + for (DeviceType dt : deviceTypes) { + if (dt.getId() == (Integer) deviceTypeAttr) { + return dt; + } + } + } else { + String msg = "Invalid device type class is received. Device type class: " + deviceTypeAttr.getClass() + .getName(); + log.error(msg); + throw new BadRequestException(msg); + } + + String msg = + "Invalid device type Attribute is found with the request. Device Type attribute: " + deviceTypeAttr; + log.error(msg); + throw new BadRequestException(msg); + + } catch (DeviceManagementException e) { + String msg = "Error occured when getting device types which are supported by the Entgra IoTS"; + log.error(msg); + throw new UnexpectedServerErrorException(msg); + } + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java index 4068284e67..ca2587d690 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java @@ -83,10 +83,10 @@ public class DAOUtil { application.setStatus(rs.getString("APP_STATUS")); application.setAppRating(rs.getDouble("APP_RATING")); application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID")); - application.getApplicationReleaseDTOs().add(loadAppRelease(rs)); + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); } else { if (application != null && application.getApplicationReleaseDTOs() != null) { - application.getApplicationReleaseDTOs().add(loadAppRelease(rs)); + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); } } hasNext = rs.next(); @@ -108,20 +108,25 @@ public class DAOUtil { public static List loadDeviceSubscriptions(ResultSet rs) throws SQLException { List deviceSubscriptionDTOS = new ArrayList<>(); while (rs.next()) { - DeviceSubscriptionDTO deviceSubscriptionDTO = new DeviceSubscriptionDTO(); - deviceSubscriptionDTO.setId(rs.getInt("ID")); - deviceSubscriptionDTO.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); - deviceSubscriptionDTO.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); - deviceSubscriptionDTO.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); - deviceSubscriptionDTO.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); - deviceSubscriptionDTO.setUnsubscribedTimestapm(rs.getTimestamp("UNSUBSCRIBED_AT")); - deviceSubscriptionDTO.setSubscribedFrom(rs.getString("SUBSCRIBED_FROM")); - deviceSubscriptionDTO.setDeviceId(rs.getInt("DEVICE_ID")); - deviceSubscriptionDTOS.add(deviceSubscriptionDTO); + deviceSubscriptionDTOS.add(constructDeviceSubscriptionDTO(rs)); } return deviceSubscriptionDTOS; } + public static DeviceSubscriptionDTO constructDeviceSubscriptionDTO(ResultSet rs ) throws SQLException { + DeviceSubscriptionDTO deviceSubscriptionDTO = new DeviceSubscriptionDTO(); + deviceSubscriptionDTO.setId(rs.getInt("ID")); + deviceSubscriptionDTO.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + deviceSubscriptionDTO.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); + deviceSubscriptionDTO.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); + deviceSubscriptionDTO.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + deviceSubscriptionDTO.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT")); + deviceSubscriptionDTO.setSubscribedFrom(rs.getString("SUBSCRIBED_FROM")); + deviceSubscriptionDTO.setDeviceId(rs.getInt("DEVICE_ID")); + deviceSubscriptionDTO.setStatus(rs.getString("STATUS")); + return deviceSubscriptionDTO; + } + /** * Populates {@link ApplicationReleaseDTO} object with the result obtained from the database. * @@ -129,7 +134,7 @@ public class DAOUtil { * @return {@link ApplicationReleaseDTO} object populated with the data * @throws SQLException If unable to populate {@link ApplicationReleaseDTO} object with the data */ - public static ApplicationReleaseDTO loadAppRelease(ResultSet rs) throws SQLException { + public static ApplicationReleaseDTO constructAppReleaseDTO(ResultSet rs) throws SQLException { ApplicationReleaseDTO appRelease = new ApplicationReleaseDTO(); appRelease.setId(rs.getInt("RELEASE_ID")); appRelease.setDescription(rs.getString("RELEASE_DESCRIPTION")); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java index a6f9c248f7..f91e755aa1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java @@ -29,19 +29,22 @@ import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Tag; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; -import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponseTmp; import org.wso2.carbon.device.application.mgt.common.EnterpriseInstallationDetails; import org.wso2.carbon.device.application.mgt.common.InstallationDetails; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.List; /** * API to handle subscription management related tasks. @@ -67,14 +70,14 @@ import javax.ws.rs.core.Response; @org.wso2.carbon.apimgt.annotations.api.Scope( name = "Install an ApplicationDTO", description = "Install an application", - key = "perm:subscription:install", - permissions = {"/device-mgt/subscription/install"} + key = "perm:app:subscription:install", + permissions = {"/app-mgt/store/subscription/install"} ), @org.wso2.carbon.apimgt.annotations.api.Scope( - name = "Install an ApplicationDTO", - description = "Install an application", - key = "perm:application-mgt:login", - permissions = {"/device-mgt/application-mgt/login"} + name = "Uninstall an Application", + description = "Uninstall an application", + key = "perm:app:subscription:uninstall", + permissions = {"/app-mgt/store/subscription/uninstall"} ) } ) @@ -87,6 +90,307 @@ public interface SubscriptionManagementAPI { String SCOPE = "scope"; + @POST + @Path("/install/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:install") + }) + } + ) + @ApiResponses( + value = { + + }) + Response installApplicationForDevices( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List deviceIdentifiers + ); + + @POST + @Path("/install/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:install") + }) + } + ) + @ApiResponses( + value = { + + }) + Response installApplicationForUsers( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List users + ); + + @POST + @Path("/install/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:install") + }) + } + ) + @ApiResponses( + value = { + + }) + Response installApplicationForRoles ( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List roles + ); + + @POST + @Path("/install/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:install") + }) + } + ) + @ApiResponses( + value = { + + }) + Response installApplicationForGroups ( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List groups + ); + +// ########################### + + + @POST + @Path("/uninstall/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + + }) + Response uninstallApplicationForDevices( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List deviceIdentifiers + ); + + @POST + @Path("/uninstall/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + + }) + Response uninstallApplicationForUsers( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List users + ); + + @POST + @Path("/uninstall/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + + }) + Response uninstallApplicationForRoles ( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List roles + ); + + @POST + @Path("/uninstall/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Install an application for devices", + notes = "This will install an application to a given list of devices", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + + }) + Response uninstallApplicationForGroups ( + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @PathParam("uuid") String uuid, + @ApiParam( + name = "installationDetails", + value = "The application ID and list of devices/users/roles", + required = true + ) + @Valid List groups + ); + + + + + + + + + +// ---------------------------------------------- + @POST @Path("/install-application") @Produces(MediaType.APPLICATION_JSON) @@ -109,7 +413,7 @@ public interface SubscriptionManagementAPI { @ApiResponse( code = 200, message = "OK. \n Successfully sent the install application operation.", - response = ApplicationInstallResponse.class + response = ApplicationInstallResponseTmp.class ), @ApiResponse( code = 304, @@ -154,7 +458,7 @@ public interface SubscriptionManagementAPI { @ApiResponse( code = 200, message = "OK. \n Successfully sent the install application operation.", - response = ApplicationInstallResponse.class + response = ApplicationInstallResponseTmp.class ), @ApiResponse( code = 304, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java index c8b8a667a8..8b2d94a0aa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java @@ -23,7 +23,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.application.mgt.common.PaginationResult; import org.wso2.carbon.device.application.mgt.common.Rating; -import org.wso2.carbon.device.application.mgt.common.exception.ReviewDoesNotExistException; import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java index db48346607..9929d2072e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java @@ -21,17 +21,22 @@ import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponseTmp; import org.wso2.carbon.device.application.mgt.common.EnterpriseInstallationDetails; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI; import org.wso2.carbon.device.application.mgt.common.InstallationDetails; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; import org.wso2.carbon.device.application.mgt.core.util.APIUtil; - +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import javax.validation.Valid; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import java.util.List; @@ -45,6 +50,141 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ private static Log log = LogFactory.getLog(SubscriptionManagementAPIImpl.class); + @Override + @POST + @Path("/install/{uuid}/devices") + public Response installApplicationForDevices( + @PathParam("uuid") String uuid, + @Valid List deviceIdentifiers) { + if (deviceIdentifiers.isEmpty()){ + String msg = "In order to install application release which has UUID " + uuid + ", you should provide list " + + "of device identifiers. But found an empty list of identifiers."; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + try { + SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); + ApplicationInstallResponseTmp response = subscriptionManager + .installApplicationForDevices(uuid, deviceIdentifiers); + return Response.status(Response.Status.OK).entity(response).build(); + } catch (NotFoundException e) { + String msg = "Couldn't found an application release for UUI: " + uuid; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (BadRequestException e) { + String msg = "Found invalid payload for installing application which has UUID: " + uuid + + ". Hence verify the payload"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "Application release is not in the installable state. Hence you are not permitted to install the aplication."; + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = + "Error occurred while installing the application release which has UUID: " + uuid + " for devices"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @POST + @Path("/install/{uuid}/users") + public Response installApplicationForUsers( + @PathParam("uuid") String uuid, + @Valid List users) { + if (users.isEmpty()){ + String msg = "In order to install application release which has UUID " + uuid + ", you should provide list " + + "of users. But found an empty list of users."; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + try { + SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); + ApplicationInstallResponse response = subscriptionManager.installApplicationForUsers(uuid, users); + return Response.status(Response.Status.OK).entity(response).build(); + + //todo + } catch(BadRequestException e){ + String msg = "Found invalid payload for installing application which has UUID: " + uuid + + ". Hence verify the payload"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch(ForbiddenException e){ + String msg = "Application release is not in the installable state. Hence you are not permitted to install the aplication."; + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + }catch (ApplicationManagementException e) { + String msg = + "Error occurred while installing the application release which has UUID: " + uuid + " for devices"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } } + + @Override + @POST + @Path("/install/{uuid}/roles") + public Response installApplicationForRoles( + @PathParam("uuid") String uuid, + @Valid List roles) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + } + + @Override + @POST + @Path("/install/{uuid}/groups") + public Response installApplicationForGroups( + @PathParam("uuid") String uuid, + @Valid List groups) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + } + + + @Override + @POST + @Path("/uninstall/{uuid}/devices") + public Response uninstallApplicationForDevices( + @PathParam("uuid") String uuid, + @Valid List deviceIdentifiers) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + } + + @Override + @POST + @Path("/uninstall/{uuid}/users") + public Response uninstallApplicationForUsers( + @PathParam("uuid") String uuid, + @Valid List users) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + } + + @Override + @POST + @Path("/uninstall/{uuid}/roles") + public Response uninstallApplicationForRoles( + @PathParam("uuid") String uuid, + @Valid List roles) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + } + + @Override + @POST + @Path("/uninstall/{uuid}/groups") + public Response uninstallApplicationForGroups( + @PathParam("uuid") String uuid, + @Valid List groups) { + return Response.status(Response.Status.BAD_REQUEST).entity("").build(); + + } + + + + + + + + @Override @POST @Path("/install-application") @@ -61,7 +201,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ } try { - ApplicationInstallResponse response = subscriptionManager.installApplicationForDevices(applicationUUID, + ApplicationInstallResponseTmp response = subscriptionManager.installApplicationForDevices(applicationUUID, installationDetails.getDeviceIdentifiers()); return Response.status(Response.Status.OK).entity(response).build(); } catch (ApplicationManagementException e) { @@ -78,7 +218,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ String applicationUUID = enterpriseInstallationDetails.getApplicationUUID(); EnterpriseInstallationDetails.EnterpriseEntity enterpriseEntity = enterpriseInstallationDetails.getEntityType(); List entityValueList = enterpriseInstallationDetails.getEntityValueList(); - ApplicationInstallResponse response; + ApplicationInstallResponseTmp response = null; if (applicationUUID.isEmpty()) { msg = "ApplicationDTO UUID is empty in the incoming request. Therefore unable to proceed with the " @@ -96,7 +236,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ try { if (EnterpriseInstallationDetails.EnterpriseEntity.USER.equals(enterpriseEntity)) { - response = subscriptionManager.installApplicationForUsers(applicationUUID, entityValueList); +// response = subscriptionManager.installApplicationForUsers(applicationUUID, entityValueList); } else if (EnterpriseInstallationDetails.EnterpriseEntity.ROLE.equals(enterpriseEntity)) { response = subscriptionManager.installApplicationForRoles(applicationUUID, entityValueList); } else if (EnterpriseInstallationDetails.EnterpriseEntity.DEVICE_GROUP.equals(enterpriseEntity)) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java index d2fb72b90e..353a37bf6b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java @@ -159,126 +159,144 @@ public class OperationManagerImpl implements OperationManager { try { DeviceIDHolder deviceValidationResult = DeviceManagerUtil.validateDeviceIdentifiers(deviceIds); List validDeviceIds = deviceValidationResult.getValidDeviceIDList(); - if (!validDeviceIds.isEmpty()) { - if (log.isDebugEnabled() && deviceIds.get(0).getType() != null) { - log.debug("Adding operation for Device type : " + deviceIds.get(0).getType() + ", tenant ID:" - + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() + ", domain:" - + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain() - + ", device count:" + deviceIds.size() + " operation type:" + operation.getCode()); - } - DeviceIDHolder deviceAuthorizationResult = this.authorizeDevices(operation, validDeviceIds); - List authorizedDeviceIds = deviceAuthorizationResult.getValidDeviceIDList(); - if (authorizedDeviceIds.size() <= 0) { - log.warn("User : " + getUser() + " is not authorized to perform operations on given device-list."); - Activity activity = new Activity(); - //Send the operation statuses only for admin triggered operations - String deviceType = validDeviceIds.get(0).getType(); - activity.setActivityStatus(this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult, - deviceType)); - return activity; - } - boolean isScheduledOperation = this.isTaskScheduledOperation(operation); - String initiatedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - if (initiatedBy == null && isScheduledOperation) { - if(log.isDebugEnabled()) { - log.debug("initiatedBy : " + SYSTEM); - } - operation.setInitiatedBy(SYSTEM); - } else { - if(log.isDebugEnabled()) { - log.debug("initiatedBy : " + initiatedBy); - } - operation.setInitiatedBy(initiatedBy); - } + if (validDeviceIds.isEmpty()) { + String msg = "Invalid device Identifiers found."; + log.error(msg); + throw new InvalidDeviceException(msg); + } + if (log.isDebugEnabled() && deviceIds.get(0).getType() != null) { + log.debug("Adding operation for Device type : " + deviceIds.get(0).getType() + ", tenant ID:" + + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() + ", domain:" + + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain() + ", device count:" + + deviceIds.size() + " operation type:" + operation.getCode()); + } +// Map> ignoredDeviceIdentifierMap = new HashMap<>(); +// Map> authorizedDeviceIdentifierMap = new HashMap<>(); + DeviceIDHolder deviceAuthorizationResult = this.authorizeDevices(operation, validDeviceIds); + List authorizedDeviceIds = deviceAuthorizationResult.getValidDeviceIDList(); + if (authorizedDeviceIds.isEmpty()) { + log.warn("User : " + getUser() + " is not authorized to perform operations on given device-list."); + Activity activity = new Activity(); + //Send the operation statuses only for admin triggered operations + activity.setActivityStatus( + this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult)); + return activity; + } - OperationManagementDAOFactory.beginTransaction(); - org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation operationDto = - OperationDAOUtil.convertOperation(operation); - int enrolmentId; - String operationCode = operationDto.getCode(); - - List authorizedDevices = new ArrayList<>(); - List ignoredDevices = new ArrayList<>(); - for (DeviceIdentifier deviceId : authorizedDeviceIds) { - Device device = getDevice(deviceId); - authorizedDevices.add(device); + boolean isScheduledOperation = this.isTaskScheduledOperation(operation); + String initiatedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (initiatedBy == null && isScheduledOperation) { + if (log.isDebugEnabled()) { + log.debug("initiatedBy : " + SYSTEM); + } + operation.setInitiatedBy(SYSTEM); + } else { + if (log.isDebugEnabled()) { + log.debug("initiatedBy : " + initiatedBy); } + operation.setInitiatedBy(initiatedBy); + } + + OperationManagementDAOFactory.beginTransaction(); + org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation operationDto = OperationDAOUtil + .convertOperation(operation); + int enrolmentId; + String operationCode = operationDto.getCode(); + + List authorizedDevices = new ArrayList<>(); + List ignoredDevices = new ArrayList<>(); + for (DeviceIdentifier deviceId : authorizedDeviceIds) { + Device device = getDevice(deviceId); + authorizedDevices.add(device); + } - if (operationDto.getControl() == - org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Control.NO_REPEAT) { - int existingOperationID; - for (Device device : authorizedDevices) { - enrolmentId = device.getEnrolmentInfo().getId(); - existingOperationID = operationDAO.getExistingOperationID(enrolmentId, operationCode); - if (existingOperationID > 0) { - ignoredDevices.add(device); - operation.setId(existingOperationID); - this.sendNotification(operation, device); - } + if (operationDto.getControl() + == org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Control.NO_REPEAT) { + int existingOperationID; + for (Device device : authorizedDevices) { + enrolmentId = device.getEnrolmentInfo().getId(); + existingOperationID = operationDAO.getExistingOperationID(enrolmentId, operationCode); + if (existingOperationID > 0) { + ignoredDevices.add(device); + operation.setId(existingOperationID); + this.sendNotification(operation, device); +// List deviceIdentifiers; +// if (ignoredDeviceIdentifierMap.containsKey(existingOperationID)) { +// deviceIdentifiers = ignoredDeviceIdentifierMap.get(existingOperationID); +// } else { +// deviceIdentifiers = new ArrayList<>(); +// } +// DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); +// deviceIdentifier.setType(device.getType()); +// deviceIdentifier.setId(device.getDeviceIdentifier()); +// deviceIdentifiers.add(deviceIdentifier); +// ignoredDeviceIdentifierMap.put(existingOperationID, deviceIdentifiers); } } + } - if (ignoredDevices.size() > 0) { - if (authorizedDevices.size() == ignoredDevices.size()) { - if (log.isDebugEnabled()) { - log.debug("All the devices contain a pending operation for the Operation Code: " - + operationCode); - } - Activity activity = new Activity(); - //Send the operation statuses only for admin triggered operations - String deviceType = validDeviceIds.get(0).getType(); - activity.setActivityStatus(this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult, - deviceType)); - return activity; - } else { - authorizedDevices.removeAll(ignoredDevices); + if (!ignoredDevices.isEmpty()) { + if (authorizedDevices.size() == ignoredDevices.size()) { + if (log.isDebugEnabled()) { + log.debug( + "All the devices contain a pending operation for the Operation Code: " + operationCode); } + Activity activity = new Activity(); + //Send the operation statuses only for admin triggered operations + activity.setActivityStatus( + this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult)); + return activity; + } else { + authorizedDevices.removeAll(ignoredDevices); } + } - int operationId = this.lookupOperationDAO(operation).addOperation(operationDto); + int operationId = this.lookupOperationDAO(operation).addOperation(operationDto); - boolean isScheduled = false; - NotificationStrategy notificationStrategy = getNotificationStrategy(); + boolean isScheduled = false; + NotificationStrategy notificationStrategy = getNotificationStrategy(); - // check whether device list is greater than batch size notification strategy has enable to send push - // notification using scheduler task - if (DeviceConfigurationManager.getInstance().getDeviceManagementConfig(). - getPushNotificationConfiguration().getSchedulerBatchSize() <= authorizedDeviceIds.size() && - notificationStrategy != null) { - isScheduled = notificationStrategy.getConfig().isScheduled(); - } + // check whether device list is greater than batch size notification strategy has enable to send push + // notification using scheduler task + if (DeviceConfigurationManager.getInstance().getDeviceManagementConfig(). + getPushNotificationConfiguration().getSchedulerBatchSize() <= authorizedDeviceIds.size() + && notificationStrategy != null) { + isScheduled = notificationStrategy.getConfig().isScheduled(); + } - //TODO have to create a sql to load device details from deviceDAO using single query. - for (Device device : authorizedDevices) { - enrolmentId = device.getEnrolmentInfo().getId(); - //Do not repeat the task operations - operationMappingDAO.addOperationMapping(operationId, enrolmentId, isScheduled); - } - OperationManagementDAOFactory.commitTransaction(); + //TODO have to create a sql to load device details from deviceDAO using single query. + List authorizedDeviceIdentifiers = new ArrayList<>(); + for (Device device : authorizedDevices) { + enrolmentId = device.getEnrolmentInfo().getId(); + //Do not repeat the task operations + operationMappingDAO.addOperationMapping(operationId, enrolmentId, isScheduled); +// DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); +// deviceIdentifier.setId(device.getDeviceIdentifier()); +// deviceIdentifier.setType(device.getType()); +// authorizedDeviceIdentifiers.add(deviceIdentifier); + } - if (!isScheduled) { - for (Device device : authorizedDevices) { - this.sendNotification(operation, device); - } - } +// authorizedDeviceIdentifierMap.put(operationId, authorizedDeviceIdentifiers); + OperationManagementDAOFactory.commitTransaction(); - Activity activity = new Activity(); - activity.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId); - activity.setCode(operationCode); - activity.setCreatedTimeStamp(new Date().toString()); - activity.setType(Activity.Type.valueOf(operationDto.getType().toString())); - //For now set the operation statuses only for admin triggered operations - if (!isScheduledOperation) { - //Get the device-type from 1st valid DeviceIdentifier. We know the 1st element is definitely there. - String deviceType = validDeviceIds.get(0).getType(); - activity.setActivityStatus(this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult, - deviceType)); + if (!isScheduled) { + for (Device device : authorizedDevices) { + this.sendNotification(operation, device); } - return activity; - } else { - throw new InvalidDeviceException("Invalid device Identifiers found."); } + + Activity activity = new Activity(); + activity.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId); + activity.setCode(operationCode); + activity.setCreatedTimeStamp(new Date().toString()); + activity.setType(Activity.Type.valueOf(operationDto.getType().toString())); + //For now set the operation statuses only for admin triggered operations + if (!isScheduledOperation) { + activity.setActivityStatus( + this.getActivityStatus(deviceValidationResult, deviceAuthorizationResult)); + } + return activity; } catch (OperationManagementDAOException e) { OperationManagementDAOFactory.rollbackTransaction(); throw new OperationManagementException("Error occurred while adding operation", e); @@ -332,22 +350,22 @@ public class OperationManagerImpl implements OperationManager { } } - private List getActivityStatus(DeviceIDHolder deviceIdValidationResult, DeviceIDHolder deviceAuthResult, - String deviceType) { + private List getActivityStatus(DeviceIDHolder deviceIdValidationResult, + DeviceIDHolder deviceAuthResult) { List activityStatuses = new ArrayList<>(); ActivityStatus activityStatus; //Add the invalid DeviceIds - for (String id : deviceIdValidationResult.getErrorDeviceIdList()) { + for (DeviceIdentifier id : deviceIdValidationResult.getErrorDeviceIdList()) { activityStatus = new ActivityStatus(); - activityStatus.setDeviceIdentifier(new DeviceIdentifier(id, deviceType)); + activityStatus.setDeviceIdentifier(id); activityStatus.setStatus(ActivityStatus.Status.INVALID); activityStatuses.add(activityStatus); } //Add the unauthorized DeviceIds - for (String id : deviceAuthResult.getErrorDeviceIdList()) { + for (DeviceIdentifier id : deviceAuthResult.getErrorDeviceIdList()) { activityStatus = new ActivityStatus(); - activityStatus.setDeviceIdentifier(new DeviceIdentifier(id, deviceType)); + activityStatus.setDeviceIdentifier(id); activityStatus.setStatus(ActivityStatus.Status.UNAUTHORIZED); activityStatuses.add(activityStatus); } @@ -365,7 +383,7 @@ public class OperationManagerImpl implements OperationManager { private DeviceIDHolder authorizeDevices( Operation operation, List deviceIds) throws OperationManagementException { List authorizedDeviceList; - List unAuthorizedDeviceList = new ArrayList<>(); + List unAuthorizedDeviceList = new ArrayList<>(); DeviceIDHolder deviceIDHolder = new DeviceIDHolder(); try { if (operation != null && isAuthenticationSkippedOperation(operation)) { @@ -379,7 +397,7 @@ public class OperationManagerImpl implements OperationManager { if (isAuthorized) { authorizedDeviceList.add(devId); } else { - unAuthorizedDeviceList.add(devId.getId()); + unAuthorizedDeviceList.add(devId); } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/util/DeviceIDHolder.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/util/DeviceIDHolder.java index 8844379adf..858b656613 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/util/DeviceIDHolder.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/util/DeviceIDHolder.java @@ -27,14 +27,14 @@ import java.util.List; */ public class DeviceIDHolder { - private List errorDeviceIdList; + private List errorDeviceIdList; private List validDeviceIDList; - public List getErrorDeviceIdList() { + public List getErrorDeviceIdList() { return errorDeviceIdList; } - public void setErrorDeviceIdList(List errorDeviceIdList) { + public void setErrorDeviceIdList(List errorDeviceIdList) { this.errorDeviceIdList = errorDeviceIdList; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index 44d8814fcd..096c18a53d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -464,8 +464,8 @@ public final class DeviceManagerUtil { public static DeviceIDHolder validateDeviceIdentifiers(List deviceIDs) { - List errorDeviceIdList = new ArrayList(); - List validDeviceIDList = new ArrayList(); + List errorDeviceIdList = new ArrayList<>(); + List validDeviceIDList = new ArrayList<>(); int deviceIDCounter = 0; for (DeviceIdentifier deviceIdentifier : deviceIDs) { @@ -474,8 +474,9 @@ public final class DeviceManagerUtil { String deviceID = deviceIdentifier.getId(); if (deviceID == null || deviceID.isEmpty()) { - errorDeviceIdList.add(String.format(OperationMgtConstants.DeviceConstants.DEVICE_ID_NOT_FOUND, + log.warn(String.format(OperationMgtConstants.DeviceConstants.DEVICE_ID_NOT_FOUND, deviceIDCounter)); + errorDeviceIdList.add(deviceIdentifier); continue; } @@ -484,10 +485,10 @@ public final class DeviceManagerUtil { if (isValidDeviceIdentifier(deviceIdentifier)) { validDeviceIDList.add(deviceIdentifier); } else { - errorDeviceIdList.add(deviceID); + errorDeviceIdList.add(deviceIdentifier); } } catch (DeviceManagementException e) { - errorDeviceIdList.add(deviceID); + errorDeviceIdList.add(deviceIdentifier); } } diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql index d1696c6f37..528e7c74da 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql @@ -110,7 +110,8 @@ CREATE TABLE IF NOT EXISTS AP_DEVICE_SUBSCRIPTION( UNSUBSCRIBED BOOLEAN NULL DEFAULT NULL, UNSUBSCRIBED_BY VARCHAR(100) NULL DEFAULT NULL, UNSUBSCRIBED_TIMESTAMP TIMESTAMP NULL DEFAULT NULL, - SUBSCRIBED_FROM VARCHAR(45) NULL, + SUBSCRIBED_FROM VARCHAR(45) NOT NULL, + STATUS VARCHAR(45) NOT NULL, DM_DEVICE_ID INTEGER NOT NULL, AP_APP_RELEASE_ID INTEGER NOT NULL, AP_APP_ID INTEGER NOT NULL, @@ -247,3 +248,15 @@ CREATE TABLE IF NOT EXISTS AP_APP_CATEGORY_MAPPING( ); CREATE INDEX fk_AP_APP_CATEGORY_copy1_AP_APP_CATEGORY1_idx ON AP_APP_CATEGORY_MAPPING (AP_APP_CATEGORY_ID ASC); CREATE INDEX fk_AP_APP_CATEGORY_copy1_AP_APP1_idx ON AP_APP_CATEGORY_MAPPING (AP_APP_ID ASC); + +CREATE TABLE IF NOT EXISTS AP_APP_SUB_OP_MAPPING ( + ID INTEGER NOT NULL AUTO_INCREMENT, + TENANT_ID INTEGER NOT NULL, + OPERATION_ID INTEGER NOT NULL, + AP_DEVICE_SUBSCRIPTION_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1 + FOREIGN KEY (AP_DEVICE_SUBSCRIPTION_ID) + REFERENCES AP_DEVICE_SUBSCRIPTION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1_idx ON AP_APP_SUB_OP_MAPPING (AP_DEVICE_SUBSCRIPTION_ID ASC); diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql index 973bfff363..0db2a022ef 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql @@ -315,3 +315,18 @@ CREATE TABLE IF NOT EXISTS `APP_MANAGER`.`AP_APP_CATEGORY_MAPPING` ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; + +CREATE TABLE IF NOT EXISTS `APP_MANAGER`.`AP_APP_OP_DEVICE_MAPPING` ( + `ID` INT(11) NOT NULL AUTO_INCREMENT, + `TENANT_ID` INT(11) NOT NULL, + `OPERATION_ID` INT(11) NOT NULL, + `AP_DEVICE_SUBSCRIPTION_ID` INT(11) NOT NULL, + PRIMARY KEY (`ID`), + INDEX `fk_AP_APP_OP_DEVICE_MAPPING_AP_DEVICE_SUBSCRIPTION1_idx` (`AP_DEVICE_SUBSCRIPTION_ID` ASC), + CONSTRAINT `fk_AP_APP_OP_DEVICE_MAPPING_AP_DEVICE_SUBSCRIPTION1` + FOREIGN KEY (`AP_DEVICE_SUBSCRIPTION_ID`) + REFERENCES `APP_MANAGER`.`AP_DEVICE_SUBSCRIPTION` (`ID`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8;