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 0000000000..3272165588
--- /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 0000000000..b9a434721c
--- /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 0000000000..adfb4359f6
--- /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 0000000000..3ebf841f13
--- /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 0000000000..bb2d44ac63
--- /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 0000000000..7f0cede95b
--- /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 0000000000..193afc92da
--- /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 0000000000..ab91e9a81a
--- /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 096d236f4a..59f1b40523 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 13a2df3442..bcaac2b283 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 d15bb08504..4d1c8edb69 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 0000000000..1a04860745
--- /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 67cc4d9e0a..24b9b322f5 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 18ec1fd164..061dbdfdf6 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 8e16d112ac..c71293b049 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