From bd35583737457d31063f419092e73b557ae2fa92 Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Wed, 10 May 2023 04:47:36 +0000 Subject: [PATCH] Fix device enrolment and syncing with MSSQL db ## Purpose * Fixes https://roadmap.entgra.net/issues/9859 * Fixes https://roadmap.entgra.net/issues/9892 ## Details * Fix dbscripts to support events and events mapping * Fix config operation implementation in MSSQL Co-authored-by: prathabanKavin Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/113 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../dao/impl/ConfigOperationMSSQLDAOImpl.java | 140 ++++++++++++------ .../main/resources/dbscripts/cdm/mssql.sql | 79 +++++++++- 2 files changed, 170 insertions(+), 49 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationMSSQLDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationMSSQLDAOImpl.java index 14cc9b8afa..2b20c83c77 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationMSSQLDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationMSSQLDAOImpl.java @@ -21,11 +21,11 @@ package org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; import org.wso2.carbon.device.mgt.core.dto.operation.mgt.ConfigOperation; import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation; import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; -import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOUtil; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -39,6 +39,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Date; import java.util.List; public class ConfigOperationMSSQLDAOImpl extends GenericOperationDAOImpl { @@ -47,24 +48,32 @@ public class ConfigOperationMSSQLDAOImpl extends GenericOperationDAOImpl { @Override public int addOperation(Operation operation) throws OperationManagementDAOException { - int operationId = 0; - PreparedStatement stmt = null; try { - operationId = super.addOperation(operation); - operation.setCreatedTimeStamp(new Timestamp(new java.util.Date().getTime()).toString()); - Connection conn = OperationManagementDAOFactory.getConnection(); - stmt = conn.prepareStatement("INSERT INTO DM_CONFIG_OPERATION(OPERATION_ID, OPERATION_CONFIG) VALUES(?, ?)"); - stmt.setInt(1, operationId); - stmt.setBinaryStream(2, toByteArrayInputStream(operation)); - stmt.executeUpdate(); + operation.setCreatedTimeStamp(new Timestamp(new Date().getTime()).toString()); + Connection connection = OperationManagementDAOFactory.getConnection(); + String sql = "INSERT INTO DM_OPERATION(TYPE, CREATED_TIMESTAMP, RECEIVED_TIMESTAMP, OPERATION_CODE, " + + "INITIATED_BY, OPERATION_DETAILS) VALUES (?, ?, ?, ?, ?, ?)"; + try (PreparedStatement stmt = connection.prepareStatement(sql, new String[]{"id"})) { + stmt.setString(1, operation.getType().toString()); + stmt.setLong(2, DeviceManagementDAOUtil.getCurrentUTCTime()); + stmt.setLong(3, 0); + stmt.setString(4, operation.getCode()); + stmt.setString(5, operation.getInitiatedBy()); + stmt.setObject(6, operation); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + int id = -1; + if (rs.next()) { + id = rs.getInt(1); + } + return id; + } + } } catch (SQLException e) { - String msg = "Error occurred while adding command operation " + operationId; + String msg = "Error occurred while adding command operation" + operation.getId(); log.error(msg, e); throw new OperationManagementDAOException(msg, e); - } finally { - OperationManagementDAOUtil.cleanupResources(stmt); } - return operationId; } private ByteArrayInputStream toByteArrayInputStream(Operation operation) throws OperationManagementDAOException { @@ -111,30 +120,41 @@ public class ConfigOperationMSSQLDAOImpl extends GenericOperationDAOImpl { @Override public Operation getOperation(int operationId) throws OperationManagementDAOException { - PreparedStatement stmt = null; - ResultSet rs = null; ConfigOperation configOperation = null; - + ByteArrayInputStream bais; + ObjectInputStream ois; try { Connection conn = OperationManagementDAOFactory.getConnection(); - String sql = "SELECT OPERATION_ID, ENABLED, OPERATION_CONFIG FROM DM_CONFIG_OPERATION WHERE OPERATION_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, operationId); - rs = stmt.executeQuery(); - - if (rs.next()) { - InputStream operationDetails = rs.getBinaryStream("OPERATION_CONFIG"); - configOperation = (ConfigOperation) fromByteArrayInputStream(operationDetails); - configOperation.setId(rs.getInt("OPERATION_ID")); - configOperation.setEnabled(rs.getBoolean("ENABLED")); + String sql = "SELECT ID, ENABLED, OPERATION_DETAILS FROM DM_OPERATION WHERE ID = ? AND TYPE='CONFIG'"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, operationId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + byte[] operationDetails = rs.getBytes("OPERATION_DETAILS"); + bais = new ByteArrayInputStream(operationDetails); + ois = new ObjectInputStream(bais); + configOperation = (ConfigOperation) ois.readObject(); + configOperation.setId(rs.getInt("ID")); + configOperation.setEnabled(rs.getBoolean("ENABLED")); + } + } } + } catch (IOException e) { + String msg = "IO Error occurred while de serialize the policy operation " + + "object"; + log.error(msg, e); + throw new OperationManagementDAOException(msg, e); + } catch (ClassNotFoundException e) { + String msg = "Class not found error occurred while de serialize the policy " + + "operation object"; + log.error(msg, e); + throw new OperationManagementDAOException(msg, e); } catch (SQLException e) { - String msg = "SQL Error occurred while retrieving the policy operation object available for the id '" + String msg = "SQL Error occurred while retrieving the policy operation " + + "object available for the id '" + operationId; log.error(msg, e); throw new OperationManagementDAOException(msg, e); - } finally { - OperationManagementDAOUtil.cleanupResources(stmt, rs); } return configOperation; } @@ -142,36 +162,60 @@ public class ConfigOperationMSSQLDAOImpl extends GenericOperationDAOImpl { @Override public List getOperationsByDeviceAndStatus(int enrolmentId, Operation.Status status) throws OperationManagementDAOException { - PreparedStatement stmt = null; - ResultSet rs = null; ConfigOperation configOperation; List operations = new ArrayList<>(); - + ByteArrayInputStream bais = null; + ObjectInputStream ois = null; try { Connection conn = OperationManagementDAOFactory.getConnection(); - String sql = "SELECT co.OPERATION_ID, co.OPERATION_CONFIG FROM DM_CONFIG_OPERATION co " + + String sql = "SELECT co.ID, co.OPERATION_DETAILS FROM DM_OPERATION co " + "INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING WHERE ENROLMENT_ID = ? " + - "AND STATUS = ?) dm ON dm.OPERATION_ID = co.OPERATION_ID"; - - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrolmentId); - stmt.setString(2, status.toString()); - rs = stmt.executeQuery(); - - while (rs.next()) { - InputStream operationDetails = rs.getBinaryStream("OPERATION_CONFIG"); - configOperation = (ConfigOperation) fromByteArrayInputStream(operationDetails); - configOperation.setStatus(status); - configOperation.setId(rs.getInt("OPERATION_ID")); - operations.add(configOperation); + "AND STATUS = ?) dm ON dm.OPERATION_ID = co.ID WHERE co.TYPE = 'CONFIG'"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, enrolmentId); + stmt.setString(2, status.toString()); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + byte[] operationDetails = rs.getBytes("OPERATION_DETAILS"); + bais = new ByteArrayInputStream(operationDetails); + ois = new ObjectInputStream(bais); + configOperation = (ConfigOperation) ois.readObject(); + configOperation.setStatus(status); + configOperation.setId(rs.getInt("ID")); + operations.add(configOperation); + } + } } + } catch (IOException e) { + String msg = "IO Error occurred while de serialize the configuration " + + "operation object"; + log.error(msg, e); + throw new OperationManagementDAOException(msg, e); + } catch (ClassNotFoundException e) { + String msg = "Class not found error occurred while de serialize the " + + "configuration operation object"; + log.error(msg, e); + throw new OperationManagementDAOException(msg, e); } catch (SQLException e) { String msg = "SQL error occurred while retrieving the operation available " + "for the device'" + enrolmentId + "' with status '" + status.toString(); log.error(msg, e); throw new OperationManagementDAOException(msg, e); } finally { - OperationManagementDAOUtil.cleanupResources(stmt, rs); + if (bais != null) { + try { + bais.close(); + } catch (IOException e) { + log.warn("Error occurred while closing ByteArrayOutputStream", e); + } + } + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + log.warn("Error occurred while closing ObjectOutputStream", e); + } + } } return operations; } 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 5d2345e77f..07275d894c 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 @@ -729,7 +729,7 @@ ORDER BY TENANT_ID, DEVICE_ID'); -- END OF DASHBOARD RELATED VIEWS -- -- DM_GEOFENCE TABLE-- - +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_GEOFENCE]') AND TYPE IN (N'U')) CREATE TABLE DM_GEOFENCE ( ID INT IDENTITY NOT NULL, FENCE_NAME VARCHAR(255) NOT NULL, @@ -747,6 +747,83 @@ CREATE TABLE DM_GEOFENCE ( -- END OF DM_GEOFENCE TABLE-- +-- DM_GEOFENCE_GROUP_MAPPING TABLE-- +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_GEOFENCE_GROUP_MAPPING]') AND TYPE IN (N'U')) +CREATE TABLE DM_GEOFENCE_GROUP_MAPPING ( + ID INT IDENTITY NOT NULL, + FENCE_ID INT NOT NULL, + GROUP_ID INT NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT fk_dm_geofence_group_mapping_geofence + FOREIGN KEY (FENCE_ID) + REFERENCES DM_GEOFENCE (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT fk_dm_geofence_group_mapping_group + FOREIGN KEY (GROUP_ID) + REFERENCES DM_GROUP (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION +); + +-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE-- + +-- DM_DEVICE_EVENT TABLE -- +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_EVENT]') AND TYPE IN (N'U')) +CREATE TABLE DM_DEVICE_EVENT ( + ID INT IDENTITY NOT NULL, + EVENT_SOURCE VARCHAR(100) NOT NULL, + EVENT_LOGIC VARCHAR(100) NOT NULL, + ACTIONS TEXT DEFAULT NULL, + CREATED_TIMESTAMP TIMESTAMP NOT NULL, + TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (ID) +); + +-- END OF DM_DEVICE_EVENT TABLE -- + +-- DM_DEVICE_EVENT_GROUP_MAPPING TABLE-- +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_EVENT_GROUP_MAPPING]') AND TYPE IN (N'U')) +CREATE TABLE DM_DEVICE_EVENT_GROUP_MAPPING ( + ID INT IDENTITY NOT NULL, + EVENT_ID INT NOT NULL, + GROUP_ID INT NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT fk_dm_event_group_mapping_event + FOREIGN KEY (EVENT_ID) + REFERENCES DM_DEVICE_EVENT (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT fk_dm_event_group_mapping_group + FOREIGN KEY (GROUP_ID) + REFERENCES DM_GROUP (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION +); + +-- END OF DM_DEVICE_EVENT_GROUP_MAPPING TABLE-- + +-- DM_GEOFENCE_GROUP_MAPPING TABLE-- +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_GEOFENCE_EVENT_MAPPING]') AND TYPE IN (N'U')) +CREATE TABLE DM_GEOFENCE_EVENT_MAPPING ( + ID INT IDENTITY NOT NULL, + FENCE_ID INT NOT NULL, + EVENT_ID INT NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT fk_dm_geofence_event_mapping_geofence + FOREIGN KEY (FENCE_ID) + REFERENCES DM_GEOFENCE (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT fk_dm_geofence_event_mapping_event + FOREIGN KEY (EVENT_ID) + REFERENCES DM_DEVICE_EVENT (ID) + ON DELETE NO ACTION + ON UPDATE NO ACTION +); + +-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE-- + -- DYNAMIC TASK TABLES-- IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DYNAMIC_TASK]') AND TYPE IN (N'U')) CREATE TABLE DYNAMIC_TASK (