diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/pom.xml new file mode 100644 index 00000000000..32721655887 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/pom.xml @@ -0,0 +1,82 @@ + + + + org.wso2.carbon.devicemgt + device-mgt + 1.1.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.mgt.analytics.dashboard + bundle + WSO2 Carbon - Device Management Dashboard Analytics + WSO2 Carbon - Device Management Dashboard Analytics + http://wso2.org + + + + org.eclipse.osgi + org.eclipse.osgi.services + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + + + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + 1.4.0 + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Device Management Dashboard Analytics Bundle + + org.wso2.carbon.device.mgt.analytics.dashboard.dao, + org.wso2.carbon.device.mgt.analytics.dashboard.internal + + + org.wso2.carbon.device.mgt.analytics.dashboard + + + org.osgi.framework, + org.osgi.service.component, + org.apache.commons.logging.*, + javax.sql, + org.wso2.carbon.context, + org.wso2.carbon.device.mgt.common.*, + org.wso2.carbon.device.mgt.core.*, + org.wso2.carbon.ndatasource.core.*; + + + + + + + + \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/GadgetDataService.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/GadgetDataService.java new file mode 100644 index 00000000000..b9a434721c8 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/GadgetDataService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard; + +import java.util.Map; + +/** + * To be updated... + */ +public interface GadgetDataService { + + @SuppressWarnings("unused") + int getTotalDeviceCount(Map filters); + + @SuppressWarnings("unused") + int getActiveDeviceCount(); + + @SuppressWarnings("unused") + int getInactiveDeviceCount(); + + @SuppressWarnings("unused") + int getRemovedDeviceCount(); + + @SuppressWarnings("unused") + int getNonCompliantDeviceCount(); + + @SuppressWarnings("unused") + int getUnmonitoredDeviceCount(); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAO.java new file mode 100644 index 00000000000..adfb4359f68 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAO.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.dao; + +import java.util.List; +import java.util.Map; + +public interface GadgetDataServiceDAO { + + /** + * Method to get total filtered device count from a particular tenant. + * + * @param filters List of filters to be applied in getting + * total filtered device count. + * + * @return Total filtered device count. + */ + int getTotalDeviceCount(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + int getFeatureNonCompliantDeviceCount(Map filters) throws GadgetDataServiceDAOException; + + int getActiveDeviceCount() throws GadgetDataServiceDAOException; + + int getInactiveDeviceCount() throws GadgetDataServiceDAOException; + + int getRemovedDeviceCount() throws GadgetDataServiceDAOException; + + /** + * Method to get non-compliant device count. + * + * @return Non-compliant device count. + */ + @SuppressWarnings("unused") + int getNonCompliantDeviceCount() throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + Map getNonCompliantDeviceCountsByFeatures() throws GadgetDataServiceDAOException; + + /** + * Method to get unmonitored device count. + * + * @return Unmonitored device count. + */ + @SuppressWarnings("unused") + int getUnmonitoredDeviceCount() throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + Map getDeviceCountsByPlatforms(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + Map getFeatureNonCompliantDeviceCountsByPlatforms(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + Map getDeviceCountsByOwnershipTypes(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + Map getFeatureNonCompliantDeviceCountsByOwnershipTypes(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + List> getDevicesWithDetails(Map filters) throws GadgetDataServiceDAOException; + + @SuppressWarnings("unused") + List> getFeatureNonCompliantDevicesWithDetails(Map filters) throws GadgetDataServiceDAOException; + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOException.java new file mode 100644 index 00000000000..3ebf841f130 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOException.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.dao; + +@SuppressWarnings("unused") +/** + * Custom exception class for data access related exceptions. + */ +public class GadgetDataServiceDAOException extends Exception { + private String errorMessage; + private static final long serialVersionUID = 2021891706072918864L; + + /** + * Constructs a new exception with the specific error message and nested exception. + * + * @param errorMessage specific error message. + * @param nestedException Nested exception. + */ + public GadgetDataServiceDAOException(String errorMessage, Exception nestedException) { + super(errorMessage, nestedException); + setErrorMessage(errorMessage); + } + + /** + * Constructs a new exception with the specific error message and cause. + * + * @param errorMessage Specific error message. + * @param cause Cause of this exception. + */ + public GadgetDataServiceDAOException(String errorMessage, Throwable cause) { + super(errorMessage, cause); + setErrorMessage(errorMessage); + } + + /** + * Constructs a new exception with the specific error message. + * + * @param errorMessage Specific error message. + */ + public GadgetDataServiceDAOException(String errorMessage) { + super(errorMessage); + setErrorMessage(errorMessage); + } + + /** + * Constructs a new exception with the specific error message and cause. + * + * @param cause Cause of this exception. + */ + public GadgetDataServiceDAOException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOFactory.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOFactory.java new file mode 100644 index 00000000000..bb2d44ac636 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOFactory.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException; +import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig; +import org.wso2.carbon.device.mgt.core.config.datasource.JNDILookupDefinition; +import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Hashtable; +import java.util.List; + +@SuppressWarnings("unused") +public class GadgetDataServiceDAOFactory { + private static final Log log = LogFactory.getLog(GadgetDataServiceDAOFactory.class); + private static DataSource dataSource; + private static String databaseEngine; + private static ThreadLocal currentConnection = new ThreadLocal<>(); + + public static GadgetDataServiceDAO getGadgetDataServiceDAO() { + return new GadgetDataServiceDAOImpl(); + } + + public static void init(DataSourceConfig config) { + dataSource = resolveDataSource(config); + try { + databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + } + + public static void init(DataSource dtSource) { + dataSource = dtSource; + try { + databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + } + + public static void openConnection() throws SQLException { + Connection conn = currentConnection.get(); + if (conn != null) { + throw new IllegalTransactionStateException("A transaction is already active within the context of " + + "this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " + + "transaction is already active is a sign of improper transaction handling"); + } + conn = dataSource.getConnection(); + currentConnection.set(conn); + } + + public static Connection getConnection() throws SQLException { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + return conn; + } + + public static void closeConnection() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while close the connection"); + } + currentConnection.remove(); + } + + + /** + * Resolve data source from the data source definition + * + * @param config data source configuration + * @return data source resolved from the data source definition + */ + private static DataSource resolveDataSource(DataSourceConfig config) { + DataSource dataSource = null; + if (config == null) { + throw new RuntimeException( + "Device Management Repository data source configuration " + "is null and " + + "thus, is not initialized"); + } + JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition(); + if (jndiConfig != null) { + if (log.isDebugEnabled()) { + log.debug("Initializing Device Management Repository data source using the JNDI " + + "Lookup Definition"); + } + List jndiPropertyList = jndiConfig.getJndiProperties(); + if (jndiPropertyList != null) { + Hashtable jndiProperties = new Hashtable<>(); + for (JNDILookupDefinition.JNDIProperty prop : jndiPropertyList) { + jndiProperties.put(prop.getName(), prop.getValue()); + } + dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), jndiProperties); + } else { + dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), null); + } + } + return dataSource; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOImpl.java new file mode 100644 index 00000000000..7f0cede95bd --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/dao/GadgetDataServiceDAOImpl.java @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class GadgetDataServiceDAOImpl implements GadgetDataServiceDAO { + @SuppressWarnings("unused") + private static final Log log = LogFactory.getLog(GadgetDataServiceDAOImpl.class); + + @Override + public int getTotalDeviceCount(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 1; + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public int getFeatureNonCompliantDeviceCount(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 2; + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public int getActiveDeviceCount() throws GadgetDataServiceDAOException { + int filteringViewID = 1; + Map filters = new HashMap<>(); + filters.put("CONNECTIVITY_STATUS", "ACTIVE"); + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public int getInactiveDeviceCount() throws GadgetDataServiceDAOException { + int filteringViewID = 1; + Map filters = new HashMap<>(); + filters.put("CONNECTIVITY_STATUS", "INACTIVE"); + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public int getRemovedDeviceCount() throws GadgetDataServiceDAOException { + int filteringViewID = 1; + Map filters = new HashMap<>(); + filters.put("CONNECTIVITY_STATUS", "REMOVED"); + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public int getNonCompliantDeviceCount() throws GadgetDataServiceDAOException { + int filteringViewID = 1; + Map filters = new HashMap<>(); + filters.put("IS_COMPLIANT", 0); + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public Map getNonCompliantDeviceCountsByFeatures() throws GadgetDataServiceDAOException { + Connection con; + PreparedStatement stmt = null; + ResultSet rs = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + Map filteredNonCompliantDeviceCountsByFeatures = new HashMap<>(); + try { + con = this.getConnection(); + String sql = "SELECT FEATURE_CODE, COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_1 " + + "WHERE TENANT_ID = ? GROUP BY FEATURE_CODE"; + stmt = con.prepareStatement(sql); + stmt.setInt(1, tenantId); + // executing query + rs = stmt.executeQuery(); + // fetching query results + while (rs.next()) { + filteredNonCompliantDeviceCountsByFeatures. + put(rs.getString("FEATURE_CODE"), rs.getInt("DEVICE_COUNT")); + } + } catch (SQLException e) { + throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return filteredNonCompliantDeviceCountsByFeatures; + } + + @Override + public int getUnmonitoredDeviceCount() throws GadgetDataServiceDAOException { + int filteringViewID = 1; + Map filters = new HashMap<>(); + filters.put("POLICY_ID", -1); + return this.getDeviceCount(filteringViewID, filters); + } + + @Override + public Map getDeviceCountsByPlatforms(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 1; + return this.getDeviceCountsByPlatforms(filteringViewID, filters); + } + + @Override + public Map getFeatureNonCompliantDeviceCountsByPlatforms(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 2; + return this.getDeviceCountsByPlatforms(filteringViewID, filters); + } + + @Override + public Map getDeviceCountsByOwnershipTypes(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 1; + return this.getDeviceCountsByOwnershipTypes(filteringViewID, filters); + } + + @Override + public Map getFeatureNonCompliantDeviceCountsByOwnershipTypes(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 2; + return this.getDeviceCountsByOwnershipTypes(filteringViewID, filters); + } + + @Override + public List> getDevicesWithDetails(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 1; + return this.getDevicesWithDetails(filteringViewID, filters); + } + + @Override + public List> getFeatureNonCompliantDevicesWithDetails(Map filters) throws GadgetDataServiceDAOException { + int filteringViewID = 2; + return this.getDevicesWithDetails(filteringViewID, filters); + } + + private int getDeviceCount(int filteringViewID, Map filters) throws GadgetDataServiceDAOException { + Connection con; + PreparedStatement stmt = null; + ResultSet rs = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + int filteredDeviceCount = 0; + try { + con = this.getConnection(); + String sql; + if (filteringViewID == 1) { + sql = "SELECT COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_1 WHERE TENANT_ID = ?"; + } else { + // if filteringViewID == 2 + sql = "SELECT COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_2 WHERE TENANT_ID = ?"; + } + // appending filters to support advanced filtering options + // [1] appending filter columns + if (filters != null && filters.size() > 0) { + for (String column : filters.keySet()) { + sql = sql + " AND " + column + " = ?"; + } + } + stmt = con.prepareStatement(sql); + // [2] appending filter column values + stmt.setInt(1, tenantId); + if (filters != null && filters.values().size() > 0) { + int i = 2; + for (Object value : filters.values()) { + if (value instanceof Integer) { + stmt.setInt(i, (Integer) value); + } else if (value instanceof String) { + stmt.setString(i, (String) value); + } + i++; + } + } + // executing query + rs = stmt.executeQuery(); + // fetching query results + while (rs.next()) { + filteredDeviceCount = rs.getInt("DEVICE_COUNT"); + } + } catch (SQLException e) { + throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return filteredDeviceCount; + } + + private Map getDeviceCountsByPlatforms(int filteringViewID, Map filters) throws GadgetDataServiceDAOException { + Connection con; + PreparedStatement stmt = null; + ResultSet rs = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + Map filteredDeviceCountsByPlatforms = new HashMap<>(); + try { + con = this.getConnection(); + String sql, advancedSqlFiltering = ""; + // appending filters if exist, to support advanced filtering options + // [1] appending filter columns + if (filters.size() > 0) { + for (String column : filters.keySet()) { + advancedSqlFiltering = advancedSqlFiltering + "AND " + column + " = ? "; + } + } + if (filteringViewID == 1) { + sql = "SELECT PLATFORM, COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_1 WHERE TENANT_ID = ? " + + advancedSqlFiltering + "GROUP BY PLATFORM"; + } else { + // if filteringViewID == 2 + sql = "SELECT PLATFORM, COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_2 WHERE TENANT_ID = ? " + + advancedSqlFiltering + "GROUP BY PLATFORM"; + } + stmt = con.prepareStatement(sql); + // [2] appending filter column values + stmt.setInt(1, tenantId); + int i = 2; + for (Object value : filters.values()) { + if (value instanceof Integer) { + stmt.setInt(i, (Integer) value); + } else if (value instanceof String) { + stmt.setString(i, (String) value); + } + i++; + } + // executing query + rs = stmt.executeQuery(); + // fetching query results + while (rs.next()) { + filteredDeviceCountsByPlatforms.put(rs.getString("PLATFORM"), rs.getInt("DEVICE_COUNT")); + } + } catch (SQLException e) { + throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return filteredDeviceCountsByPlatforms; + } + + private Map getDeviceCountsByOwnershipTypes(int filteringViewID, Map filters) throws GadgetDataServiceDAOException { + Connection con; + PreparedStatement stmt = null; + ResultSet rs = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + Map filteredDeviceCountsByOwnershipTypes = new HashMap<>(); + try { + con = this.getConnection(); + String sql, advancedSqlFiltering = ""; + // appending filters if exist, to support advanced filtering options + // [1] appending filter columns + if (filters.size() > 0) { + for (String column : filters.keySet()) { + advancedSqlFiltering = advancedSqlFiltering + "AND " + column + " = ? "; + } + } + if (filteringViewID == 1) { + sql = "SELECT PLATFORM, COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_1 WHERE TENANT_ID = ? " + + advancedSqlFiltering + "GROUP BY OWNERSHIP"; + } else { + // if filteringViewID == 2 + sql = "SELECT PLATFORM, COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_2 WHERE TENANT_ID = ? " + + advancedSqlFiltering + "GROUP BY OWNERSHIP"; + } + stmt = con.prepareStatement(sql); + // [2] appending filter column values + stmt.setInt(1, tenantId); + int i = 2; + for (Object value : filters.values()) { + if (value instanceof Integer) { + stmt.setInt(i, (Integer) value); + } else if (value instanceof String) { + stmt.setString(i, (String) value); + } + i++; + } + // executing query + rs = stmt.executeQuery(); + // fetching query results + while (rs.next()) { + filteredDeviceCountsByOwnershipTypes.put(rs.getString("PLATFORM"), rs.getInt("DEVICE_COUNT")); + } + } catch (SQLException e) { + throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return filteredDeviceCountsByOwnershipTypes; + } + + private List> getDevicesWithDetails(int filteringViewID, Map filters) throws GadgetDataServiceDAOException { + Connection con; + PreparedStatement stmt = null; + ResultSet rs = null; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + Map filteredDeviceWithDetails = new HashMap<>(); + List> filteredDevicesWithDetails = new ArrayList<>(); + try { + con = this.getConnection(); + String sql; + if (filteringViewID == 1) { + sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_1 WHERE TENANT_ID = ?"; + } else { + // if filteringViewID == 2 + sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_2 WHERE TENANT_ID = ?"; + } + // appending filters to support advanced filtering options + // [1] appending filter columns + if (filters.size() > 0) { + for (String column : filters.keySet()) { + sql = sql + " AND " + column + " = ?"; + } + } + stmt = con.prepareStatement(sql); + // [2] appending filter column values + stmt.setInt(1, tenantId); + int i = 2; + for (Object value : filters.values()) { + if (value instanceof Integer) { + stmt.setInt(i, (Integer) value); + } else if (value instanceof String) { + stmt.setString(i, (String) value); + } + i++; + } + // executing query + rs = stmt.executeQuery(); + // fetching query results + while (rs.next()) { + filteredDeviceWithDetails.put("Device-ID", rs.getInt("DEVICE_ID")); + filteredDeviceWithDetails.put("Platform", rs.getString("PLATFORM")); + filteredDeviceWithDetails.put("Ownership", rs.getString("OWNERSHIP")); + filteredDeviceWithDetails.put("Connectivity-Details", rs.getString("CONNECTIVITY_STATUS")); + filteredDevicesWithDetails.add(filteredDeviceWithDetails); + } + } catch (SQLException e) { + throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return filteredDevicesWithDetails; + } + + private Connection getConnection() throws SQLException { + return GadgetDataServiceDAOFactory.getConnection(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceComponent.java new file mode 100644 index 00000000000..193afc92da6 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceComponent.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService; +import org.wso2.carbon.device.mgt.analytics.dashboard.dao.GadgetDataServiceDAOFactory; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig; +import org.wso2.carbon.ndatasource.core.DataSourceService; + +@SuppressWarnings("unused") +/** + * @scr.component name="org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService" immediate="true" + * @scr.reference name="org.wso2.carbon.ndatasource" + * interface="org.wso2.carbon.ndatasource.core.DataSourceService" + * cardinality="1..1" + * policy="dynamic" + * bind="setDataSourceService" + * unbind="unsetDataSourceService" + */ +public class GadgetDataServiceComponent { + private static final Log log = LogFactory.getLog(GadgetDataServiceComponent.class); + + protected void activate(ComponentContext componentContext) { + if (log.isDebugEnabled()) { + log.debug("Starting Device Management Dashboard Analytics Bundle..."); + } + try { + DeviceConfigurationManager.getInstance().initConfig(); + DeviceManagementConfig config = + DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + + DataSourceConfig dsConfig = config.getDeviceManagementConfigRepository().getDataSourceConfig(); + GadgetDataServiceDAOFactory.init(dsConfig); + //Register GadgetDataService to expose corresponding data to external parties. + componentContext.getBundleContext(). + registerService(GadgetDataService.class.getName(), new GadgetDataServiceImpl(), null); + if (log.isDebugEnabled()) { + log.debug("Device Management Dashboard Analytics Bundle has been started successfully"); + } + } catch (Throwable e) { + log.error("Error occurred while initializing the bundle", e); + } + } + + protected void deactivate(ComponentContext componentContext) { + if (log.isDebugEnabled()) { + log.debug("Deactivating Device Management Dashboard Analytics Bundle..."); + } + //do nothing + } + + public void setDataSourceService(DataSourceService dataSourceService){ + + } + + public void unsetDataSourceService(DataSourceService dataSourceService){ + + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceImpl.java new file mode 100644 index 00000000000..ab91e9a81a4 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard/src/main/java/org/wso2/carbon/device/mgt/analytics/dashboard/internal/GadgetDataServiceImpl.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.analytics.dashboard.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService; +import org.wso2.carbon.device.mgt.analytics.dashboard.dao.GadgetDataServiceDAOException; +import org.wso2.carbon.device.mgt.analytics.dashboard.dao.GadgetDataServiceDAOFactory; + +import java.sql.SQLException; +import java.util.Map; + +/** + * To be updated... + */ +class GadgetDataServiceImpl implements GadgetDataService { + + @SuppressWarnings("unused") + private static final Log log = LogFactory.getLog(GadgetDataServiceImpl.class); + + @Override + public int getTotalDeviceCount(Map filters) { + int totalDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + totalDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getTotalDeviceCount(filters); + } catch (GadgetDataServiceDAOException | SQLException e) { + totalDeviceCount = -1; + return totalDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return totalDeviceCount; + } + + @Override + public int getActiveDeviceCount() { + int activeDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + activeDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getActiveDeviceCount(); + } catch (GadgetDataServiceDAOException | SQLException e) { + activeDeviceCount = -1; + return activeDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return activeDeviceCount; + } + + @Override + public int getInactiveDeviceCount() { + int inactiveDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + inactiveDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getInactiveDeviceCount(); + } catch (GadgetDataServiceDAOException | SQLException e) { + inactiveDeviceCount = -1; + return inactiveDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return inactiveDeviceCount; + } + + @Override + public int getRemovedDeviceCount() { + int removedDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + removedDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getRemovedDeviceCount(); + } catch (GadgetDataServiceDAOException | SQLException e) { + removedDeviceCount = -1; + return removedDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return removedDeviceCount; + } + + @Override + public int getNonCompliantDeviceCount() { + int nonCompliantDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + nonCompliantDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getNonCompliantDeviceCount(); + } catch (GadgetDataServiceDAOException | SQLException e) { + nonCompliantDeviceCount = -1; + return nonCompliantDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return nonCompliantDeviceCount; + } + + @Override + public int getUnmonitoredDeviceCount() { + int unmonitoredDeviceCount; + try { + GadgetDataServiceDAOFactory.openConnection(); + unmonitoredDeviceCount = GadgetDataServiceDAOFactory. + getGadgetDataServiceDAO().getUnmonitoredDeviceCount(); + } catch (GadgetDataServiceDAOException | SQLException e) { + unmonitoredDeviceCount = -1; + return unmonitoredDeviceCount; + } finally { + GadgetDataServiceDAOFactory.closeConnection(); + } + return unmonitoredDeviceCount; + } + +} diff --git a/components/device-mgt/pom.xml b/components/device-mgt/pom.xml index 096d236f4a8..59f1b40523b 100644 --- a/components/device-mgt/pom.xml +++ b/components/device-mgt/pom.xml @@ -28,7 +28,6 @@ 4.0.0 - org.wso2.carbon.devicemgt device-mgt pom WSO2 Carbon - Device Management Component @@ -39,6 +38,7 @@ org.wso2.carbon.device.mgt.common org.wso2.carbon.device.mgt.extensions org.wso2.carbon.device.mgt.ui + org.wso2.carbon.device.mgt.analytics.dashboard org.wso2.carbon.device.mgt.api org.wso2.carbon.device.mgt.analytics.data.publisher org.wso2.carbon.device.mgt.etc diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/util/PolicyManagementConstants.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/util/PolicyManagementConstants.java index 13a2df34427..bcaac2b2839 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/util/PolicyManagementConstants.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/util/PolicyManagementConstants.java @@ -22,29 +22,34 @@ public final class PolicyManagementConstants { public static final String DEVICE_CONFIG_XML_NAME = "cdm-config.xml"; public static final String ANY = "ANY"; - public static final String POLICY_BUNDLE = "POLICY_BUNDLE"; + // public static final String POLICY_BUNDLE = "POLICY_BUNDLE"; public static final String TENANT_ID = "TENANT_ID"; - public static final String MONITOR = "MONITOR"; + // public static final String MONITOR = "MONITOR"; public static final String ENFORCE = "ENFORCE"; public static final String WARN = "WARN"; public static final String BLOCK = "BLOCK"; - public static final String MONITORING_TASK_TYPE = "MONITORING_TASK"; public static final String MONITORING_TASK_NAME = "MONITORING"; public static final String MONITORING_TASK_CLAZZ = "org.wso2.carbon.policy.mgt.core.task.MonitoringTask"; - public static final String DM_CACHE_MANAGER = "DM_CACHE_MANAGER"; - public static final String DM_CACHE = "DM_CACHE"; + // public static final String DM_CACHE = "DM_CACHE"; public static final String DM_CACHE_LIST = "DM_CACHE_LIST"; - public static final String DELEGATION_TASK_TYPE = "DELEGATION__TASK"; public static final String DELEGATION_TASK_NAME = "DELEGATION"; public static final String DELEGATION_TASK_CLAZZ = "org.wso2.carbon.policy.mgt.core.enforcement.DelegationTask"; + /** + Caller would reference the constants using PolicyManagementConstants.DEVICE_CONFIG_XML_NAME, + and so on. Any caller should be prevented from constructing objects of + this class, thus declaring this private constructor. + */ + private PolicyManagementConstants() { + throw new AssertionError(); + } } diff --git a/components/policy-mgt/pom.xml b/components/policy-mgt/pom.xml index d15bb08504d..4d1c8edb691 100644 --- a/components/policy-mgt/pom.xml +++ b/components/policy-mgt/pom.xml @@ -28,7 +28,6 @@ 4.0.0 - org.wso2.carbon.devicemgt policy-mgt 1.1.0-SNAPSHOT pom @@ -43,7 +42,6 @@ org.wso2.carbon.complex.policy.decision.point - diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard.feature/pom.xml new file mode 100644 index 00000000000..1a04860745e --- /dev/null +++ b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.dashboard.feature/pom.xml @@ -0,0 +1,65 @@ + + + + org.wso2.carbon.devicemgt + device-mgt-feature + 1.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + org.wso2.carbon.device.mgt.analytics.dashboard.feature + 1.1.0-SNAPSHOT + pom + WSO2 Carbon - Device Management Dashboard Analytics Feature + WSO2 Carbon - Device Management Dashboard Analytics Feature + http://wso2.org + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics.dashboard + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.device.mgt.analytics.dashboard + ../../../features/etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + org.eclipse.equinox.p2.type.group:false + + + + + org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.analytics.dashboard:${carbon.device.mgt.version} + + + + org.wso2.carbon.core.server:${carbon.kernel.version} + + + + + + + + + + \ No newline at end of file diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql index 67cc4d9e0a4..24b9b322f53 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -484,3 +484,31 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_DETAIL ( ON DELETE NO ACTION ON UPDATE NO ACTION ); + +CREATE VIEW DEVICES_VIEW_1 AS +SELECT +DEVICE_INFO.DEVICE_ID, +DEVICE_INFO.PLATFORM, +DEVICE_INFO.OWNERSHIP, +DEVICE_INFO.CONNECTIVITY_STATUS, +IFNULL(DEVICE_WITH_POLICY_INFO.POLICY_ID, -1) AS POLICY_ID, +IFNULL(DEVICE_WITH_POLICY_INFO.IS_COMPLIANT, -1) AS IS_COMPLIANT, +DEVICE_INFO.TENANT_ID +FROM +(SELECT +DM_DEVICE.ID AS DEVICE_ID, +DM_DEVICE_TYPE.NAME AS PLATFORM, +DM_ENROLMENT.OWNERSHIP AS OWNERSHIP, +DM_ENROLMENT.STATUS AS CONNECTIVITY_STATUS, +DM_DEVICE.TENANT_ID AS TENANT_ID +FROM DM_DEVICE, DM_DEVICE_TYPE, DM_ENROLMENT +WHERE DM_DEVICE.DEVICE_TYPE_ID = DM_DEVICE_TYPE.ID AND DM_DEVICE.ID = DM_ENROLMENT.DEVICE_ID) DEVICE_INFO +LEFT JOIN +(SELECT +DEVICE_ID, +POLICY_ID, +STATUS AS IS_COMPLIANT +FROM +DM_POLICY_COMPLIANCE_STATUS) DEVICE_WITH_POLICY_INFO +ON DEVICE_INFO.DEVICE_ID = DEVICE_WITH_POLICY_INFO.DEVICE_ID +ORDER BY DEVICE_INFO.DEVICE_ID; diff --git a/features/device-mgt/pom.xml b/features/device-mgt/pom.xml index 18ec1fd164e..061dbdfdf61 100644 --- a/features/device-mgt/pom.xml +++ b/features/device-mgt/pom.xml @@ -39,6 +39,7 @@ org.wso2.carbon.device.mgt.feature org.wso2.carbon.device.mgt.extensions.feature org.wso2.carbon.device.mgt.analytics.data.publisher.feature + org.wso2.carbon.device.mgt.analytics.dashboard.feature \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8e16d112ac0..c71293b0494 100644 --- a/pom.xml +++ b/pom.xml @@ -269,6 +269,11 @@ org.wso2.carbon.device.mgt.analytics.data.publisher ${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics.dashboard + ${carbon.device.mgt.version} + org.wso2.carbon.devicemgt org.wso2.carbon.device.mgt.server.feature