Adding entity application mapping to the database

When an application installation request is made other than adding an application install operation a mapping between the devices and the installed applications are kept in the database. In a case where an enterprise wide installation happens a mapping is made with the respective entity and the application.

This commit implement the mapping function.

Related to issue wso2/product-iots#1688
feature/appm-store/pbac
Madawa Soysa 7 years ago
parent debe93cb03
commit b911c9e169

@ -18,12 +18,71 @@
*/
package org.wso2.carbon.device.application.mgt.core.dao;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import java.util.List;
/**
* This interface provides the list of operations that are supported with subscription database.
*
*/
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
public interface SubscriptionDAO {
int addDeviceApplicationMapping(String deviceIdentifier, String applicationUUID, boolean installed) throws ApplicationManagementException;
/**
* Adds a mapping between devices and the application which the application is installed on.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param deviceList List of {@link Device} which the application is installed on
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeDeviceToApplication(int tenantId, String subscribedBy, List<Device> deviceList, int appId,
int releaseId) throws ApplicationManagementDAOException;
/**
* Adds a mapping between user and the application which the application is installed on. This mapping will be
* added when an enterprise installation triggered to the user.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param userList list of user names of the users whose devices are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeUserToApplication(int tenantId, String subscribedBy, List<String> userList, int appId, int releaseId)
throws ApplicationManagementDAOException;
/**
* Adds a mapping between user and the application which the application is installed on. This mapping will be
* added when an enterprise installation triggered to the role.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param roleList list of roles which belongs devices are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeRoleToApplication(int tenantId, String subscribedBy, List<String> roleList, int appId, int releaseId)
throws ApplicationManagementDAOException;
/**
* Adds a mapping between user and the application which the application is installed on. This mapping will be
* added when an enterprise installation triggered to the role.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param groupList list of {@link DeviceGroup} which belongs the devices that are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeGroupToApplication(int tenantId, String subscribedBy, List<DeviceGroup> groupList, int appId,
int releaseId) throws ApplicationManagementDAOException;
}

@ -19,55 +19,152 @@ package org.wso2.carbon.device.application.mgt.core.dao.impl.subscription;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO;
import org.wso2.carbon.device.application.mgt.core.dao.common.Util;
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import java.sql.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO {
private static Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class);
@Override
public int addDeviceApplicationMapping(String deviceIdentifier, String applicationUUID, boolean installed) throws
ApplicationManagementException {
public void subscribeDeviceToApplication(int tenantId, String subscribedBy, List<Device> deviceList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
int mappingId = -1;
try {
conn = this.getDBConnection();
String sql = "SELECT ID FROM APPM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_IDENTIFIER = ? AND " +
"APPLICATION_UUID = ?";
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_DEVICE_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "DM_DEVICE_ID, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier);
stmt.setString(2, applicationUUID);
rs = stmt.executeQuery();
for (Device device : deviceList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setInt(4, device.getId());
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to device ID[" + device.getId() + "] to the application [" + appId
+ "], release[" + releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
if (!rs.next()) {
sql = "INSERT INTO APPM_DEVICE_APPLICATION_MAPPING (DEVICE_IDENTIFIER, APPLICATION_UUID, " +
"INSTALLED) VALUES (?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, deviceIdentifier);
stmt.setString(2, applicationUUID);
stmt.setBoolean(3, installed);
stmt.executeUpdate();
@Override
public void subscribeUserToApplication(int tenantId, String subscribedBy, List<String> userList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_USER_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "USER_NAME, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (String user : userList) {
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setString(4, user);
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to user[" + user + "] to the application [" + appId + "], release["
+ releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
rs = stmt.getGeneratedKeys();
if (rs.next()) {
mappingId = rs.getInt(1);
}
return mappingId;
} else {
log.warn("Device[" + deviceIdentifier + "] application[" + applicationUUID + "] mapping already " +
"exists in the DB");
return -1;
}
} catch (SQLException e) {
throw new ApplicationManagementException("Error occurred while adding device application mapping to DB", e);
@Override
public void subscribeRoleToApplication(int tenantId, String subscribedBy, List<String> roleList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_ROLE_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "ROLE_NAME, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (String role : roleList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setString(4, role);
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to role[" + role + "] to the application [" + appId + "], release["
+ releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
@Override
public void subscribeGroupToApplication(int tenantId, String subscribedBy, List<DeviceGroup> groupList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_GROUP_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "DM_GROUP_ID, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (DeviceGroup group : groupList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setInt(4, group.getGroupId());
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to group ID[" + group.getGroupId() + "] to the application [" + appId
+ "], release[" + releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, rs);
Util.cleanupResources(stmt, null);
}
}
}

@ -19,15 +19,19 @@ package org.wso2.carbon.device.application.mgt.core.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.HelperUtil;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
@ -52,6 +56,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class);
private static final String INSTALL_APPLICATION = "INSTALL_APPLICATION";
private SubscriptionDAO subscriptionDAO;
public SubscriptionManagerImpl() {
this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO();
}
@Override
public ApplicationInstallResponse installApplicationForDevices(String applicationUUID,
@ -59,7 +68,10 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + deviceList.size() + "devices.");
}
return installApplication(applicationUUID, deviceList);
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
return installApplication(application, deviceList);
}
@Override
@ -68,13 +80,15 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + userList.size() + " users.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String user : userList) {
try {
List<Device> devicesOfUser = HelperUtil.getDeviceManagementProviderService().getDevicesOfUser(user);
for (Device device : devicesOfUser) {
deviceList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
devicesOfUser.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
if (log.isDebugEnabled()) {
log.debug(devicesOfUser.size() + " found for the provided user list");
}
@ -83,7 +97,22 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
e);
}
}
return installApplication(applicationUUID, deviceList);
ApplicationInstallResponse response = installApplication(application, deviceList);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, userList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
@ -92,13 +121,15 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + roleList.size() + " roles.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String role : roleList) {
try {
List<Device> devicesOfRole = HelperUtil.getDeviceManagementProviderService().getAllDevicesOfRole(role);
for (Device device : devicesOfRole) {
deviceList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
devicesOfRole.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
if (log.isDebugEnabled()) {
log.debug(devicesOfRole.size() + " found for role: " + role);
}
@ -107,7 +138,22 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
"Error when extracting the device list from role[" + role + "].", e);
}
}
return installApplication(applicationUUID, deviceList);
ApplicationInstallResponse response = installApplication(application, deviceList);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeRoleToApplication(tenantId, subscriber, roleList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
@ -116,23 +162,42 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + deviceGroupList.size() + " groups.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService();
List<DeviceGroup> groupList = new ArrayList<>();
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String groupName : deviceGroupList) {
try {
DeviceGroup deviceGroup = groupManagementProviderService.getGroup(groupName);
groupList.add(deviceGroup);
int deviceCount = groupManagementProviderService.getDeviceCount(deviceGroup.getGroupId());
List<Device> devicesOfGroups = groupManagementProviderService
.getDevices(deviceGroup.getGroupId(), 0, deviceCount);
for (Device device : devicesOfGroups) {
deviceList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
devicesOfGroups.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
} catch (GroupManagementException e) {
throw new ApplicationManagementException(
"Error when extracting the device list from group[" + groupName + "].", e);
}
}
return installApplication(applicationUUID, deviceList);
ApplicationInstallResponse response = installApplication(application, deviceList);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeGroupToApplication(tenantId, subscriber, groupList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
@ -141,34 +206,54 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
return null;
}
private ApplicationInstallResponse installApplication(String applicationUUID, List<DeviceIdentifier> deviceList)
throws ApplicationManagementException {
private ApplicationInstallResponse installApplication(Application application,
List<DeviceIdentifier> deviceIdentifierList) throws ApplicationManagementException {
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService();
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
ApplicationInstallResponse response = validateDevices(deviceList, application.getType());
ApplicationInstallResponse response = validateDevices(deviceIdentifierList, application.getType());
/*
Group the valid device list by device type. Following lambda expression produces a map containing device type
as the key and the list of device identifiers as the corresponding value.
*/
Map<String, List<DeviceIdentifier>> deviceTypeIdentifierMap = response.getSuccessfulDevices().stream()
.collect(Collectors.groupingBy(DeviceIdentifier::getType));
for(Map.Entry<String, List<DeviceIdentifier>> entry: deviceTypeIdentifierMap.entrySet()) {
for (Map.Entry<String, List<DeviceIdentifier>> entry : deviceTypeIdentifierMap.entrySet()) {
Operation operation = generateOperationPayloadByDeviceType(entry.getKey(), application);
try {
Activity activity = deviceManagementProviderService
.addOperation(entry.getKey(), operation, entry.getValue());
response.setActivity(activity);
} catch (OperationManagementException e) {
throw new ApplicationManagementException("Error occurred while adding the application install"
+ " operation to devices" , e);
response.setSuccessfulDevices(null);
response.setFailedDevices(deviceIdentifierList);
throw new ApplicationManagementException("Error occurred while adding the application install "
+ "operation to devices", e);
} catch (InvalidDeviceException e) {
//This exception should not occur because the validation has already been done.
throw new ApplicationManagementException("The list of device identifiers are invalid");
}
}
//todo: add device application mapping
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
List<Device> deviceList = new ArrayList<>();
for (DeviceIdentifier deviceIdentifier : response.getSuccessfulDevices()) {
try {
deviceList.add(deviceManagementProviderService.getDevice(deviceIdentifier));
} catch (DeviceManagementException e) {
log.error("Unable to fetch device for device identifier: " + deviceIdentifier.toString());
}
}
subscriptionDAO.subscribeDeviceToApplication(tenantId, subscriber, deviceList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}

@ -62,7 +62,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
}
try {
ApplicationInstallResponse response= subscriptionManager.installApplicationForDevices(applicationUUID,
ApplicationInstallResponse response = subscriptionManager.installApplicationForDevices(applicationUUID,
installationDetails.getDeviceIdentifiers());
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {
@ -95,7 +95,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
try{
try {
if (EnterpriseInstallationDetails.EnterpriseEntity.USER.equals(enterpriseEntity)) {
response = subscriptionManager.installApplicationForUsers(applicationUUID, entityValueList);
} else if (EnterpriseInstallationDetails.EnterpriseEntity.ROLE.equals(enterpriseEntity)) {
@ -108,7 +108,6 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)

Loading…
Cancel
Save