diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java new file mode 100644 index 0000000000..b2445fcf7f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +public class BasePaginatedResult { + + @ApiModelProperty( + value = "Number of total resources.", + example = "1") + @JsonProperty("count") + private long count; + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java new file mode 100644 index 0000000000..26e73d2dc1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "BasicUserInfo", description = "Basic user information and the roles of the user.") +public class BasicUserInfo { + + @ApiModelProperty(name = "username", value = "The login name of the user.", required = true ) + private String username; + @ApiModelProperty(name = "firstname", value = "The first name of the user.", required = true ) + private String firstname; + @ApiModelProperty(name = "lastname", value = "The last name of the user.", required = true ) + private String lastname; + @ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true ) + private String emailAddress; + @ApiModelProperty(name = "createdDate", value = "User creation date." ) + private String createdDate; + @ApiModelProperty(name = "modifiedDate", value = "User modifiedDate date." ) + private String modifiedDate; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + public String getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(String createdDate) { + this.createdDate = createdDate; + } + + public String getModifiedDate() { + return modifiedDate; + } + + public void setModifiedDate(String modifiedDate) { + this.modifiedDate = modifiedDate; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java new file mode 100644 index 0000000000..3f4762e3cb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "BasicUserInfoList", description = "This contains basic details of a set of users that matches " + + "a given criteria as a collection") +public class BasicUserInfoList extends BasePaginatedResult { + + private List users = new ArrayList<>(); + + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("users") + public List getList() { + return users; + } + + public void setList(List users) { + this.users = users; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" users: [").append(users).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java new file mode 100644 index 0000000000..698d29ee44 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceGroupList extends BasePaginatedResult { + + @ApiModelProperty(value = "List of device groups returned") + @JsonProperty("groups") + private List deviceGroups = new ArrayList<>(); + + public List getList() { + return deviceGroups; + } + + public void setList(List deviceGroups) { + this.deviceGroups = deviceGroups; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" groups: [").append(deviceGroups).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java new file mode 100644 index 0000000000..94f81e153c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceList extends BasePaginatedResult { + + private List devices = new ArrayList<>(); + + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("devices") + public List getList() { + return devices; + } + + public void setList(List devices) { + this.devices = devices; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" devices: [").append(devices).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java new file mode 100644 index 0000000000..183f196c8c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "Role List") +public class RoleList extends BasePaginatedResult { + + private List roles; + + @ApiModelProperty(value = "Returns the list of roles that match the offset and limit parameter values " + + "that were specified.") + @JsonProperty("roles") + + public List getList() { + return roles; + } + + public void setList(List roles) { + this.roles = roles; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" roles: [").append(roles).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java index 3f2866e8f7..cba18e6733 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java @@ -23,21 +23,22 @@ import java.util.HashMap; import java.util.Map; public class SubscribingDeviceIdHolder { - private Map subscribedDevices = new HashMap<>(); - private Map subscribableDevices = new HashMap<>(); - public Map getSubscribedDevices() { - return subscribedDevices; + private Map appInstalledDevices = new HashMap<>(); + private Map appInstallableDevices = new HashMap<>(); + + public Map getAppInstalledDevices() { + return appInstalledDevices; } - public void setSubscribedDevices(Map subscribedDevices) { - this.subscribedDevices = subscribedDevices; + public void setAppInstalledDevices(Map appInstalledDevices) { + this.appInstalledDevices = appInstalledDevices; } - public Map getSubscribableDevices() { - return subscribableDevices; + public Map getAppInstallableDevices() { + return appInstallableDevices; } - public void setSubscribableDevices(Map subscribableDevices) { - this.subscribableDevices = subscribableDevices; + public void setAppInstallableDevices(Map appInstallableDevices) { + this.appInstallableDevices = appInstallableDevices; } } 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 03c970d5fb..f8ed72b586 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 @@ -23,6 +23,7 @@ import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.mgt.common.PaginationResult; import java.util.List; @@ -83,4 +84,30 @@ public interface SubscriptionManager { * @throws SubscriptionManagementException if error occurred while updating the status of the subscription */ void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws SubscriptionManagementException; + + /*** + * This method used to get the app id ,device ids and pass them to DM service method. + * + * @param appUUID UUID of the application release. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param status status of the devices. + * @return deviceDetails - device details for given application release. + * @throws {@link ApplicationManagementException} Exception of the application management + */ + PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, + String status) throws ApplicationManagementException; + + /*** + * This method used to get category details. + * + * @param appUUID UUID of the application release. + * @param subType subscription type of the application. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @return {@link PaginationResult} pagination result of the category details. + * @throws {@link ApplicationManagementException} Exception of the application management + */ + PaginationResult getAppInstalledCategories(int offsetValue, int limitValue, String appUUID, + String subType) 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 e6ff3a3f53..5c952f8042 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 @@ -83,8 +83,8 @@ public interface SubscriptionDAO { List getDeviceSubscriptions(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; - Map getDeviceSubscriptions(List deviceIds, int tenantId) throws - ApplicationManagementDAOException; + Map getDeviceSubscriptions(List deviceIds, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException; List getSubscribedUserNames(List users, int tenantId) throws ApplicationManagementDAOException; @@ -168,6 +168,46 @@ public interface SubscriptionDAO { * @return {@link ScheduledSubscriptionDTO} * @throws ApplicationManagementDAOException if error occurred while retrieving the subscription */ - ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) + ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of users + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated result + * @param limitValue limit value for get paginated result + * @param appReleaseId id of the application release. + * @return subscribedUsers - list of app subscribed users. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of roles + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param appReleaseId id of the application release. + * @return subscribedRoles - list of app subscribed roles. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of subscribed groups + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param appReleaseId id of the application release. + * @return subscribedGroups - list of app subscribed groups. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, 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/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 8eb297f4da..53c44e73a7 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 @@ -356,6 +356,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.STATUS AS STATUS," + "DS.DM_DEVICE_ID AS DEVICE_ID " + "FROM AP_DEVICE_SUBSCRIPTION DS " + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; @@ -385,7 +386,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public Map getDeviceSubscriptions(List deviceIds, int tenantId) + public Map getDeviceSubscriptions(List deviceIds, int appReleaseId, + int tenantId) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to get device subscriptions for given device ids."); @@ -406,13 +408,14 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc + "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 = ?"); + + "WHERE DS.DM_DEVICE_ID IN (", ") AND AP_APP_RELEASE_ID = ? 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++, appReleaseId); ps.setInt(index, tenantId); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { @@ -575,8 +578,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc for (Integer deviceId : deviceIds) { ps.setObject(index++, deviceId); } - ps.setInt(index++, tenantId); - ps.setInt(index, applicationReleaseId); + ps.setInt(index++, applicationReleaseId); + ps.setInt(index, tenantId); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { subscribedDevices.add(rs.getInt("DM_DEVICE_ID")); @@ -847,6 +850,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } } + public List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedUsers = new ArrayList<>(); + String sql = "SELECT " + + "US.USER_NAME AS USER " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, appReleaseId); + stmt.setInt(2, tenantId); + stmt.setInt(3, offsetValue); + stmt.setInt(4, limitValue); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER")); + } + } + return subscribedUsers; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + @Override public List getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted) throws ApplicationManagementDAOException { @@ -916,6 +958,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } } + public List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed roles for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedRoles = new ArrayList<>(); + String sql = "SELECT " + + "US.ROLE_NAME AS ROLE " + + "FROM AP_ROLE_SUBSCRIPTION US " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedRoles.add(rs.getString("ROLE")); + } + } + return subscribedRoles; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + @Override public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) throws ApplicationManagementDAOException { @@ -955,4 +1036,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + @Override + public List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed groups for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedGroups = new ArrayList<>(); + String sql = "SELECT " + + "GS.GROUP_NAME AS GROUPS " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedGroups.add(rs.getString("GROUPS")); + } + } + return subscribedGroups; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed groups for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed groups for given " + + "app release id."; + log.error(msg, e); + 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/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 7d7d18b896..c8e22bc69c 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 @@ -18,9 +18,6 @@ package org.wso2.carbon.device.application.mgt.core.impl; import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; @@ -77,7 +74,6 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.ActivityStatus; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; -import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature; 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; @@ -86,6 +82,7 @@ import org.wso2.carbon.device.mgt.core.util.MDMAndroidOperationUtil; import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.device.mgt.common.PaginationResult; import javax.ws.rs.core.MediaType; import java.io.IOException; @@ -346,35 +343,45 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + /*** + * This method perform given action (i.e APP INSTALL or APP UNINSTALL) on given set of devices. + * + * @param deviceType Application supported device type. + * @param devices List of devices that action is triggered. + * @param applicationDTO Application data + * @param subType Subscription type (i.e USER, ROLE, GROUP or DEVICE) + * @param subscribers Subscribers + * @param action Performing action. (i.e INSTALL or UNINSTALL) + * @return {@link ApplicationInstallResponse} + * @throws ApplicationManagementException if error occured when adding operation on device or updating subscription + * data. + */ private ApplicationInstallResponse performActionOnDevices(String deviceType, List devices, ApplicationDTO applicationDTO, String subType, List subscribers, String action) throws ApplicationManagementException { - SubscribingDeviceIdHolder subscribingDeviceIdHolder = getSubscribingDeviceIdHolder(devices); + SubscribingDeviceIdHolder subscribingDeviceIdHolder = getSubscribingDeviceIdHolder(devices, + applicationDTO.getApplicationReleaseDTOs().get(0).getId()); List activityList = new ArrayList<>(); List deviceIdentifiers = new ArrayList<>(); List ignoredDeviceIdentifiers = new ArrayList<>(); Map> deviceIdentifierMap = new HashMap<>(); if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { - deviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getSubscribableDevices().keySet()); - ignoredDeviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getSubscribedDevices().keySet()); - - if (deviceIdentifiers.isEmpty()) { - ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); - applicationInstallResponse.setIgnoredDeviceIdentifiers(ignoredDeviceIdentifiers); - return applicationInstallResponse; - } + deviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getAppInstallableDevices().keySet()); + ignoredDeviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getAppInstalledDevices().keySet()); } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { - deviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getSubscribedDevices().keySet()); - ignoredDeviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getSubscribableDevices().keySet()); - if (deviceIdentifiers.isEmpty()) { - ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); - applicationInstallResponse.setIgnoredDeviceIdentifiers(ignoredDeviceIdentifiers); - return applicationInstallResponse; - } + deviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getAppInstalledDevices().keySet()); + ignoredDeviceIdentifiers = new ArrayList<>(subscribingDeviceIdHolder.getAppInstallableDevices().keySet()); + } + + if (deviceIdentifiers.isEmpty()) { + ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); + applicationInstallResponse.setIgnoredDeviceIdentifiers(ignoredDeviceIdentifiers); + return applicationInstallResponse; } + //device type is getting null when we try to perform action on Web Clip. if (deviceType == null) { for (DeviceIdentifier identifier : deviceIdentifiers) { List identifiers; @@ -417,28 +424,37 @@ public class SubscriptionManagerImpl implements SubscriptionManager { return applicationInstallResponse; } - private SubscribingDeviceIdHolder getSubscribingDeviceIdHolder(List devices) + /*** + * Filter given devices and davide given list of device into two sets, those are already application installed + * devices and application installable devices. + * + * @param devices List of {@link Device} + * @param appReleaseId Application release id. + * @return {@link SubscribingDeviceIdHolder} + * @throws ApplicationManagementException if error occured while getting device subscriptions for applicaion. + */ + private SubscribingDeviceIdHolder getSubscribingDeviceIdHolder(List devices, int appReleaseId) throws ApplicationManagementException { - Map subscribedDevices = new HashMap<>(); - Map subscribableDevices = new HashMap<>(); + Map appInstalledDevices = new HashMap<>(); + Map appInstallableDevices = new HashMap<>(); - List filteredDeviceIds = devices.stream().map(Device::getId).collect(Collectors.toList()); + List deviceIds = devices.stream().map(Device::getId).collect(Collectors.toList()); //get device subscriptions for given device id list. - Map deviceSubscriptions = getDeviceSubscriptions(filteredDeviceIds); + Map deviceSubscriptions = getDeviceSubscriptions(deviceIds, appReleaseId); for (Device device : devices) { 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())) { - subscribedDevices.put(deviceIdentifier, device.getId()); + appInstalledDevices.put(deviceIdentifier, device.getId()); } else { - subscribableDevices.put(deviceIdentifier, device.getId()); + appInstallableDevices.put(deviceIdentifier, device.getId()); } } SubscribingDeviceIdHolder subscribingDeviceIdHolder = new SubscribingDeviceIdHolder(); - subscribingDeviceIdHolder.setSubscribableDevices(subscribableDevices); - subscribingDeviceIdHolder.setSubscribedDevices(subscribedDevices); + subscribingDeviceIdHolder.setAppInstallableDevices(appInstallableDevices); + subscribingDeviceIdHolder.setAppInstalledDevices(appInstalledDevices); return subscribingDeviceIdHolder; } @@ -458,6 +474,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + /*** + * Get Application with application release which has given UUID. + * + * @param uuid UUID of the application release. + * @return {@link ApplicationDTO} + * @throws ApplicationManagementException if error occurred while getting application data from database or + * verifying whether application is in installable state. + */ private ApplicationDTO getApplicationDTO(String uuid) throws ApplicationManagementException { ApplicationDTO applicationDTO; int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -531,7 +555,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { for (Activity activity : activities) { int operationId = Integer.parseInt(activity.getActivityId().split("ACTIVITY_")[1]); List operationAddedDeviceIds = getOperationAddedDeviceIds(activity, - subscribingDeviceIdHolder.getSubscribableDevices()); + subscribingDeviceIdHolder.getAppInstallableDevices()); List alreadySubscribedDevices = subscriptionDAO .getSubscribedDeviceIds(operationAddedDeviceIds, applicationReleaseId, tenantId); if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { @@ -548,7 +572,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { deviceSubIds.addAll(subscribingDevices); } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action) && !alreadySubscribedDevices.isEmpty()) { List deviceResubscribingIds = subscriptionDAO - .updateDeviceSubscription(username, alreadySubscribedDevices, false, subType, + .updateDeviceSubscription(username, alreadySubscribedDevices, true, subType, Operation.Status.PENDING.toString(), applicationReleaseId, tenantId); deviceSubIds.addAll(deviceResubscribingIds); } @@ -586,13 +610,13 @@ public class SubscriptionManagerImpl implements SubscriptionManager { return deviceIds; } - private Map getDeviceSubscriptions(List filteredDeviceIds) + private Map getDeviceSubscriptions(List deviceIds, int appReleaseId) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { ConnectionManagerUtil.openDBConnection(); - return this.subscriptionDAO.getDeviceSubscriptions(filteredDeviceIds, tenantId); + return this.subscriptionDAO.getDeviceSubscriptions(deviceIds, appReleaseId, tenantId); } catch (ApplicationManagementDAOException e) { String msg = "Error occured when getting device subscriptions for given device IDs"; log.error(msg, e); @@ -661,6 +685,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { app.setLocation(application.getApplicationReleases().get(0).getInstallerPath()); return MDMAndroidOperationUtil.createInstallAppOperation(app); } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + app.setType(mobileAppType); return MDMAndroidOperationUtil.createAppUninstallOperation(app); } else { String msg = "Invalid Action is found. Action: " + action; @@ -770,10 +795,117 @@ public class SubscriptionManagerImpl implements SubscriptionManager { log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (IOException e) { - String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO() - .getId() + " on device"; + String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO().getId() + + " on device"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + @Override + public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, + String status) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(appUUID, tenantId); + int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); + + List deviceSubscriptionDTOS = subscriptionDAO + .getDeviceSubscriptions(applicationReleaseId, tenantId); + if (deviceSubscriptionDTOS.isEmpty()) { + String msg = "Couldn't found an subscribed devices for application release id: " + + applicationReleaseId; + log.info(msg); + } + List deviceIdList = new ArrayList<>(); + for (DeviceSubscriptionDTO deviceIds : deviceSubscriptionDTOS) { + deviceIdList.add(deviceIds.getDeviceId()); + } + //pass the device id list to device manager service method + try { + PaginationResult deviceDetails = deviceManagementProviderService + .getAppSubscribedDevices(offsetValue ,limitValue, deviceIdList, status); + + if (deviceDetails == null) { + String msg = "Couldn't found an subscribed devices details for device ids: " + + deviceIdList; + log.error(msg); + throw new NotFoundException(msg); + } + return deviceDetails; + + } catch (DeviceManagementException e) { + String msg = "service error occurred while getting data from the service"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when get application release data for application" + + " release UUID: " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting device details that " + + "given application id"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAppInstalledCategories(int offsetValue, int limitValue, + String appUUID, String subType) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + PaginationResult paginationResult = new PaginationResult(); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO + .getAppWithRelatedRelease(appUUID, tenantId); + int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); + + int count = 0; + List SubscriptionList = new ArrayList<>(); + + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + SubscriptionList = subscriptionDAO + .getAppSubscribedUsers(offsetValue, limitValue, applicationReleaseId, tenantId); + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + SubscriptionList = subscriptionDAO + .getAppSubscribedRoles(offsetValue, limitValue, applicationReleaseId, tenantId); + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + SubscriptionList = subscriptionDAO + .getAppSubscribedGroups(offsetValue, limitValue, applicationReleaseId, tenantId); + } + count = SubscriptionList.size(); + paginationResult.setData(SubscriptionList); + paginationResult.setRecordsFiltered(count); + paginationResult.setRecordsTotal(count); + + return paginationResult; + + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when get application release data for application" + + " release UUID: " + appUUID; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting category details that " + + "given application id"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); } } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.css index c0484b7a41..63cb9777e6 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.css +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.css @@ -58,7 +58,7 @@ } .mobile-menu-button{ - margin-top: 4%; + margin-top: 15px; } Header{ @@ -68,7 +68,7 @@ } .dashboard-body{ - margin-top: 14%; + margin-top: 50px; } .logo-image { @@ -80,7 +80,7 @@ @media screen and (max-height: 350px) { .mobile-menu-button{ - margin-top: 2%; + margin-top: 15px; } .dashboard-body{ margin-top: 9%; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js index 8965e32fe2..5cd6ce5de5 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js @@ -40,14 +40,14 @@ class Dashboard extends React.Component { this.Logo = this.config.theme.logo; } - showDrawer = () => { + showMobileNavigationBar = () => { this.setState({ visible: true, collapsed: !this.state.collapsed }); }; - onClose = () => { + onCloseMobileNavigationBar = () => { this.setState({ visible: false, }); @@ -131,7 +131,7 @@ class Dashboard extends React.Component {
-
@@ -146,7 +146,7 @@ class Dashboard extends React.Component { } placement="left" closable={false} - onClose={this.onClose} + onClose={this.onCloseMobileNavigationBar} visible={this.state.visible} getContainer={false} style={{position: 'absolute'}}> @@ -214,6 +214,6 @@ class Dashboard extends React.Component { ); } -} +}; export default withConfigContext(Dashboard); \ No newline at end of file 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 937a4f55ba..1af6b2276d 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 @@ -20,6 +20,7 @@ package org.wso2.carbon.device.application.mgt.store.api.services; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import io.swagger.annotations.Extension; import io.swagger.annotations.ExtensionProperty; @@ -27,15 +28,17 @@ import io.swagger.annotations.Info; 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.ErrorResponse; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import javax.validation.Valid; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; +import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.PathParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; @@ -181,4 +184,133 @@ public interface SubscriptionManagementAPI { ) @QueryParam("timestamp") String timestamp ); + + @GET + @Path("/{uuid}/devices") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get device details that have a given application install", + notes = "This will get the device details that have a given application install, if exists", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved device details.", + response = List.class, + responseContainer = "List"), + @ApiResponse( + code = 404, + message = "Not Found. \n No Application found which has application release of UUID.", + response = ErrorResponse.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Found invalid payload with the request.", + response = List.class), + @ApiResponse( + code = 403, + message = "Forbidden. \n Don't have permission to get the details.", + response = List.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting data", + response = ErrorResponse.class) + }) + Response getAppInstalledDevices( + @ApiParam( + name="uuid", + value="uuid of the application release.", + required = true) + @PathParam("uuid") String uuid, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") int limit, + @ApiParam( + name = "status", + value = "Provide the device status details, such as active or inactive.") + @QueryParam("status") String status + ); + + @GET + @Path("/{uuid}/{subType}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get category details that have a given application install", + notes = "This will get the category details that have a given application install, if exists", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved categories details.", + response = List.class, + responseContainer = "List"), + @ApiResponse( + code = 404, + message = "Not Found. \n No Application found which has application " + + "release of UUID.", + response = ErrorResponse.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Found invalid payload with the request.", + response = List.class), + @ApiResponse( + code = 403, + message = "Forbidden. \n Don't have permission to get the details.", + response = List.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting data", + response = ErrorResponse.class) + }) + Response getAppInstalledCategories( + @ApiParam( + name="uuid", + value="uuid of the application release.", + required = true) + @PathParam("uuid") String uuid, + @ApiParam( + name="subType", + value="Subscription type of the application release.", + required = true) + @PathParam("subType") String subType, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting " + + "pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") int limit + ); } 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 ad7bfd8d62..11bdf94873 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 @@ -1,21 +1,3 @@ -/* - * Copyright (c) 2017, 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. - */ - /* * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. * @@ -46,20 +28,31 @@ import org.wso2.carbon.device.application.mgt.common.SubscriptionType; 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.exception.ApplicationOperationTaskException; +import org.wso2.carbon.device.application.mgt.common.DeviceList; +import org.wso2.carbon.device.application.mgt.common.BasicUserInfo; +import org.wso2.carbon.device.application.mgt.common.BasicUserInfoList; +import org.wso2.carbon.device.application.mgt.common.RoleList; +import org.wso2.carbon.device.application.mgt.common.DeviceGroupList; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.application.mgt.common.SubsciptionType; 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.task.ScheduledAppSubscriptionTaskManager; import org.wso2.carbon.device.application.mgt.core.util.APIUtil; import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI; +import org.wso2.carbon.device.mgt.common.Device; 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.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.PathParam; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.core.Response; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -114,6 +107,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ } } + @Override @POST @Path("/{uuid}/{subType}/{action}") @@ -185,4 +179,114 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ } return Response.status(Response.Status.CREATED).build(); } + + @GET + @Consumes("application/json") + @Produces("application/json") + @Path("/{uuid}/devices") + public Response getAppInstalledDevices(@PathParam("uuid") String uuid, + @DefaultValue("0") + @QueryParam("offset") int offset, + @DefaultValue("5") + @QueryParam("limit") int limit, + @QueryParam("status") String status) { + + try { + SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); + + PaginationResult subscribedDeviceDetails = subscriptionManager + .getAppInstalledDevices(offset, limit, uuid, status); + + DeviceList devices = new DeviceList(); + + devices.setList((List) subscribedDeviceDetails.getData()); + devices.setCount(subscribedDeviceDetails.getRecordsTotal()); + + return Response.status(Response.Status.OK).entity(devices).build(); + } catch (NotFoundException e) { + String msg = "Application with application release UUID: " + uuid + " is not found"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (BadRequestException e) { + String msg = "Found invalid payload for getting application which has UUID: " + uuid + + ". Hence verify the payload"; + log.error(msg, e); + 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 get the devices details."; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application with the application release uuid: " + + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Consumes("application/json") + @Produces("application/json") + @Path("/{uuid}/{subType}") + public Response getAppInstalledCategories(@PathParam("uuid") String uuid, + @PathParam("subType") String subType, + @DefaultValue("0") + @QueryParam("offset") int offset, + @DefaultValue("5") + @QueryParam("limit") int limit) { + + try { + SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); + + PaginationResult subscribedCategoryDetails = subscriptionManager + .getAppInstalledCategories(offset, limit, uuid, subType); + + if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) { + BasicUserInfoList users = new BasicUserInfoList(); + + users.setList((List) subscribedCategoryDetails.getData()); + users.setCount(subscribedCategoryDetails.getRecordsTotal()); + + return Response.status(Response.Status.OK).entity(users).build(); + } else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) { + RoleList roles = new RoleList(); + + roles.setList(subscribedCategoryDetails.getData()); + roles.setCount(subscribedCategoryDetails.getRecordsTotal()); + + return Response.status(Response.Status.OK).entity(roles).build(); + } else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) { + DeviceGroupList groups = new DeviceGroupList(); + + groups.setList(subscribedCategoryDetails.getData()); + groups.setCount(subscribedCategoryDetails.getRecordsTotal()); + + return Response.status(Response.Status.OK).entity(groups).build(); + } else { + String msg = "Found invalid sub type "; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } + } catch (NotFoundException e) { + String msg = "Application with application release UUID: " + uuid + " is not found"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (BadRequestException e) { + String msg = "Found invalid payload for getting application which has UUID: " + uuid + + ". Hence verify the payload"; + log.error(msg, e); + 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 get the devices details."; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application with the application " + + "release uuid: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js index 5409e3f853..33d6afaca8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js @@ -25,6 +25,7 @@ import DetailedRating from "./DetailedRating"; import Reviews from "./review/Reviews"; import axios from "axios"; import AppInstallModal from "./install/AppInstallModal"; +import AppUninstallModal from "./install/AppUninstallModal"; import CurrentUsersReview from "./review/CurrentUsersReview"; import {withConfigContext} from "../../../context/ConfigContext"; import {handleApiError} from "../../../js/Utils"; @@ -36,11 +37,12 @@ class ReleaseView extends React.Component { super(props); this.state = { loading: false, - appInstallModalVisible: false + appInstallModalVisible: false, + appUninstallModalVisible: false } } - installApp = (type, payload) => { + appOperation = (type, payload, operation) => { const config = this.props.context; const release = this.props.app.applicationReleases[0]; const {uuid} = release; @@ -48,7 +50,7 @@ class ReleaseView extends React.Component { this.setState({ loading: true, }); - const url = window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/install"; + const url = window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/" + operation; axios.post( url, payload, @@ -64,7 +66,7 @@ class ReleaseView extends React.Component { notification["success"]({ message: 'Done!', description: - 'App installed triggered.', + 'App '+operation+'ed triggered.', }); } else { this.setState({ @@ -74,24 +76,31 @@ class ReleaseView extends React.Component { message: "There was a problem", duration: 0, description: - "Error occurred while installing app", + "Error occurred while "+operation+"ing app", }); } - }).catch((error) => { - handleApiError(error,"Error occurred while installing the app."); + handleApiError(error,"Error occurred while "+operation+"ing the app."); }); }; + showAppInstallModal = () => { this.setState({ appInstallModalVisible: true }); }; - closeAppInstallModal = () => { + closeAppOperationModal = () => { this.setState({ - appInstallModalVisible: false + appInstallModalVisible: false, + appUninstallModalVisible: false + }); + }; + + showAppUninstallModal = () => { + this.setState({ + appUninstallModalVisible: true }); }; @@ -112,8 +121,14 @@ class ReleaseView extends React.Component { uuid={release.uuid} visible={this.state.appInstallModalVisible} deviceType = {deviceType} - onClose={this.closeAppInstallModal} - onInstall={this.installApp}/> + onClose={this.closeAppOperationModal} + onInstall={this.appOperation}/> +
@@ -138,6 +153,12 @@ class ReleaseView extends React.Component { htmlType="button" type="primary" icon="download">Install
+
+ + + +
@@ -179,4 +200,4 @@ class ReleaseView extends React.Component { } } -export default withConfigContext(ReleaseView); \ No newline at end of file +export default withConfigContext(ReleaseView); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/AppUninstallModal.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/AppUninstallModal.js new file mode 100644 index 0000000000..14a729466a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/AppUninstallModal.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from "react"; +import {Modal, Tabs} from "antd"; +import DeviceUninstall from "./DeviceUninstall"; +import UserUninstall from "./UserUninstall"; +import RoleUninstall from "./RoleUninstall"; +import GroupUninstall from "./GroupUninstall"; + +const { TabPane } = Tabs; + +class AppUninstallModal extends React.Component{ + state={ + data:[] + }; + render() { + const {deviceType} = this.props; + return ( +
+ + + + + + + + + + + + + + + + +
+ ); + } +} + +export default AppUninstallModal; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js index 4b7f11bbd2..14fbb0ce67 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js @@ -196,7 +196,7 @@ class DeviceInstall extends React.Component { type: device.type }); }); - this.props.onInstall("devices", payload); + this.props.onInstall("devices", payload, "install"); }; render() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceUninstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceUninstall.js new file mode 100644 index 0000000000..f9d30db39f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceUninstall.js @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {Button,Table, Typography} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../../../context/ConfigContext"; +import {handleApiError} from "../../../../js/Utils"; + +const {Text} = Typography; +const columns = [ + { + title: 'Device', + dataIndex: 'name', + fixed: 'left', + width: 100, + }, + { + title: 'Modal', + dataIndex: 'deviceInfo', + key: 'modal', + render: deviceInfo => `${deviceInfo.vendor} ${deviceInfo.deviceModel}` + // todo add filtering options + }, + { + title: 'Owner', + dataIndex: 'enrolmentInfo', + key: 'owner', + render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Last Updated', + dataIndex: 'enrolmentInfo', + key: 'dateOfLastUpdate', + render: (data) => { + return (getTimeAgo(data.dateOfLastUpdate)); + } + // todo add filtering options + }, + { + title: 'Status', + dataIndex: 'enrolmentInfo', + key: 'status', + render: enrolmentInfo => enrolmentInfo.status + // todo add filtering options + }, + { + title: 'Ownership', + dataIndex: 'enrolmentInfo', + key: 'ownership', + render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'OS Version', + dataIndex: 'deviceInfo', + key: 'osVersion', + render: deviceInfo => deviceInfo.osVersion + // todo add filtering options + }, + { + title: 'IMEI', + dataIndex: 'properties', + key: 'imei', + render: properties => { + let imei = "not-found"; + for (let i = 0; i < properties.length; i++) { + if (properties[i].name === "IMEI") { + imei = properties[i].value; + } + } + return imei; + } + // todo add filtering options + }, +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class DeviceUninstall extends React.Component { + constructor(props) { + super(props); + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + }, + getCheckboxProps: record => ({ + disabled: record.name === 'Disabled User', // Column configuration not to be checked + name: record.name, + }), + }; + + componentDidMount() { + this.fetch(); + } + + //fetch data from api + fetch = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + const {deviceType} = this.props; + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + status: "ACTIVE", + }; + + if (deviceType !== 'ANY') { + extraParams.type = deviceType; + } + + // note: encode with '%26' not '&' + const encodedExtraParams = Object.keys(extraParams).map(key => key + '=' + extraParams[key]).join('&'); + + const uuid = this.props.uuid; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/"+ + "/devices?" + encodedExtraParams, + ).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.devices, + pagination, + }); + } + }).catch((error) => { + handleApiError(error,"Error occurred while trying to load devices."); + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + uninstall = () => { + const {selectedRows} = this.state; + const payload = []; + selectedRows.map(device => { + payload.push({ + id: device.deviceIdentifier, + type: device.type + }); + }); + this.props.onUninstall("devices", payload, "uninstall"); + }; + + render() { + const {data, pagination, loading, selectedRows} = this.state; + return ( +
+ + Start uninstalling the application for devices by selecting the corresponding devices. + Select uninstall to automatically start uninstalling the application for the respective devices. + + record.deviceIdentifier} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices` + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + scroll={{x: 1000}} + /> +
+ +
+ + ); + } +} + +export default withConfigContext(DeviceUninstall); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupInstall.js index 44024687a2..47d3b628c4 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupInstall.js @@ -47,7 +47,7 @@ class GroupInstall extends React.Component { const config = this.props.context; this.setState({data: [], fetching: true}); - axios.post( + axios.get( window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt+"/groups?name=" + value, ).then(res => { @@ -85,7 +85,7 @@ class GroupInstall extends React.Component { value.map(val=>{ data.push(val.key); }); - this.props.onInstall("group",data); + this.props.onInstall("group", data, "install"); }; render() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupUninstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupUninstall.js new file mode 100644 index 0000000000..f3aeebc974 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/GroupUninstall.js @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import {Typography, Select, Spin, message, notification, Button} from "antd"; +import debounce from 'lodash.debounce'; +import axios from "axios"; +import {withConfigContext} from "../../../../context/ConfigContext"; +import {handleApiError} from "../../../../js/Utils"; + +const {Text} = Typography; +const {Option} = Select; + +class GroupUninstall extends React.Component { + + constructor(props) { + super(props); + this.lastFetchId = 0; + this.fetchUser = debounce(this.fetchUser, 800); + } + + state = { + data: [], + value: [], + fetching: false, + }; + + fetchUser = value => { + this.lastFetchId += 1; + const fetchId = this.lastFetchId; + const config = this.props.context; + this.setState({data: [], fetching: true}); + + const uuid = this.props.uuid; + + axios.get( + window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+ + "/GROUP?", + + ).then(res => { + if (res.status === 200) { + if (fetchId !== this.lastFetchId) { + // for fetch callback order + return; + } + + const data = res.data.data.deviceGroups.map(group => ({ + text: group, + value: group, + })); + + this.setState({data, fetching: false}); + } + + }).catch((error) => { + handleApiError(error,"Error occurred while trying to load groups."); + this.setState({fetching: false}); + }); + }; + + handleChange = value => { + this.setState({ + value, + data: [], + fetching: false, + }); + }; + + install = () =>{ + const {value} = this.state; + const data = []; + value.map(val=>{ + data.push(val.key); + }); + this.props.onInstall("group", data, "uninstall"); + }; + + render() { + + const {fetching, data, value} = this.state; + + return ( +
+ Start uninstalling the application for one or more groups by entering the corresponding group name. Select uninstall to automatically start uninstalling the application for the respective device group/ groups. +
+
+ +
+ +
+
+ ); + } +} + +export default withConfigContext(GroupUninstall); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js index 0f6da0f2d7..b9edba286e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js @@ -85,7 +85,7 @@ class RoleInstall extends React.Component { value.map(val=>{ data.push(val.key); }); - this.props.onInstall("role",data); + this.props.onInstall("role", data, "install"); }; render() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleUninstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleUninstall.js new file mode 100644 index 0000000000..53c3a6c557 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleUninstall.js @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import {Typography, Select, Spin, message, notification, Button} from "antd"; +import debounce from 'lodash.debounce'; +import axios from "axios"; +import {withConfigContext} from "../../../../context/ConfigContext"; +import {handleApiError} from "../../../../js/Utils"; + +const {Text} = Typography; +const {Option} = Select; + +class RoleUninstall extends React.Component { + + constructor(props) { + super(props); + this.lastFetchId = 0; + this.fetchUser = debounce(this.fetchUser, 800); + } + + state = { + data: [], + value: [], + fetching: false, + }; + + fetchUser = value => { + const config = this.props.context; + this.lastFetchId += 1; + const fetchId = this.lastFetchId; + this.setState({data: [], fetching: true}); + + const uuid = this.props.uuid; + + axios.get( + window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+ + "/ROLE?", + ).then(res => { + if (res.status === 200) { + if (fetchId !== this.lastFetchId) { + // for fetch callback order + return; + } + + const data = res.data.data.roles.map(role => ({ + text: role, + value: role, + })); + + this.setState({data, fetching: false}); + } + + }).catch((error) => { + handleApiError(error,"Error occurred while trying to load roles."); + this.setState({fetching: false}); + }); + }; + + handleChange = value => { + this.setState({ + value, + data: [], + fetching: false, + }); + }; + + install = () =>{ + const {value} = this.state; + const data = []; + value.map(val=>{ + data.push(val.key); + }); + this.props.onInstall("role", data, "uninstall"); + }; + + render() { + + const {fetching, data, value} = this.state; + + return ( +
+ Start uninstalling the application for one or more roles by entering the corresponding role name. Select uninstall to automatically start uninstalling the application for the respective user role/roles. +
+
+ +
+ +
+
+ ); + } +} + +export default withConfigContext(RoleUninstall); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js index d04d11a24c..7be794f9ae 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js @@ -87,7 +87,7 @@ class UserInstall extends React.Component { value.map(val => { data.push(val.key); }); - this.props.onInstall("user", data); + this.props.onInstall("user", data, "install"); }; render() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserUninstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserUninstall.js new file mode 100644 index 0000000000..5c68455abd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserUninstall.js @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import {Typography, Select, Spin, message, notification, Button} from "antd"; +import debounce from 'lodash.debounce'; +import axios from "axios"; +import {withConfigContext} from "../../../../context/ConfigContext"; +import {handleApiError} from "../../../../js/Utils"; + +const {Text} = Typography; +const {Option} = Select; + +class UserUninstall extends React.Component { + + constructor(props) { + super(props); + this.lastFetchId = 0; + this.fetchUser = debounce(this.fetchUser, 800); + } + + state = { + data: [], + value: [], + fetching: false, + }; + + fetchUser = (value) => { + const config = this.props.context; + this.lastFetchId += 1; + const fetchId = this.lastFetchId; + this.setState({data: [], fetching: true}); + + const uuid = this.props.uuid; + + axios.get( + window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+ + "/USER?", + + ).then(res => { + if (res.status === 200) { + if (fetchId !== this.lastFetchId) { + // for fetch callback order + return; + } + const data = res.data.data.users.map(user => ({ + text: user, + value: user, + })); + + this.setState({data, fetching: false}); + } + + }).catch((error) => { + handleApiError(error,"Error occurred while trying to load users."); + this.setState({fetching: false}); + }); + }; + + handleChange = value => { + this.setState({ + value, + data: [], + fetching: false, + }); + }; + + uninstall = () => { + const {value} = this.state; + const data = []; + value.map(val => { + data.push(val.key); + }); + this.props.onUninstall("user", data, "uninstall"); + }; + + render() { + const {fetching, data, value} = this.state; + + return ( +
+ Start uninstalling the application for one or more users by entering the corresponding user name. Select uninstall to automatically start uninstalling the application for the respective user/users. +

Select users

+ +
+ +
+
+ ); + } +} + +export default withConfigContext(UserUninstall); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.css index e1138ad3f5..c62c54c6b1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.css +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.css @@ -58,7 +58,7 @@ } .mobile-menu-button { - margin-top: 4%; + margin-top: 15px; } Header{ @@ -68,7 +68,7 @@ } .dashboard-body{ - margin-top: 15%; + margin-top: 50px; } .logo-image { @@ -80,7 +80,7 @@ @media only screen and (max-height: 350px) { .mobile-menu-button{ - margin-top: 2%; + margin-top: 15px; } .dashboard-body{ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js index 044dae5378..2ee3aba497 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js @@ -36,7 +36,9 @@ class Dashboard extends React.Component { this.state = { routes: props.routes, selectedKeys: [], - deviceTypes: [] + deviceTypes: [], + visible: false, + collapsed: false }; this.logo = this.props.context.theme.logo; } @@ -72,20 +74,14 @@ class Dashboard extends React.Component { }) }; - //functions for show the drawer - state = { - visible: false, - collapsed: false - }; - - showDrawer = () => { + showMobileNavigationBar = () => { this.setState({ visible: true, collapsed: !this.state.collapsed, }); }; - onClose = () => { + onCloseMobileNavigationBar = () => { this.setState({ visible: false, }); @@ -153,7 +149,7 @@ class Dashboard extends React.Component {
-
@@ -163,7 +159,7 @@ class Dashboard extends React.Component { } placement="left" closable={false} - onClose={this.onClose} + onClose={this.onCloseMobileNavigationBar} visible={this.state.visible} getContainer={false} style={{position: 'absolute'}} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/webapp/WEB-INF/web.xml index ca08169c8c..b1ae20d952 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/webapp/WEB-INF/web.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/webapp/WEB-INF/web.xml @@ -58,6 +58,10 @@ isSharedWithAllTenants true + + basicAuth + true + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/pom.xml b/components/device-mgt/io.entgra.device.mgt.ui/pom.xml index 9a02213c66..d2087ab084 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/pom.xml +++ b/components/device-mgt/io.entgra.device.mgt.ui/pom.xml @@ -29,8 +29,8 @@ io.entgra.device.mgt.ui 3.2.9-SNAPSHOT war - WSO2 Carbon - Device Management UI Component - http://wso2.org + Entgra - Device Management UI Component + https://entgra.io This Component contains Device Management UI diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java index 06e99cd74d..a5306c825f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java @@ -23,6 +23,7 @@ import io.swagger.annotations.ApiModelProperty; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.policy.mgt.DeviceGroupWrapper; +import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.List; @@ -102,6 +103,19 @@ public class PolicyWrapper { required = true) private List deviceGroups; + @ApiModelProperty(name = "policyType", value = "Type of the corresponding policy", + required = true) + @NotNull + private String policyType; + + public String getPolicyType() { + return policyType; + } + + public void setPolicyType(String policyType) { + this.policyType = policyType; + } + public Profile getProfile() { return profile; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 29c70b11a7..b2f032c762 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -469,17 +469,21 @@ public interface DeviceManagementService { String id, @ApiParam( name = "owner", - value = "The owner of the device you want ot get details.", - required = false) + value = "The owner of the device you want ot get details.") @QueryParam("owner") @Size(max = 100) String owner, + @ApiParam( + name = "ownership", + value = "Device ownership.") + @QueryParam("ownership") + @Size(max = 100) + String ownership, @ApiParam( name = "If-Modified-Since", value = "Checks if the requested variant was modified, since the specified date-time. \n" + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + - "Example: Mon, 05 Jan 2014 15:10:00 +0200", - required = false) + "Example: Mon, 05 Jan 2014 15:10:00 +0200") @HeaderParam("If-Modified-Since") String ifModifiedSince); @@ -1412,21 +1416,18 @@ public interface DeviceManagementService { name = "If-Modified-Since", value = "Checks if the requested variant was modified, since the specified date-time. \n" + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + - "Example: Mon, 05 Jan 2014 15:10:00 +0200", - required = false) + "Example: Mon, 05 Jan 2014 15:10:00 +0200") @HeaderParam("If-Modified-Since") String ifModifiedSince, @ApiParam( name = "offset", value = "The starting pagination index for the complete list of qualified items.", - required = false, defaultValue = "0") @QueryParam("offset") int offset, @ApiParam( name = "limit", value = "Provide how many activity details you require from the starting pagination index/offset.", - required = false, defaultValue = "5") @QueryParam("limit") int limit, @@ -1436,7 +1437,12 @@ public interface DeviceManagementService { required = true, defaultValue = "") @QueryParam("owner") - String owner); + String owner, + @ApiParam( + name = "ownership", + value = "Provides the ownership of the required device.") + @QueryParam("owner") + String ownership); @GET @Path("/{type}/{id}/effective-policy") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java index 0b25518d46..a438570798 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java @@ -697,4 +697,87 @@ public interface PolicyManagementService { @PathParam("deviceId") @Size(max = 45) String deviceId); + + @GET + @Path("/type/{policyType}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Policies", + responseContainer = "List", + notes = "Retrieve the details of all the policies filtered by policy type in WSO2 EMM.", + response = Policy.class, + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:get-details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched policies.", + response = Policy.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = ("Internal Server Error. \n Server error occurred while fetching the policies."), + response = ErrorResponse.class) + }) + Response getPolicies(@ApiParam( + name = "policyType", + value = "The policy type, such as general policy, Geo policy.", + required = true) + @PathParam("policyType") + String policyType, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many policy details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit + ); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 6e190e5d46..a5c2ca2024 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -36,6 +36,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -51,6 +52,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.Application; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; @@ -106,6 +108,7 @@ import javax.ws.rs.core.Response; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; @@ -383,8 +386,10 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @PathParam("type") @Size(max = 45) String type, @PathParam("id") @Size(max = 45) String id, @QueryParam("owner") @Size(max = 100) String owner, + @QueryParam("ownership") @Size(max = 100) String ownership, @HeaderParam("If-Modified-Since") String ifModifiedSince) { - Device device = null; + Device device; + Date sinceDate = null; try { RequestValidationUtil.validateDeviceIdentifier(type, id); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); @@ -399,61 +404,32 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + id + "'"; log.error(msg); return Response.status(Response.Status.UNAUTHORIZED).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_UNAUTHORIZED).setMessage(msg).build()).build(); } - Date sinceDate = null; - if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { + DeviceData deviceData = new DeviceData(); + deviceData.setDeviceIdentifier(deviceIdentifier); + + if (!StringUtils.isBlank(ifModifiedSince)){ SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); try { sinceDate = format.parse(ifModifiedSince); + deviceData.setLastModifiedDate(sinceDate); } catch (ParseException e) { + String msg = "Invalid date string is provided in 'If-Modified-Since' header"; + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + - "string is provided in 'If-Modified-Since' header").build()).build(); + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } } - if (!StringUtils.isEmpty(owner)) { - if (authorizedUser.equalsIgnoreCase(owner) || deviceAccessAuthorizationService.isDeviceAdminUser()) { - if (sinceDate != null) { - device = dms.getDevice(new DeviceIdentifier(id, type), owner, sinceDate, true); - if (device == null) { - return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + - "after the timestamp provided in 'If-Modified-Since' header").build(); - } - } else { - device = dms.getDevice(new DeviceIdentifier(id, type), owner, true); - } - } else { - String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + id + - "' which belongs to user '" + owner + "'"; - log.error(msg); - return Response.status(Response.Status.UNAUTHORIZED).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); - } - } else if (deviceAccessAuthorizationService.isDeviceAdminUser()) { - if (sinceDate != null) { - device = dms.getDevice(new DeviceIdentifier(id, type), sinceDate); - if (device == null) { - return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + - "after the timestamp provided in 'If-Modified-Since' header").build(); - } - } else { - device = dms.getDevice(new DeviceIdentifier(id, type)); - } - } else { - owner = authorizedUser; - if (sinceDate != null) { - device = dms.getDevice(new DeviceIdentifier(id, type), owner, sinceDate, true); - if (device == null) { - return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + - "after the timestamp provided in 'If-Modified-Since' header").build(); - } - } else { - device = dms.getDevice(new DeviceIdentifier(id, type), owner, true); - } + if (!StringUtils.isBlank(owner)){ + deviceData.setDeviceOwner(owner); } + if (!StringUtils.isBlank(ownership)){ + deviceData.setDeviceOwnership(ownership); + } + device = dms.getDevice(deviceData, true); } catch (DeviceManagementException e) { String msg = "Error occurred while fetching the device information."; log.error(msg, e); @@ -466,8 +442,12 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } if (device == null) { + if (sinceDate != null) { + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + + "after the timestamp provided in 'If-Modified-Since' header").build(); + } return Response.status(Response.Status.NOT_FOUND).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(404l).setMessage("Requested device of type '" + + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_NOT_FOUND).setMessage("Requested device of type '" + type + "', which carries id '" + id + "' does not exist").build()).build(); } return Response.status(Response.Status.OK).entity(device).build(); @@ -782,7 +762,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @HeaderParam("If-Modified-Since") String ifModifiedSince, @QueryParam("offset") int offset, @QueryParam("limit") int limit, - @QueryParam("owner") String owner) { + @QueryParam("owner") String owner, + @QueryParam("ownership") String ownership) { OperationList operationsList = new OperationList(); RequestValidationUtil.validateOwnerParameter(owner); RequestValidationUtil.validatePaginationParameters(offset, limit); @@ -793,6 +774,9 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { try { RequestValidationUtil.validateDeviceIdentifier(type, id); dms = DeviceMgtAPIUtils.getDeviceManagementService(); + if (!StringUtils.isBlank(ownership)) { + request.setOwnership(ownership); + } result = dms.getOperations(new DeviceIdentifier(id, type), request); operationsList.setList((List) result.getData()); operationsList.setCount(result.getRecordsTotal()); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java index bf9fc8b7bd..b5b92e7a0c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java @@ -123,6 +123,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService { policy.setUsers(policyWrapper.getUsers()); policy.setCompliance(policyWrapper.getCompliance()); policy.setDeviceGroups(policyWrapper.getDeviceGroups()); + policy.setPolicyType(policyWrapper.getPolicyType()); //TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here. List devices = new ArrayList(); List deviceIdentifiers = policyWrapper.getDeviceIdentifiers(); @@ -398,4 +399,33 @@ public class PolicyManagementServiceImpl implements PolicyManagementService { return Response.status(Response.Status.OK).entity(policy).build(); } + @GET + @Path("/type/{policyType}") + @Override + public Response getPolicies( + @PathParam("policyType") String policyType, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + + RequestValidationUtil.validatePaginationParameters(offset, limit); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + List policies; + List filteredPolicies; + PolicyList targetPolicies = new PolicyList(); + try { + PolicyAdministratorPoint policyAdministratorPoint = policyManagementService.getPAP(); + policies = policyAdministratorPoint.getPolicies(policyType); + targetPolicies.setCount(policies.size()); + filteredPolicies = FilteringUtil.getFilteredList(policies, offset, limit); + targetPolicies.setList(filteredPolicies); + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving all available policies"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + + return Response.status(Response.Status.OK).entity(targetPolicies).build(); + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index 81eecab0cb..bdd8693c9a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -625,7 +625,8 @@ public class DeviceManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); Response response = this.deviceManagementService - .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME); + .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME, + DEFAULT_OWNERSHIP); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Expects to return HTTP 200 when the operation is retrieved successfully."); } @@ -637,7 +638,8 @@ public class DeviceManagementServiceImplTest { Mockito.when(this.deviceManagementProviderService.getOperations(Mockito.any(DeviceIdentifier.class), Mockito.any(PaginationRequest.class))).thenThrow(new OperationManagementException()); Response response = this.deviceManagementService - .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME); + .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME, + DEFAULT_OWNERSHIP); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Expects to return HTTP 500 when an exception occurred while retrieving operation list of the device"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceData.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceData.java new file mode 100644 index 0000000000..7a65f39fad --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceData.java @@ -0,0 +1,77 @@ +/* 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.mgt.common.device.details; + +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.Date; + +public class DeviceData { + + /*** + * Identifier of the device, which contains identifier and device ype. + */ + private DeviceIdentifier deviceIdentifier; + + /*** + * User who is enrolled the device. + */ + private String deviceOwner; + + /*** + * Last modified date. + */ + private Date lastModifiedDate; + + /*** + * Current status of the device, e.g ACTIVE, INACTIVE, REMOVED etc. + */ + private String deviceOwnership; + + public DeviceIdentifier getDeviceIdentifier() { + return deviceIdentifier; + } + + public void setDeviceIdentifier(DeviceIdentifier deviceIdentifier) { + this.deviceIdentifier = deviceIdentifier; + } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public Date getLastModifiedDate() { + return lastModifiedDate; + } + + public void setLastModifiedDate(Date lastModifiedDate) { + this.lastModifiedDate = lastModifiedDate; + } + + public String getDeviceOwnership() { + return deviceOwnership; + } + + public void setDeviceOwnership(String deviceOwnership) { + this.deviceOwnership = deviceOwnership; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/Policy.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/Policy.java index 54d21f1f81..977fd60d38 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/Policy.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/Policy.java @@ -177,6 +177,12 @@ public class Policy implements Comparable, Serializable { example = "[]") private List deviceGroups; + @ApiModelProperty( + name = "policyType", + value = "Type of the corresponding policy", + required = true, + example = "GENERAL") + private String policyType; @XmlElement public int getId() { @@ -341,6 +347,14 @@ public class Policy implements Comparable, Serializable { this.deviceGroups = deviceGroups; } + public String getPolicyType() { + return policyType; + } + + public void setPolicyType(String policyType) { + this.policyType = policyType; + } + @Override public int compareTo(Policy o) { if (this.priorityId == o.priorityId) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index 54b2114a72..5214baf962 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -42,6 +42,7 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; +import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; @@ -139,6 +140,9 @@ public interface DeviceDAO { */ boolean updateDevice(Device device, int tenantId) throws DeviceManagementDAOException; + Device getDevice(DeviceData deviceData, int tenantId) throws DeviceManagementDAOException; + + /** * This method is used to retrieve a device of a given device-identifier and tenant-id. * @@ -446,13 +450,13 @@ public interface DeviceDAO { * This method is used to retrieve current enrollment of a given device and user. * * @param deviceId device id. - * @param currentUser user name. + * @param request {@link PaginationRequest} * @param tenantId tenant id. * @return returns EnrolmentInfo object. - * @throws DeviceManagementDAOException + * @throws DeviceManagementDAOException if SQL error occurred while processing the query. */ - EnrolmentInfo getEnrolment(DeviceIdentifier deviceId, String currentUser, - int tenantId) throws DeviceManagementDAOException; + EnrolmentInfo getEnrolment(DeviceIdentifier deviceId, PaginationRequest request, int tenantId) + throws DeviceManagementDAOException; /** * This method is used to retrieve current active enrollment of a given device and tenant id. @@ -562,4 +566,18 @@ public interface DeviceDAO { */ List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementDAOException; + + /** + * This method is used to get the details of subscribed devices. + * + * @param deviceIds device ids of the subscribed devices. + * @param tenantId Id of the current tenant. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param status status of the devices. + * @return devices - subscribed device details list + * @throws {@link DeviceManagementDAOException} if connections establishment fails. + */ + List getSubscribedDevices(int offsetValue, int limitValue, List deviceIds, + int tenantId, String status) throws DeviceManagementDAOException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 1041d39911..090480d6f5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -36,6 +36,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; @@ -44,6 +45,7 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; +import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -65,7 +67,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringJoiner; -import java.util.concurrent.atomic.AtomicInteger; public abstract class AbstractDeviceDAOImpl implements DeviceDAO { @@ -139,6 +140,84 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } } + @Override + public Device getDevice(DeviceData deviceData, int tenantId) throws DeviceManagementDAOException { + Device device = null; + try { + Connection conn = this.getConnection(); + String sql = "SELECT " + + "d1.ID AS DEVICE_ID, " + + "d1.DESCRIPTION, " + + "d1.NAME AS DEVICE_NAME, " + + "d1.DEVICE_TYPE, " + + "d1.DEVICE_IDENTIFICATION, " + + "e.OWNER, " + + "e.OWNERSHIP, " + + "e.STATUS, " + + "e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT, " + + "e.ID AS ENROLMENT_ID " + + "FROM DM_ENROLMENT e, " + + "(SELECT " + + "d.ID, " + + "d.DESCRIPTION, " + + "d.NAME, " + + "t.NAME AS DEVICE_TYPE, " + + "d.DEVICE_IDENTIFICATION " + + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " + + "WHERE " + + "t.NAME = ? AND " + + "t.ID = d.DEVICE_TYPE_ID AND " + + "d.DEVICE_IDENTIFICATION = ? AND " + + "d.TENANT_ID = ? AND " + + "dt.DEVICE_ID = d.ID"; + + if (deviceData.getLastModifiedDate() != null) { + sql += " AND dt.UPDATE_TIMESTAMP > ?"; + } + + sql += ") d1 WHERE d1.ID = e.DEVICE_ID AND "; + + if (!StringUtils.isBlank(deviceData.getDeviceOwner())) { + sql += "e.OWNER = ? AND "; + } + if (!StringUtils.isBlank(deviceData.getDeviceOwnership())) { + sql += "e.OWNERSHIP = ? AND "; + } + + sql += "TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int paramIndx = 1; + stmt.setString(paramIndx++, deviceData.getDeviceIdentifier().getType()); + stmt.setString(paramIndx++, deviceData.getDeviceIdentifier().getId()); + stmt.setInt(paramIndx++, tenantId); + if (deviceData.getLastModifiedDate() != null) { + stmt.setLong(paramIndx++, deviceData.getLastModifiedDate().getTime()); + } + if (!StringUtils.isBlank(deviceData.getDeviceOwner())) { + stmt.setString(paramIndx++, deviceData.getDeviceOwner()); + } + if (!StringUtils.isBlank(deviceData.getDeviceOwnership())) { + stmt.setString(paramIndx++, deviceData.getDeviceOwnership()); + } + stmt.setInt(paramIndx, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + device = DeviceManagementDAOUtil.loadMatchingDevice(rs, false); + } + } + } + } catch (SQLException e) { + String msg = "Error occurred while getting device data for device identifier " + + deviceData.getDeviceIdentifier().getId() + " and device type " + + deviceData.getDeviceIdentifier().getType(); + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + return device; + } + @Override public Device getDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException { Connection conn; @@ -239,7 +318,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " + "t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " + "t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " + - "AND TENANT_ID = ? AND e.OWNER = ?"; + "AND TENANT_ID = ? AND e.OWNER = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC"; stmt = conn.prepareStatement(sql); stmt.setString(1, deviceIdentifier.getType()); stmt.setString(2, deviceIdentifier.getId()); @@ -508,7 +587,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " + "t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " + "WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " + - "AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ?"; + "AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC"; stmt = conn.prepareStatement(sql); stmt.setString(1, deviceIdentifier.getType()); stmt.setString(2, deviceIdentifier.getId()); @@ -1293,36 +1372,54 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } @Override - public EnrolmentInfo getEnrolment(DeviceIdentifier deviceId, String currentOwner, - int tenantId) throws DeviceManagementDAOException { - Connection conn; - PreparedStatement stmt = null; - ResultSet rs = null; + public EnrolmentInfo getEnrolment(DeviceIdentifier deviceId, PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { EnrolmentInfo enrolmentInfo = null; try { - conn = this.getConnection(); - String sql = "SELECT ID AS ENROLMENT_ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, DATE_OF_ENROLMENT, " + - "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = (SELECT d.ID " + + Connection conn = this.getConnection(); + String sql = "SELECT " + + "ID AS ENROLMENT_ID, " + + "DEVICE_ID, " + + "OWNER, " + + "OWNERSHIP, " + + "STATUS, " + + "DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, " + + "TENANT_ID " + + "FROM DM_ENROLMENT " + + "WHERE " + + "DEVICE_ID = (SELECT d.ID " + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID " + - "AND d.DEVICE_IDENTIFICATION = ? AND t.NAME = ? AND d.TENANT_ID = ?) " + - "AND OWNER = ? AND TENANT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setString(1, deviceId.getId()); - stmt.setString(2, deviceId.getType()); - stmt.setInt(3, tenantId); - stmt.setString(4, currentOwner); - stmt.setInt(5, tenantId); - rs = stmt.executeQuery(); - if (rs.next()) { - enrolmentInfo = DeviceManagementDAOUtil.loadMatchingEnrolment(rs); + "AND d.DEVICE_IDENTIFICATION = ? AND t.NAME = ? AND d.TENANT_ID = ?) " + + "AND OWNER = ? "; + + if (!StringUtils.isBlank(request.getOwnership())) { + sql += "AND OWNERSHIP = ? "; + } + sql += "AND TENANT_ID = ?"; + int paramIdx = 1; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(paramIdx++, deviceId.getId()); + stmt.setString(paramIdx++, deviceId.getType()); + stmt.setInt(paramIdx++, tenantId); + stmt.setString(paramIdx++, request.getOwner()); + if (!StringUtils.isBlank(request.getOwnership())) { + stmt.setString(paramIdx++, request.getOwnership()); + } + stmt.setInt(paramIdx, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + enrolmentInfo = DeviceManagementDAOUtil.loadMatchingEnrolment(rs); + } + } } - return enrolmentInfo; } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " + - "information of user '" + currentOwner + "' upon device '" + deviceId + "'", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, rs); + String msg = "Error occurred while retrieving the enrolment " + + "information of user '" + request.getOwner() + "' upon device '" + deviceId + "'"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } + return enrolmentInfo; } @Override diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 7680e3f905..a902860015 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -34,6 +34,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.StringJoiner; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -583,7 +584,68 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List getSubscribedDevices(int offsetValue, int limitValue, + List deviceIds, int tenantId, String status) + throws DeviceManagementDAOException { + Connection conn; + + try { + conn = this.getConnection(); + int index = 1; + + boolean isStatusProvided = false; + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " + + "f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " + + "e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " + + "e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " + + "FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+ + "WHERE " + + "e.DEVICE_ID=f.ID AND " + + "e.DEVICE_ID IN (", ") AND e.TENANT_ID=?"); + + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + + if (status != null && !status.isEmpty()) { + query = query + " AND e.STATUS=?"; + isStatusProvided = true; + } + + query = query + " LIMIT ?,?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + + ps.setInt(index++, tenantId); + if (isStatusProvided) { + ps.setString(index++, status); + } + ps.setInt(index++, offsetValue); + ps.setInt(index, limitValue); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + devices.add(DeviceManagementDAOUtil.loadDevice(rs)); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving information of all registered devices " + + "according to device ids and the limit area."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } -} \ No newline at end of file +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index fd8156c50f..c52f8a11b0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -37,6 +37,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.StringJoiner; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -588,6 +589,67 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List getSubscribedDevices(int offsetValue, int limitValue, + List deviceIds, int tenantId, String status) + throws DeviceManagementDAOException { + Connection conn; + + try { + conn = this.getConnection(); + int index = 1; + + boolean isStatusProvided = false; + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " + + "f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " + + "e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " + + "e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " + + "FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t " + + "WHERE " + + "e.DEVICE_ID=f.ID AND " + + "e.DEVICE_ID IN (", ") AND e.TENANT_ID=?"); + + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + + if (status != null && !status.isEmpty()) { + query = query + " AND e.STATUS=?"; + isStatusProvided = true; + } + + query = query + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + + ps.setInt(index++, tenantId); + if (isStatusProvided) { + ps.setString(index++, status); + } + ps.setInt(index++, offsetValue); + ps.setInt(index, limitValue); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + devices.add(DeviceManagementDAOUtil.loadDevice(rs)); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving information of all registered devices " + + "according to device ids and the limit area."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index fe80e47808..f8bb373174 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -34,6 +34,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.StringJoiner; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -565,6 +566,67 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { } return devices; } + + @Override + public List getSubscribedDevices(int offsetValue, int limitValue, + List deviceIds, int tenantId, String status) + throws DeviceManagementDAOException { + Connection conn; + + try { + conn = this.getConnection(); + int index = 1; + + boolean isStatusProvided = false; + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " + + "f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " + + "e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " + + "e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " + + "FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+ + "WHERE " + + "e.DEVICE_ID=f.ID AND " + + "e.DEVICE_ID IN (", ") AND e.TENANT_ID=?"); + + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + + if (status != null && !status.isEmpty()) { + query = query + " AND e.STATUS=?"; + isStatusProvided = true; + } + + query = query + " LIMIT ? OFFSET ?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + + ps.setInt(index++, tenantId); + if (isStatusProvided) { + ps.setString(index++, status); + } + ps.setInt(index++, offsetValue); + ps.setInt(index, limitValue); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + devices.add(DeviceManagementDAOUtil.loadDevice(rs)); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving information of all registered devices " + + "according to device ids and the limit area."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index 0bffa3af87..2c7dccc4ee 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -34,6 +34,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.StringJoiner; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -521,6 +522,67 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List getSubscribedDevices(int offsetValue, int limitValue, + List deviceIds, int tenantId, String status) + throws DeviceManagementDAOException { + Connection conn; + + try { + conn = this.getConnection(); + int index = 1; + + boolean isStatusProvided = false; + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " + + "f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " + + "e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " + + "e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " + + "FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+ + "WHERE " + + "e.DEVICE_ID=f.ID AND " + + "e.DEVICE_ID IN (", ") AND e.TENANT_ID=?"); + + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + + if (status != null && !status.isEmpty()) { + query = query + " AND e.STATUS=?"; + isStatusProvided = true; + } + + query = query + " LIMIT ?,?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + + ps.setInt(index++, tenantId); + if (isStatusProvided) { + ps.setString(index++, status); + } + ps.setInt(index++, offsetValue); + ps.setInt(index, limitValue); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + devices.add(DeviceManagementDAOUtil.loadDevice(rs)); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving information of all registered devices " + + "according to device ids and the limit area."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } 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 d83f1cf483..f2141d7a97 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 @@ -458,7 +458,12 @@ public class OperationManagerImpl implements OperationManager { deviceId.getType() + "' device, which carries the identifier '" + deviceId.getId() + "' of owner '" + owner + "'"); } - EnrolmentInfo enrolmentInfo = this.getEnrolmentInfo(deviceId, owner); + EnrolmentInfo enrolmentInfo = this.getEnrolmentInfo(deviceId, request); + if (enrolmentInfo == null){ + throw new OperationManagementException("Enrollment info not found for given device which has device " + + "Identifier:" + deviceId.getId() + " and device type: " + deviceId.getType() + "Further, device " + + "is own to: " + owner); + } int enrolmentId = enrolmentInfo.getId(); try { OperationManagementDAOFactory.openConnection(); @@ -1072,33 +1077,34 @@ public class OperationManagerImpl implements OperationManager { return isUserAuthorized; } - private EnrolmentInfo getEnrolmentInfo(DeviceIdentifier deviceId, String owner) throws OperationManagementException { + private EnrolmentInfo getEnrolmentInfo(DeviceIdentifier deviceId, PaginationRequest request) + throws OperationManagementException { EnrolmentInfo enrolmentInfo = null; try { int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); String user = this.getUser(); DeviceManagementDAOFactory.openConnection(); - if (this.isSameUser(user, owner)) { - enrolmentInfo = deviceDAO.getEnrolment(deviceId, owner, tenantId); + if (this.isSameUser(user, request.getOwner())) { + enrolmentInfo = deviceDAO.getEnrolment(deviceId, request, tenantId); } else { boolean isAdminUser = DeviceManagementDataHolder.getInstance().getDeviceAccessAuthorizationService(). isDeviceAdminUser(); if (isAdminUser) { - enrolmentInfo = deviceDAO.getEnrolment(deviceId, owner, tenantId); + enrolmentInfo = deviceDAO.getEnrolment(deviceId, request, tenantId); } //TODO : Add a check for group admin if this fails } } catch (DeviceManagementDAOException e) { throw new OperationManagementException("Error occurred while retrieving enrollment data of '" + deviceId.getType() + "' device carrying the identifier '" + - deviceId.getId() + "' of owner '" + owner + "'", e); + deviceId.getId() + "' of owner '" + request.getOwner() + "'", e); } catch (SQLException e) { throw new OperationManagementException( "Error occurred while opening a connection to the data source", e); } catch (DeviceAccessAuthorizationException e) { throw new OperationManagementException("Error occurred while checking the device access permissions for '" + deviceId.getType() + "' device carrying the identifier '" + - deviceId.getId() + "' of owner '" + owner + "'", e); + deviceId.getId() + "' of owner '" + request.getOwner() + "'", e); } finally { DeviceManagementDAOFactory.closeConnection(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index da1bddecae..a78de8cbc2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -56,6 +56,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManageme import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; +import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; @@ -262,6 +263,17 @@ public interface DeviceManagementProviderService { */ Device getDevice(DeviceIdentifier deviceId, Date since, boolean requireDeviceInfo) throws DeviceManagementException; + /*** + * + * @param deviceData Device data, + * @param requireDeviceInfo A boolean indicating whether the device-info (location, app-info etc) is also required + * along with the device data. + * @return {@link Device}, null when device is not available. + * @throws {@link DeviceManagementException} + */ + Device getDevice(DeviceData deviceData, boolean requireDeviceInfo) throws DeviceManagementException; + + /** * Retrieves a list of devices based on a given criteria of properties * @@ -759,7 +771,6 @@ public interface DeviceManagementProviderService { DeviceTypeVersion getDeviceTypeVersion(String deviceTypeName, String version) throws DeviceManagementException; - /** * Retrieves a list of configurations of a specific device * using the device's properties @@ -782,4 +793,18 @@ public interface DeviceManagementProviderService { * @return tru if device transferee, otherwise false */ List transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) throws DeviceManagementException, DeviceNotFoundException; + + /** + * This method retrieves a list of subscribed devices. + * + * @param devicesIds devices ids of the subscribed devices. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param status status of the devices. + * @return {@link PaginationResult} + * @throws {@link DeviceManagementException} if any service level or DAO level error occurs. + */ + PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, + List devicesIds, String status) + throws DeviceManagementException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index abe8be5385..0e52285893 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -77,6 +77,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManageme import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; @@ -1242,6 +1243,54 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv return device; } + @Override + public Device getDevice(DeviceData deviceData, boolean requireDeviceInfo) + throws DeviceManagementException { + if (deviceData.getDeviceIdentifier() == null) { + String msg = "Received null device identifier for method getDevice"; + log.error(msg); + throw new DeviceManagementException(msg); + } + if (log.isDebugEnabled()) { + log.debug("Get device by device identifier :" + deviceData.getDeviceIdentifier().getId() + " of type '" + + deviceData.getDeviceIdentifier().getType() + "' and requiredDeviceInfo: " + requireDeviceInfo); + } + Device device = null; + int tenantId = this.getTenantId(); + try { + DeviceManagementDAOFactory.openConnection(); + device = deviceDAO.getDevice(deviceData, tenantId); + if (device == null) { + String msg = + "No device is found upon the type '" + deviceData.getDeviceIdentifier().getType() + "' and id '" + + deviceData.getDeviceIdentifier().getId() + "'"; + if (log.isDebugEnabled()) { + log.debug(msg); + } + return null; + } + } catch (DeviceManagementDAOException e) { + String msg = + "Error occurred while obtaining the device for '" + deviceData.getDeviceIdentifier().getId() + "'"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg); + throw new DeviceManagementException(msg, e); + } catch (Exception e) { + String msg = "Error occurred in getDevice: " + deviceData.getDeviceIdentifier().getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + if (requireDeviceInfo) { + return this.getAllDeviceInfo(device); + } + return device; + } + @Override public List getDevicesBasedOnProperties(Map deviceProps) throws DeviceManagementException { @@ -1718,9 +1767,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv @Override public PaginationResult getOperations(DeviceIdentifier deviceId, PaginationRequest request) throws OperationManagementException { - request = DeviceManagerUtil.validateOperationListPageSize(request); return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId()) - .getOperations(deviceId, request); + .getOperations(deviceId, DeviceManagerUtil.validateOperationListPageSize(request)); } @Override @@ -3665,4 +3713,39 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv deviceConfiguration.setDeviceOwner(deviceOwner); return deviceConfiguration; } + + @Override + public PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, + List devicesIds, String status) + throws DeviceManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (log.isDebugEnabled()) { + log.debug("Getting all devices details for device ids: " + devicesIds); + } + PaginationResult paginationResult = new PaginationResult(); + int count; + List SubscribedDeviceDetails; + try { + DeviceManagementDAOFactory.openConnection(); + SubscribedDeviceDetails = deviceDAO + .getSubscribedDevices(offsetValue, limitValue, devicesIds, tenantId, status); + count = SubscribedDeviceDetails.size(); + + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while retrieving device list for device ids " + devicesIds; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + paginationResult.setData(getAllDeviceInfo(SubscribedDeviceDetails)); + paginationResult.setRecordsFiltered(count); + paginationResult.setRecordsTotal(count); + return paginationResult; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNegativeDBOperationTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNegativeDBOperationTest.java index fc790f09a9..db7425407b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNegativeDBOperationTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNegativeDBOperationTest.java @@ -55,6 +55,7 @@ public class OperationManagementNegativeDBOperationTest extends BaseDeviceManage private static final String DEVICE_ID_PREFIX = "NEGDB_OP-TEST-DEVICE-ID-"; private static final int NO_OF_DEVICES = 5; private static final String ADMIN_USER = "admin"; + private static final String OWNSERSHIP = "BYOD"; private List deviceIds = new ArrayList<>(); private OperationManager operationMgtService; @@ -111,6 +112,7 @@ public class OperationManagementNegativeDBOperationTest extends BaseDeviceManage PaginationRequest request = new PaginationRequest(1, 2); request.setDeviceType(DEVICE_TYPE); request.setOwner(ADMIN_USER); + request.setOwnership(OWNSERSHIP); this.dataSource.setThrowException(true); try { this.operationMgtService.getOperations(this.deviceIds.get(0), request); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNoDBSchemaTests.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNoDBSchemaTests.java index 4b92b1a39a..98e2fc5a04 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNoDBSchemaTests.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementNoDBSchemaTests.java @@ -57,6 +57,7 @@ public class OperationManagementNoDBSchemaTests extends BaseDeviceManagementTest private static final String COMMAND_OPERATON_CODE = "COMMAND-TEST"; private static final int NO_OF_DEVICES = 5; private static final String ADMIN_USER = "admin"; + private static final String OWNERSHIP = "BYOD"; private List deviceIds = new ArrayList<>(); private OperationManager operationMgtService; @@ -124,6 +125,7 @@ public class OperationManagementNoDBSchemaTests extends BaseDeviceManagementTest PaginationRequest request = new PaginationRequest(1, 2); request.setDeviceType(DEVICE_TYPE); request.setOwner(ADMIN_USER); + request.setOwnership(OWNERSHIP); for (DeviceIdentifier deviceIdentifier : deviceIds) { this.operationMgtService.getOperations(deviceIdentifier, request); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementTests.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementTests.java index a71360c85b..098903e32b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementTests.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/operation/OperationManagementTests.java @@ -75,6 +75,7 @@ public class OperationManagementTests extends BaseDeviceManagementTest { private static final String ADMIN_USER = "admin"; private static final String NON_ADMIN_USER = "test"; private static final String INVALID_DEVICE = "ThisIsInvalid"; + private static final String OWNERSHIP = "BYOD"; private List deviceIds = new ArrayList<>(); private OperationManager operationMgtService; @@ -286,6 +287,7 @@ public class OperationManagementTests extends BaseDeviceManagementTest { PaginationRequest request = new PaginationRequest(1, 2); request.setDeviceType(DEVICE_TYPE); request.setOwner(ADMIN_USER); + request.setOwnership(OWNERSHIP); for (DeviceIdentifier deviceIdentifier : deviceIds) { PaginationResult result = this.operationMgtService.getOperations(deviceIdentifier, request); Assert.assertEquals(result.getRecordsFiltered(), 4); @@ -302,6 +304,7 @@ public class OperationManagementTests extends BaseDeviceManagementTest { PaginationRequest request = new PaginationRequest(1, 2); request.setDeviceType(DEVICE_TYPE); request.setOwner(ADMIN_USER); + request.setOwnership(OWNERSHIP); for (DeviceIdentifier deviceIdentifier : deviceIds) { try { this.operationMgtService.getOperations(deviceIdentifier, request); @@ -540,6 +543,7 @@ public class OperationManagementTests extends BaseDeviceManagementTest { PaginationRequest request = new PaginationRequest(1, 2); request.setDeviceType(DEVICE_TYPE); request.setOwner(ADMIN_USER); + request.setOwnership(OWNERSHIP); PaginationResult result = this.operationMgtService.getOperations (new DeviceIdentifier(INVALID_DEVICE, DEVICE_TYPE), request); Assert.assertEquals(result.getRecordsFiltered(), 4); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/operation-api.jag b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/operation-api.jag index c581aad791..9fa2a37353 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/operation-api.jag +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/operation-api.jag @@ -29,12 +29,14 @@ if (uriMatcher.match("/{context}/api/operation/paginate")) { var deviceType = request.getParameter("deviceType"); var deviceId = request.getParameter("deviceId"); var owner = request.getParameter("owner"); + var ownership = request.getParameter("ownership"); var index = request.getParameter("start"); var length = request.getParameter("length"); var search = request.getParameter("search[value]"); var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + - "/devices/" + deviceType + "/" + deviceId + "/operations?owner=" + owner + "&offset=" + index + "&limit=" + length; + "/devices/" + deviceType + "/" + deviceId + "/operations?owner=" + owner + "&ownership=" + ownership + + "&offset=" + index + "&limit=" + length; serviceInvokers.XMLHttp.get( restAPIEndpoint, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index c39e797bc2..b561c8a23e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -63,7 +63,7 @@ deviceModule = function () { /* @Updated */ - publicMethods.viewDevice = function (deviceType, deviceId, owner) { + publicMethods.viewDevice = function (deviceType, deviceId, owner, ownership) { var carbonUser = session.get(constants["USER_SESSION_KEY"]); if (!carbonUser) { log.error("User object was not found in the session"); @@ -114,7 +114,12 @@ deviceModule = function () { utility.startTenantFlow(carbonUser); var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId; if (owner) { - url = url + "?owner=" + owner; + url = url + "?owner=" + owner; + if (ownership){ + url = url + "&ownership=" + ownership; + } + } else if (ownership){ + url = url + "?ownership=" + ownership; } return serviceInvokers.XMLHttp.get( url, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js index 2448a89f8f..10c1542695 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js @@ -342,7 +342,8 @@ function loadDevices(searchType, searchParam) { data: 'ownership', class: 'remove-padding-top viewEnabledIcon', render: function (status, type, row, meta) { - if (getDeviceTypeCategory(row.deviceType) == 'mobile') { + if (getDeviceTypeCategory(row.deviceType) === 'mobile' + || getDeviceTypeCategory(row.deviceType) === 'hybrid') { return row.ownership; } else { return null; @@ -422,17 +423,6 @@ function loadDevices(searchType, searchParam) { ]; var fnCreatedRow = function (row, data, dataIndex) { - - if(data.status != "REMOVED"){ - $(row).attr('data-type', 'selectable'); - }else{ - $(row).attr('data-type', 'non-selectable'); - } - - $(row).attr('data-deviceid', htmlspecialchars(data.deviceIdentifier)); - $(row).attr('data-devicetype', htmlspecialchars(data.deviceType)); - $(row).attr('data-url', context + '/device/' + htmlspecialchars(data.deviceType) + '?id=' - + htmlspecialchars(data.deviceIdentifier) + '&owner=' + htmlspecialchars(data.userPattern)) ; var model = htmlspecialchars(getPropertyValue(data.properties, 'DEVICE_MODEL')); var vendor = htmlspecialchars(getPropertyValue(data.properties, 'VENDOR')); var owner = htmlspecialchars(data.userPattern); @@ -440,6 +430,10 @@ function loadDevices(searchType, searchParam) { var ownership = htmlspecialchars(data.ownership); var deviceType = htmlspecialchars(data.deviceType); var category = getDeviceTypeCategory(deviceType); + $(row).attr('data-deviceid', htmlspecialchars(data.deviceIdentifier)); + $(row).attr('data-devicetype', deviceType); + $(row).attr('data-url', context + '/device/' + htmlspecialchars(data.deviceType) + '?id=' + + htmlspecialchars(data.deviceIdentifier) + '&owner=' + owner + '&ownership=' + ownership) ; $.each($('td', row), function (colIndex) { switch (colIndex) { case 1: @@ -462,7 +456,7 @@ function loadDevices(searchType, searchParam) { $(this).attr('data-display', getDeviceTypeLabel(deviceType)); break; case 5: - if (category == 'mobile') { + if (category === 'mobile' || category === 'hybrid') { $(this).attr('data-grid-label', "Ownership"); $(this).attr('data-search', ownership); $(this).attr('data-display', ownership); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js index a431c66a71..62308cade4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js @@ -24,6 +24,7 @@ function onRequest(context) { var deviceType = context.uriParams.deviceType; var deviceId = request.getParameter("id"); var owner = request.getParameter("owner"); + var ownership = request.getParameter("ownership"); var attributes = []; var featureList = []; var user = userModule.getCarbonUser(); @@ -130,10 +131,10 @@ function onRequest(context) { displayData.tenantDomain = tenantDomain; - if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { + if (deviceType && deviceId) { var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; - var device = deviceModule.viewDevice(deviceType, deviceId, owner); - if (device && device.status != "error") { + var device = deviceModule.viewDevice(deviceType, deviceId, owner, ownership); + if (device && device.status !== "error") { displayData.device = device.content; displayData.autoCompleteParams = autoCompleteParams; displayData.encodedFeaturePayloads = ""; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js index 7cce058c69..4564ef9512 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js @@ -20,6 +20,7 @@ var deviceId = $(".device-id"); var deviceIdentifier = deviceId.data("deviceid"); var deviceType = deviceId.data("type"); var deviceOwner = deviceId.data("owner"); +var deviceOwnership = deviceId.data("ownership"); $(document).ready(function() { $(".panel-body").removeClass("hidden"); @@ -86,7 +87,8 @@ function loadOperationsLog(update) { data: { deviceId: deviceIdentifier, deviceType: deviceType, - owner: deviceOwner + owner: deviceOwner, + ownership: deviceOwnership }, dataSrc: function(json) { $("#operations-spinner").addClass("hidden"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js index af0baeaeac..2f9cc89126 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/view.js @@ -21,10 +21,11 @@ function onRequest(context) { var deviceType = context["uriParams"]["deviceType"]; var deviceId = request.getParameter("id"); var owner = request.getParameter("owner"); + var ownership = request.getParameter("ownership"); var deviceViewData = {}; if (deviceType && deviceId) { var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; - var response = deviceModule.viewDevice(deviceType, deviceId, owner); + var response = deviceModule.viewDevice(deviceType, deviceId, owner, ownership); if (response["status"] == "success") { deviceViewData["deviceFound"] = true; deviceViewData["isAuthorized"] = true; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/public/js/policy-create.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/public/js/policy-create.js index 49b71a9d41..703c808923 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/public/js/policy-create.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/public/js/policy-create.js @@ -458,6 +458,8 @@ var savePolicy = function (policy, isActive, serviceURL) { payload["deviceGroups"] = policy["selectedGroups"]; } + payload["policyType"] = "GENERAL"; + invokerUtil.post( serviceURL, payload, diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.common/src/main/java/org/wso2/carbon/policy/mgt/common/PolicyAdministratorPoint.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.common/src/main/java/org/wso2/carbon/policy/mgt/common/PolicyAdministratorPoint.java index eab6f6214f..e9bdbdc014 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.common/src/main/java/org/wso2/carbon/policy/mgt/common/PolicyAdministratorPoint.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.common/src/main/java/org/wso2/carbon/policy/mgt/common/PolicyAdministratorPoint.java @@ -155,4 +155,11 @@ public interface PolicyAdministratorPoint { List getProfiles() throws PolicyManagementException; int getPolicyCount() throws PolicyManagementException; + + /** + * @param policyType type of the policy + * @return policy list of the specific type + * @throws PolicyManagementException + */ + List getPolicies(String policyType) throws PolicyManagementException; } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/PolicyCacheManager.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/PolicyCacheManager.java index 8a4db21d7b..ce71b7a213 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/PolicyCacheManager.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/PolicyCacheManager.java @@ -113,4 +113,13 @@ public interface PolicyCacheManager { * @return - Id of the policy. */ int getPolicyIdOfDevice(int deviceId); + + /** + * This method will return the all policies belongs to the specific type. + * + * @param policyType - type of the policy + * @return - list of policies + * @throws PolicyManagementException + */ + List getAllPolicies(String policyType) throws PolicyManagementException; } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/impl/PolicyCacheManagerImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/impl/PolicyCacheManagerImpl.java index 8b0bb71c1c..51c0dc4e81 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/impl/PolicyCacheManagerImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/cache/impl/PolicyCacheManagerImpl.java @@ -30,6 +30,7 @@ import org.wso2.carbon.policy.mgt.core.util.PolicyManagementConstants; import org.wso2.carbon.policy.mgt.core.util.PolicyManagerUtil; import javax.cache.Cache; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -74,31 +75,13 @@ public class PolicyCacheManagerImpl implements PolicyCacheManager { @Override public List getAllPolicies() throws PolicyManagementException { - Cache> lCache = getPolicyListCache(); - if (!lCache.containsKey(1)) { - PolicyManager policyManager = new PolicyManagerImpl(); - this.addAllPolicies(policyManager.getPolicies()); - } + updateCache(lCache); if (log.isDebugEnabled()) { - List cachedPolicy = lCache.get(1); - for (Policy policy : cachedPolicy) { - log.debug("Policy id in cache .. : " + policy.getId() + " policy name : " + policy. - getPolicyName() + " Activated : " + policy.isActive()); - - List users = policy.getUsers(); - for (String user : users) { - log.debug("Users in cached policy : " + user); - } - List roles = policy.getRoles(); - for (String role : roles) { - log.debug("Roles in cached policy : " + role); - } - } - + showDebugLog(lCache); } + lCache = getPolicyListCache(); return lCache.get(1); - } @Override @@ -218,4 +201,47 @@ public class PolicyCacheManagerImpl implements PolicyCacheManager { return 0; } + @Override + public List getAllPolicies(String policyType) throws PolicyManagementException { + Cache> lCache = getPolicyListCache(); + updateCache(lCache); + if (log.isDebugEnabled()) { + showDebugLog(lCache); + } + lCache = getPolicyListCache(); + List policyListByType = new ArrayList<>(); + List cachedPolicyList = lCache.get(1); + Iterator iterator = cachedPolicyList.iterator(); + while (iterator.hasNext()) { + Policy policy = iterator.next(); + if (policy.getPolicyType().equals(policyType)) { + policyListByType.add(policy); + } + } + return policyListByType; + } + + private void updateCache(Cache> lCache) throws PolicyManagementException { + if (!lCache.containsKey(1)) { + PolicyManager policyManager = new PolicyManagerImpl(); + this.addAllPolicies(policyManager.getPolicies()); + } + } + + private void showDebugLog(Cache> lCache) { + List cachedPolicy = lCache.get(1); + for (Policy policy : cachedPolicy) { + log.debug("Policy id in cache .. : " + policy.getId() + " policy name : " + policy. + getPolicyName() + " Activated : " + policy.isActive()); + + List users = policy.getUsers(); + for (String user : users) { + log.debug("Users in cached policy : " + user); + } + List roles = policy.getRoles(); + for (String role : roles) { + log.debug("Roles in cached policy : " + role); + } + } + } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/PolicyDAO.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/PolicyDAO.java index bda6bb88c4..2ea593ee4b 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/PolicyDAO.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/PolicyDAO.java @@ -150,4 +150,6 @@ public interface PolicyDAO { HashMap getAppliedPolicyIds() throws PolicyManagerDAOException; HashMap getAppliedPolicyIdsDeviceIds() throws PolicyManagerDAOException; + + List getAllPolicies(String policyType) throws PolicyManagerDAOException; } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/PolicyDAOImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/PolicyDAOImpl.java index 580c89ecc3..9be99cde93 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/PolicyDAOImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/PolicyDAOImpl.java @@ -979,21 +979,7 @@ public class PolicyDAOImpl implements PolicyDAO { stmt.setInt(1, tenantId); resultSet = stmt.executeQuery(); - while (resultSet.next()) { - Policy policy = new Policy(); - policy.setId(resultSet.getInt("ID")); - policy.setProfileId(resultSet.getInt("PROFILE_ID")); - policy.setPolicyName(resultSet.getString("NAME")); - policy.setTenantId(tenantId); - policy.setPriorityId(resultSet.getInt("PRIORITY")); - policy.setCompliance(resultSet.getString("COMPLIANCE")); - policy.setOwnershipType(resultSet.getString("OWNERSHIP_TYPE")); - policy.setUpdated(PolicyManagerUtil.convertIntToBoolean(resultSet.getInt("UPDATED"))); - policy.setActive(PolicyManagerUtil.convertIntToBoolean(resultSet.getInt("ACTIVE"))); - policy.setDescription(resultSet.getString("DESCRIPTION")); - policies.add(policy); - } - return policies; + return this.extractPolicyListFromDbResult(resultSet, tenantId); } catch (SQLException e) { throw new PolicyManagerDAOException("Error occurred while reading the policies from the database", e); } finally { @@ -1437,7 +1423,7 @@ public class PolicyDAOImpl implements PolicyDAO { try { conn = this.getConnection(); String query = "INSERT INTO DM_POLICY (NAME, PROFILE_ID, TENANT_ID, PRIORITY, COMPLIANCE, OWNERSHIP_TYPE," + - "UPDATED, ACTIVE, DESCRIPTION) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "UPDATED, ACTIVE, DESCRIPTION, POLICY_TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; stmt = conn.prepareStatement(query, new String[]{"id"}); stmt.setString(1, policy.getPolicyName()); @@ -1449,6 +1435,7 @@ public class PolicyDAOImpl implements PolicyDAO { stmt.setInt(7, 0); stmt.setInt(8, 0); stmt.setString(9, policy.getDescription()); + stmt.setString(10, policy.getPolicyType()); int affectedRows = stmt.executeUpdate(); @@ -1704,4 +1691,57 @@ public class PolicyDAOImpl implements PolicyDAO { return devicePolicyIds; } + @Override + public List getAllPolicies(String policyType) throws PolicyManagerDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + + try { + conn = this.getConnection(); + String query = "SELECT ID, " + + "PROFILE_ID, " + + "NAME, " + + "PRIORITY, " + + "COMPLIANCE, " + + "OWNERSHIP_TYPE, " + + "UPDATED, " + + "ACTIVE, " + + "DESCRIPTION, " + + "POLICY_TYPE "+ + "FROM DM_POLICY WHERE TENANT_ID = ? AND POLICY_TYPE = ?"; + stmt = conn.prepareStatement(query); + stmt.setInt(1, tenantId); + stmt.setString(2, policyType); + resultSet = stmt.executeQuery(); + return this.extractPolicyListFromDbResult(resultSet, tenantId); + } catch (SQLException e) { + String msg = "Error occurred while reading the policies from the database "; + log.error(msg, e); + throw new PolicyManagerDAOException(msg, e); + } finally { + PolicyManagementDAOUtil.cleanupResources(stmt, resultSet); + } + } + + private List extractPolicyListFromDbResult(ResultSet resultSet, int tenantId) throws SQLException { + List policies = new ArrayList<>(); + while (resultSet.next()) { + Policy policy = new Policy(); + policy.setId(resultSet.getInt("ID")); + policy.setProfileId(resultSet.getInt("PROFILE_ID")); + policy.setPolicyName(resultSet.getString("NAME")); + policy.setTenantId(tenantId); + policy.setPriorityId(resultSet.getInt("PRIORITY")); + policy.setCompliance(resultSet.getString("COMPLIANCE")); + policy.setOwnershipType(resultSet.getString("OWNERSHIP_TYPE")); + policy.setUpdated(PolicyManagerUtil.convertIntToBoolean(resultSet.getInt("UPDATED"))); + policy.setActive(PolicyManagerUtil.convertIntToBoolean(resultSet.getInt("ACTIVE"))); + policy.setDescription(resultSet.getString("DESCRIPTION")); + policy.setPolicyType(resultSet.getString("POLICY_TYPE")); + policies.add(policy); + } + return policies; + } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/impl/PolicyAdministratorPointImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/impl/PolicyAdministratorPointImpl.java index 9cbd11aefc..c555b27b97 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/impl/PolicyAdministratorPointImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/impl/PolicyAdministratorPointImpl.java @@ -377,4 +377,12 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint { } } + @Override + public List getPolicies(String policyType) throws PolicyManagementException { + if (policyConfiguration.getCacheEnable()) { + return PolicyCacheManagerImpl.getInstance().getAllPolicies(policyType); + } else { + return policyManager.getPolicies(policyType); + } + } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/PolicyManager.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/PolicyManager.java index 68c57b5049..187bbaaae2 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/PolicyManager.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/PolicyManager.java @@ -83,4 +83,6 @@ public interface PolicyManager { Policy getAppliedPolicyToDevice(DeviceIdentifier deviceIdentifier) throws PolicyManagementException; HashMap getAppliedPolicyIdsDeviceIds() throws PolicyManagementException; + + List getPolicies(String type) throws PolicyManagementException; } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java index 59c34abfa2..e2ef347269 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java @@ -626,25 +626,7 @@ public class PolicyManagerImpl implements PolicyManager { try { PolicyManagementDAOFactory.openConnection(); policyList = policyDAO.getAllPolicies(); - - for (Policy policy : policyList) { - for (Profile profile : profileList) { - if (policy.getProfileId() == profile.getProfileId()) { - policy.setProfile(profile); - } - } - policy.setRoles(policyDAO.getPolicyAppliedRoles(policy.getId())); - policy.setUsers(policyDAO.getPolicyAppliedUsers(policy.getId())); - policy.setPolicyCriterias(policyDAO.getPolicyCriteria(policy.getId())); - - List deviceGroupWrappers = policyDAO.getDeviceGroupsOfPolicy(policy.getId()); - if (!deviceGroupWrappers.isEmpty()) { - deviceGroupWrappers = this.getDeviceGroupNames(deviceGroupWrappers); - } - policy.setDeviceGroups(deviceGroupWrappers); - - } - Collections.sort(policyList); + this.buildPolicyList(policyList, profileList); } catch (PolicyManagerDAOException e) { throw new PolicyManagementException("Error occurred while getting all the policies.", e); } catch (SQLException e) { @@ -1144,4 +1126,60 @@ public class PolicyManagerImpl implements PolicyManager { return policyRevokeOperation; } + @Override + public List getPolicies(String type) throws PolicyManagementException { + List policyList; + List profileList; + try { + profileList = profileManager.getAllProfiles(); + } catch (ProfileManagementException e) { + throw new PolicyManagementException("Error occurred while getting all the profiles.", e); + } + try { + PolicyManagementDAOFactory.openConnection(); + policyList = policyDAO.getAllPolicies(type); + this.buildPolicyList(policyList, profileList); + } catch (PolicyManagerDAOException e) { + String msg = "Error occurred while getting all the policies. "; + log.error(msg, e); + throw new PolicyManagementException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source "; + log.error(msg, e); + throw new PolicyManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting device groups. "; + log.error(msg, e); + throw new PolicyManagementException(msg, e); + } finally { + PolicyManagementDAOFactory.closeConnection(); + } + + for (Policy policy : policyList) { + policy.setDevices(this.getPolicyAppliedDevicesIds(policy.getId())); + } + + return policyList; + } + + private void buildPolicyList(List policyList, List profileList) + throws PolicyManagerDAOException, GroupManagementException { + for (Policy policy : policyList) { + for (Profile profile : profileList) { + if (policy.getProfileId() == profile.getProfileId()) { + policy.setProfile(profile); + } + } + policy.setRoles(policyDAO.getPolicyAppliedRoles(policy.getId())); + policy.setUsers(policyDAO.getPolicyAppliedUsers(policy.getId())); + policy.setPolicyCriterias(policyDAO.getPolicyCriteria(policy.getId())); + + List deviceGroupWrappers = policyDAO.getDeviceGroupsOfPolicy(policy.getId()); + if (!deviceGroupWrappers.isEmpty()) { + deviceGroupWrappers = this.getDeviceGroupNames(deviceGroupWrappers); + } + policy.setDeviceGroups(deviceGroupWrappers); + } + Collections.sort(policyList); + } } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java index e88343bc2d..6dc56ab346 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java @@ -132,6 +132,7 @@ public class PolicyManagerServiceImplTest extends BasePolicyManagementDAOTest { policy1.setDeviceGroups(deviceGroupWrappers); List devices = new ArrayList(); policy1.setDevices(devices); + policy1.setPolicyType("GENERAL"); policy1.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); policy1 = policyManagerService.addPolicy(policy1); diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/PolicyCreator.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/PolicyCreator.java index 9dc81df195..b4d14788f7 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/PolicyCreator.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/PolicyCreator.java @@ -40,6 +40,7 @@ public class PolicyCreator { policy.setCompliance("NOTIFY"); policy.setOwnershipType("COPE"); policy.setDescription("This is the first policy."); + policy.setPolicyType("GENERAL"); return policy; } @@ -51,6 +52,7 @@ public class PolicyCreator { policy.setPolicyName("Test_Policy_02"); policy.setGeneric(true); policy.setProfile(profile); + policy.setPolicyType("GENERAL"); policy.setDevices(DeviceCreator.getDeviceList2(DeviceTypeCreator.getDeviceType())); policy.setCompliance("ENFORCE"); @@ -110,7 +112,7 @@ public class PolicyCreator { policy.setRoles(roles); policy.setCompliance("ENFORCE"); policy.setOwnershipType("BYOD"); - + policy.setPolicyType("GENERAL"); PolicyCriterion criterion = new PolicyCriterion(); @@ -144,7 +146,7 @@ public class PolicyCreator { policy.setCompliance("MONITOR"); policy.setOwnershipType("BYOD"); - + policy.setPolicyType("GENERAL"); List roles = new ArrayList(); roles.add("Role_04"); roles.add("Role_05"); diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql index 6c77071c0c..379d4a4652 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql @@ -200,6 +200,7 @@ CREATE TABLE IF NOT EXISTS DM_POLICY ( PRIORITY INT NOT NULL, ACTIVE INT(2) NOT NULL, UPDATED INT(1) NULL, + POLICY_TYPE VARCHAR(45) NULL, PRIMARY KEY (ID) , CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID ) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index 88419e9082..60597bc43d 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -193,6 +193,7 @@ CREATE TABLE IF NOT EXISTS DM_POLICY ( PRIORITY INT NOT NULL, ACTIVE INT(2) NOT NULL, UPDATED INT(1) NULL, + POLICY_TYPE VARCHAR(45) NULL, PRIMARY KEY (ID) , CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID ) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 3023883547..c87b947eca 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -246,6 +246,7 @@ CREATE TABLE DM_POLICY ( PRIORITY INTEGER NOT NULL, ACTIVE BIT NOT NULL DEFAULT 0, UPDATED BIT NULL DEFAULT 0, + POLICY_TYPE VARCHAR(45) NULL, PRIMARY KEY (ID) , CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID) REFERENCES DM_PROFILE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index 22c0b7ec9e..cca244f67f 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -224,6 +224,7 @@ CREATE TABLE IF NOT EXISTS DM_POLICY ( PRIORITY INT NOT NULL, ACTIVE INT(2) NOT NULL, UPDATED INT(1) NULL, + POLICY_TYPE VARCHAR(45) NULL, PRIMARY KEY (ID) , CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID ) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index e428ab2183..5ee36a2193 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -357,6 +357,7 @@ CREATE TABLE DM_POLICY ( PRIORITY NUMBER(10) NOT NULL, ACTIVE NUMBER(10) NOT NULL, UPDATED NUMBER(10) NULL, + POLICY_TYPE VARCHAR2(45) NULL, CONSTRAINT PK_DM_PROFILE_DM_POLICY PRIMARY KEY (ID) , CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID ) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index 27e674e5a3..e5a5976b6f 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -194,6 +194,7 @@ CREATE TABLE IF NOT EXISTS DM_POLICY ( PRIORITY INTEGER NOT NULL, ACTIVE INTEGER NOT NULL, UPDATED INTEGER NULL, + POLICY_TYPE VARCHAR(45) NULL, CONSTRAINT FK_DM_PROFILE_DM_POLICY FOREIGN KEY (PROFILE_ID ) REFERENCES DM_PROFILE (ID )