diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/pom.xml
new file mode 100644
index 0000000000..3d7551fa0d
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/pom.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt
+ device-mgt
+ 1.1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.device.mgt.analytics
+ 1.1.0-SNAPSHOT
+ bundle
+ WSO2 Carbon - Device Analytics
+ WSO2 Carbon - Device Analytics
+ http://wso2.org
+
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi.services
+
+
+ org.testng
+ testng
+
+
+ org.wso2.tomcat
+ tomcat
+
+
+ org.wso2.tomcat
+ tomcat-servlet-api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.core
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.agent
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.commons
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+
+
+ org.wso2.carbon.registry
+ org.wso2.carbon.registry.indexing
+
+
+ org.json.wso2
+ json
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 1.4.0
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ ${carbon.device.mgt.version}
+ Data Publisher
+ org.wso2.carbon.device.mgt.analytics.internal
+
+ !org.wso2.carbon.device.mgt.analytics.internal,
+ org.wso2.carbon.device.mgt.analytics.*;version="${carbon.device.mgt.version}"
+
+
+ org.osgi.framework,
+ org.osgi.service.component,
+ org.apache.commons.logging.*,
+ org.wso2.carbon.context;version="${carbon.kernel.version.range}",
+ org.wso2.carbon.utils;version="${carbon.kernel.version.range}",
+ org.wso2.carbon.databridge.*;version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.analytics.*;version="${carbon.analytics.version.range}",
+ org.wso2.carbon.registry.core.*;resolution:=optional,
+ org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}",
+ org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}",
+ org.json;version="${commons-json.version}",
+ javax.xml.bind,
+ javax.xml.bind.annotation,
+ javax.xml.parsers,
+ org.w3c.dom
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/AnalyticsDataRecord.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/AnalyticsDataRecord.java
new file mode 100644
index 0000000000..d869aed1c3
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/AnalyticsDataRecord.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AnalyticsDataRecord {
+ private Map values;
+ private long timestamp;
+
+ public AnalyticsDataRecord() {
+ values = new HashMap<>();
+ }
+
+ public AnalyticsDataRecord(Map values) {
+ this.values = values;
+ }
+
+ public Map getValues() {
+ return this.values;
+ }
+
+ public void setValue(String name, Object value) {
+ values.put(name, value);
+ }
+
+ public Object getValue(String name) {
+ return this.values.get(name);
+ }
+
+ public void setValues(Map values) {
+ this.values = values;
+ }
+
+ public long getTimestamp() {
+ return this.timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceAnalyticsUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceAnalyticsUtil.java
new file mode 100644
index 0000000000..b50c57aa7f
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceAnalyticsUtil.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import org.w3c.dom.Document;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.File;
+
+public class DeviceAnalyticsUtil {
+
+ public static Document convertToDocument(File file) throws DataPublisherConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ try {
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ return docBuilder.parse(file);
+ } catch (Exception e) {
+ throw new DataPublisherConfigurationException("Error occurred while parsing file, while converting " +
+ "to a org.w3c.dom.Document", e);
+ }
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceDataPublisher.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceDataPublisher.java
new file mode 100644
index 0000000000..464a6a444a
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/DeviceDataPublisher.java
@@ -0,0 +1,222 @@
+/*
+ * 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;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.databridge.agent.DataPublisher;
+import org.wso2.carbon.databridge.agent.exception.DataEndpointAgentConfigurationException;
+import org.wso2.carbon.databridge.agent.exception.DataEndpointAuthenticationException;
+import org.wso2.carbon.databridge.agent.exception.DataEndpointConfigurationException;
+import org.wso2.carbon.databridge.agent.exception.DataEndpointException;
+import org.wso2.carbon.databridge.commons.exception.TransportException;
+import org.wso2.carbon.device.mgt.analytics.config.AnalyticsConfiguration;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherAlreadyExistsException;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+import org.wso2.carbon.device.mgt.analytics.internal.DeviceAnalyticsDataHolder;
+import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
+import org.wso2.carbon.registry.core.Registry;
+import org.wso2.carbon.registry.core.Resource;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This is used to manage data publisher per tenant.
+ */
+public class DeviceDataPublisher {
+
+ private static final Log log = LogFactory.getLog(DeviceDataPublisher.class);
+ private static final String TENANT_DAS_CONFIG_LOCATION = "/das/config.json";
+ private static final String USERNAME_CONFIG_TAG = "username";
+ private static final String PASSWORD_CONFIG_TAG = "password";
+ /**
+ * map to store data publishers for each tenant.
+ */
+ private static Map dataPublisherMap;
+ private static DeviceDataPublisher deviceDataPublisher;
+
+ public static DeviceDataPublisher getInstance() {
+ if (deviceDataPublisher == null) {
+ synchronized (DeviceDataPublisher.class) {
+ if (deviceDataPublisher == null) {
+ deviceDataPublisher = new DeviceDataPublisher();
+ }
+ }
+ }
+ return deviceDataPublisher;
+ }
+
+ private DeviceDataPublisher() {
+ dataPublisherMap = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * this return the data publisher for the tenant.
+ *
+ * @return
+ * @throws DataPublisherConfigurationException
+ *
+ */
+ public DataPublisher getDataPublisher() throws DataPublisherConfigurationException {
+ String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
+ //Get LoadBalancingDataPublisher which has been registered for the tenant.
+ DataPublisher dataPublisher = getDataPublisher(tenantDomain);
+ //If a LoadBalancingDataPublisher had not been registered for the tenant.
+ if (dataPublisher == null) {
+ AnalyticsConfiguration analyticsConfig = AnalyticsConfiguration.getInstance();
+ if (!analyticsConfig.isEnable()) {
+ return null;
+ }
+ String analyticsServerUrlGroups = analyticsConfig.getReceiverServerUrl();
+ String analyticsServerUsername = analyticsConfig.getAdminUsername();
+ String analyticsServerPassword = analyticsConfig.getAdminPassword();
+ if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ String userInfo[] = getAnalyticsServerUserInfo(tenantId);
+ if (userInfo != null) {
+ analyticsServerUsername = userInfo[0];
+ analyticsServerPassword = userInfo[1];
+ }
+ }
+ //Create new DataPublisher for the tenant.
+ try {
+ dataPublisher = new DataPublisher(analyticsServerUrlGroups, analyticsServerUsername,
+ analyticsServerPassword);
+ //Add created DataPublisher.
+ addDataPublisher(tenantDomain, dataPublisher);
+ } catch (DataEndpointAgentConfigurationException e) {
+ throw new DataPublisherConfigurationException("Configuration Exception on data publisher for " +
+ "ReceiverGroup = " + analyticsServerUrlGroups + " for username " + analyticsServerUsername, e);
+ } catch (DataEndpointException e) {
+ throw new DataPublisherConfigurationException("Invalid ReceiverGroup = " + analyticsServerUrlGroups, e);
+ } catch (DataEndpointConfigurationException e) {
+ throw new DataPublisherConfigurationException("Invalid Data endpoint configuration.", e);
+ } catch (DataEndpointAuthenticationException e) {
+ throw new DataPublisherConfigurationException("Authentication Failed for user " +
+ analyticsServerUsername, e);
+ } catch (TransportException e) {
+ throw new DataPublisherConfigurationException("Error occurred while retrieving data publisher", e);
+ } catch (DataPublisherAlreadyExistsException e) {
+ log.warn("Attempting to register a data publisher for the tenant " + tenantDomain +
+ " when one already exists. Returning existing data publisher");
+ return getDataPublisher(tenantDomain);
+ }
+ }
+ return dataPublisher;
+ }
+
+ /**
+ * Fetch the data publisher which has been registered under the tenant domain.
+ *
+ * @param tenantDomain - The tenant domain under which the data publisher is registered
+ * @return - Instance of the DataPublisher which was registered. Null if not registered.
+ */
+ private DataPublisher getDataPublisher(String tenantDomain) {
+ if (dataPublisherMap.containsKey(tenantDomain)) {
+ return dataPublisherMap.get(tenantDomain);
+ }
+ return null;
+ }
+
+ /**
+ * Adds a LoadBalancingDataPublisher to the data publisher map.
+ *
+ * @param tenantDomain - The tenant domain under which the data publisher will be registered.
+ * @param dataPublisher - Instance of the LoadBalancingDataPublisher
+ * @throws DataPublisherAlreadyExistsException
+ * -
+ * If a data publisher has already been registered under the tenant
+ * domain
+ */
+ private void addDataPublisher(String tenantDomain, DataPublisher dataPublisher)
+ throws DataPublisherAlreadyExistsException {
+ if (dataPublisherMap.containsKey(tenantDomain)) {
+ throw new DataPublisherAlreadyExistsException(
+ "A DataPublisher has already been created for the tenant " + tenantDomain);
+ }
+
+ dataPublisherMap.put(tenantDomain, dataPublisher);
+ }
+
+ /**
+ * retrieve the credential from registry
+ */
+ private String[] getAnalyticsServerUserInfo(int tenantId) throws DataPublisherConfigurationException {
+ try {
+ String config = getConfigRegistryResourceContent(tenantId, TENANT_DAS_CONFIG_LOCATION);
+ JSONObject jsonConfigforDas = new JSONObject(config);
+ String credential[] = new String[2];
+ credential[0] = jsonConfigforDas.getString(USERNAME_CONFIG_TAG);
+ credential[1] = jsonConfigforDas.getString(PASSWORD_CONFIG_TAG);
+ return credential;
+ } catch (RegistryException e) {
+ throw new DataPublisherConfigurationException("Failed to load the registry for tenant " + tenantId, e);
+ } catch (JSONException e) {
+ throw new DataPublisherConfigurationException(
+ "Failed to parse the credential from the registry for tenant " + tenantId, e);
+ }
+ }
+
+ /**
+ * get the credential detail from the registry for tenants.
+ *
+ * @param tenantId for identify tenant space.
+ * @param registryLocation retrieve the config file from tenant space.
+ * @return the config for tenant
+ * @throws RegistryException
+ */
+ private String getConfigRegistryResourceContent(int tenantId, final String registryLocation)
+ throws RegistryException {
+ String content = null;
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
+ RegistryService registryService = DeviceAnalyticsDataHolder.getInstance().getRegistryService();
+ if (registryService != null) {
+ Registry registry = registryService.getConfigSystemRegistry(tenantId);
+ this.loadTenantRegistry(tenantId);
+ if (registry.resourceExists(registryLocation)) {
+ Resource resource = registry.get(registryLocation);
+ content = new String((byte[]) resource.getContent(), Charset.defaultCharset());
+ }
+ }
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+
+ return content;
+ }
+
+ private void loadTenantRegistry(int tenantId) throws RegistryException {
+ TenantRegistryLoader tenantRegistryLoader = DeviceAnalyticsDataHolder.getInstance().getTenantRegistryLoader();
+ DeviceAnalyticsDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId);
+ tenantRegistryLoader.loadTenantRegistry(tenantId);
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/AnalyticsConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/AnalyticsConfiguration.java
new file mode 100644
index 0000000000..28146dd6f5
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/AnalyticsConfiguration.java
@@ -0,0 +1,119 @@
+/*
+ * 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.config;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.wso2.carbon.device.mgt.analytics.DeviceAnalyticsUtil;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+
+/**
+ * Configurations related to DAS data publisher and DAL.
+ */
+@XmlRootElement(name = "AnalyticsConfiguration")
+public class AnalyticsConfiguration {
+
+ private String receiverServerUrl;
+ private String adminUsername;
+ private String adminPassword;
+ private boolean enable;
+
+ private static AnalyticsConfiguration config;
+
+ private static final Log log = LogFactory.getLog(AnalyticsConfiguration.class);
+ private static final String DEVICE_ANALYTICS_CONFIG_PATH =
+ CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "device-analytics-config.xml";
+
+ private AnalyticsConfiguration() {
+ }
+
+ public static AnalyticsConfiguration getInstance() {
+ if (config == null) {
+ throw new InvalidConfigurationStateException("Device analytics configuration is not " +
+ "initialized properly");
+ }
+ return config;
+ }
+
+
+ @XmlElement(name = "AdminUsername", required = true)
+ public String getAdminUsername() {
+ return adminUsername;
+ }
+
+ public void setAdminUsername(String adminUsername) {
+ this.adminUsername = adminUsername;
+ }
+
+ @XmlElement(name = "AdminPassword", required = true)
+ public String getAdminPassword() {
+ return adminPassword;
+ }
+
+ public void setAdminPassword(String adminPassword) {
+ this.adminPassword = adminPassword;
+ }
+
+ @XmlElement(name = "ReceiverServerUrl", required = true)
+ public String getReceiverServerUrl() {
+ return receiverServerUrl;
+ }
+
+ public void setReceiverServerUrl(String receiverServerUrl) {
+ this.receiverServerUrl = receiverServerUrl;
+ }
+
+ @XmlElement(name = "Enabled", required = true)
+ public boolean isEnable() {
+ return enable;
+ }
+
+ public void setEnable(boolean status) {
+ this.enable = status;
+ }
+
+ public static void init() throws DataPublisherConfigurationException {
+ try {
+ File authConfig = new File(AnalyticsConfiguration.DEVICE_ANALYTICS_CONFIG_PATH);
+ Document doc = DeviceAnalyticsUtil.convertToDocument(authConfig);
+
+ /* Un-marshaling device analytics configuration */
+ JAXBContext ctx = JAXBContext.newInstance(AnalyticsConfiguration.class);
+ Unmarshaller unmarshaller = ctx.createUnmarshaller();
+ config = (AnalyticsConfiguration) unmarshaller.unmarshal(doc);
+ } catch (JAXBException e) {
+ throw new DataPublisherConfigurationException("Error occurred while un-marshalling device analytics " +
+ "Config", e);
+ }
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/InvalidConfigurationStateException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/InvalidConfigurationStateException.java
new file mode 100644
index 0000000000..b471c9e82a
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/config/InvalidConfigurationStateException.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.config;
+
+public class InvalidConfigurationStateException extends RuntimeException {
+
+ private static final long serialVersionUID = -3151274311329070297L;
+
+ public InvalidConfigurationStateException(String message) {
+ super(message);
+ }
+
+ public InvalidConfigurationStateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidConfigurationStateException(String msg, Exception nestedEx) {
+ super(msg, nestedEx);
+ }
+
+ public InvalidConfigurationStateException() {
+ super();
+ }
+
+ public InvalidConfigurationStateException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherAlreadyExistsException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherAlreadyExistsException.java
new file mode 100644
index 0000000000..b174b407f2
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherAlreadyExistsException.java
@@ -0,0 +1,44 @@
+/*
+ * 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.exception;
+
+public class DataPublisherAlreadyExistsException extends Exception {
+ public DataPublisherAlreadyExistsException() {
+ super();
+ }
+
+ public DataPublisherAlreadyExistsException(String message) {
+ super(message);
+ }
+
+ public DataPublisherAlreadyExistsException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DataPublisherAlreadyExistsException(Throwable cause) {
+ super(cause);
+ }
+
+ protected DataPublisherAlreadyExistsException(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherConfigurationException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherConfigurationException.java
new file mode 100644
index 0000000000..8bf57137ed
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DataPublisherConfigurationException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.exception;
+
+public class DataPublisherConfigurationException extends Exception {
+ public DataPublisherConfigurationException() {
+ super();
+ }
+
+ public DataPublisherConfigurationException(String message) {
+ super(message);
+ }
+
+ public DataPublisherConfigurationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DataPublisherConfigurationException(Throwable cause) {
+ super(cause);
+ }
+
+ protected DataPublisherConfigurationException(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DeviceManagementAnalyticsException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DeviceManagementAnalyticsException.java
new file mode 100644
index 0000000000..602d8da587
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/exception/DeviceManagementAnalyticsException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.exception;
+
+public class DeviceManagementAnalyticsException extends Exception {
+ public DeviceManagementAnalyticsException() {
+ super();
+ }
+
+ public DeviceManagementAnalyticsException(String message) {
+ super(message);
+ }
+
+ public DeviceManagementAnalyticsException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DeviceManagementAnalyticsException(Throwable cause) {
+ super(cause);
+ }
+
+ protected DeviceManagementAnalyticsException(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsDataHolder.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsDataHolder.java
new file mode 100644
index 0000000000..0f2c01d40d
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsDataHolder.java
@@ -0,0 +1,75 @@
+/*
+ * 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.internal;
+
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
+
+public class DeviceAnalyticsDataHolder {
+ private static DeviceAnalyticsDataHolder thisInstance = new DeviceAnalyticsDataHolder();
+ /**
+ * AnalyticsDataAPI is service used to retrieve data from DAS.
+ */
+ private AnalyticsDataAPI analyticsDataAPI;
+ private TenantRegistryLoader tenantRegistryLoader;
+ private TenantIndexingLoader indexLoader;
+ private RegistryService registryService;
+ private DeviceAnalyticsDataHolder() {
+ }
+
+
+ public static DeviceAnalyticsDataHolder getInstance() {
+ return thisInstance;
+ }
+
+ public AnalyticsDataAPI getAnalyticsDataAPI() {
+ return analyticsDataAPI;
+ }
+
+ public void setAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) {
+ this.analyticsDataAPI = analyticsDataAPI;
+ }
+
+ public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader){
+ this.tenantRegistryLoader = tenantRegistryLoader;
+ }
+
+ public TenantRegistryLoader getTenantRegistryLoader(){
+ return tenantRegistryLoader;
+ }
+
+ public void setIndexLoaderService(TenantIndexingLoader indexLoader) {
+ this.indexLoader = indexLoader;
+ }
+
+ public TenantIndexingLoader getIndexLoaderService(){
+ return indexLoader;
+ }
+
+ public RegistryService getRegistryService() {
+ return registryService;
+ }
+
+ public void setRegistryService(RegistryService registryService) {
+ this.registryService = registryService;
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsServiceComponent.java
new file mode 100644
index 0000000000..51d45c78dc
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/internal/DeviceAnalyticsServiceComponent.java
@@ -0,0 +1,151 @@
+/*
+ * 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.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.device.mgt.analytics.config.AnalyticsConfiguration;
+import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsServiceImpl;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
+
+/**
+ * @scr.component name="org.wso2.carbon.device.mgt.analytics.internal.DeviceAnalyticsServiceComponent"
+ * immediate="true"
+ * @scr.reference name="device.analytics.api"
+ * interface="org.wso2.carbon.analytics.api.AnalyticsDataAPI"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setAnalyticsDataAPI"
+ * unbind="unsetAnalyticsDataAPI"
+ * @scr.reference name="registry.service"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setRegistryService"
+ * unbind="unsetRegistryService"
+ * @scr.reference name="tenant.registryloader"
+ * interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader"
+ * cardinality="1..1" policy="dynamic"
+ * bind="setTenantRegistryLoader"
+ * unbind="unsetTenantRegistryLoader"
+ * @scr.reference name="tenant.indexloader"
+ * interface="org.wso2.carbon.registry.indexing.service.TenantIndexingLoader"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setIndexLoader"
+ * unbind="unsetIndexLoader"
+ */
+public class DeviceAnalyticsServiceComponent {
+
+ private ServiceRegistration analyticsServiceRef;
+ private static Log log = LogFactory.getLog(DeviceAnalyticsServiceComponent.class);
+
+ protected void activate(ComponentContext componentCtx) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing device analytics bundle");
+ }
+ AnalyticsConfiguration.init();
+
+ BundleContext bundleCtx = componentCtx.getBundleContext();
+ this.analyticsServiceRef =
+ bundleCtx.registerService(DeviceAnalyticsService.class, new DeviceAnalyticsServiceImpl(), null);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Device management analytics bundle has been successfully initialized");
+ }
+ } catch (Throwable e) {
+ log.error("Error occurred while initializing device analytics bundle", e);
+ }
+ }
+
+ protected void deactivate(ComponentContext componentCtx) {
+ if (log.isDebugEnabled()) {
+ log.debug("Deactivating device analytics bundle");
+ }
+ if (analyticsServiceRef != null) {
+ analyticsServiceRef.unregister();
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Device analytics bundle has been successfully deactivated");
+ }
+ }
+
+ /**
+ * Sets AnalyticsDataAPI Service.
+ *
+ * @param analyticsDataAPI An instance of AnalyticsDataAPI
+ */
+ protected void setAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting AnalyticsDataAPI Service");
+ }
+ DeviceAnalyticsDataHolder.getInstance().setAnalyticsDataAPI(analyticsDataAPI);
+ }
+
+ /**
+ * Un sets AnalyticsDataAPI Service.
+ *
+ * @param analyticsDataAPI An instance of AnalyticsDataAPI
+ */
+ protected void unsetAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) {
+ if (log.isDebugEnabled()) {
+ log.debug("Un-Setting AnalyticsDataAPI Service");
+ }
+ DeviceAnalyticsDataHolder.getInstance().setAnalyticsDataAPI(null);
+ }
+
+ protected void setRegistryService(RegistryService registryService) {
+ if (registryService != null && log.isDebugEnabled()) {
+ log.debug("Registry service initialized");
+ }
+ DeviceAnalyticsDataHolder.getInstance().setRegistryService(registryService);
+ }
+
+ protected void unsetRegistryService(RegistryService registryService) {
+ DeviceAnalyticsDataHolder.getInstance().setRegistryService(null);
+ }
+
+ protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
+ DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader);
+ }
+
+ protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
+ DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(null);
+ }
+
+ protected void setIndexLoader(TenantIndexingLoader indexLoader) {
+ if (indexLoader != null && log.isDebugEnabled()) {
+ log.debug("IndexLoader service initialized");
+ }
+ DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(indexLoader);
+ }
+
+ protected void unsetIndexLoader(TenantIndexingLoader indexLoader) {
+ DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(null);
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsService.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsService.java
new file mode 100644
index 0000000000..25359cb4b2
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.service;
+
+import org.wso2.carbon.device.mgt.analytics.AnalyticsDataRecord;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+import org.wso2.carbon.device.mgt.analytics.exception.DeviceManagementAnalyticsException;
+import java.util.List;
+
+/**
+ * This service can be used to publish and retreive data from the Analytics Server.
+ */
+public interface DeviceAnalyticsService {
+
+ /**
+ * This is used to publish an event to DAS.
+ * @param streamName is the name of the stream that the data needs to pushed
+ * @param version is the version of the stream
+ * @param metaDataArray - meta data that needs to pushed
+ * @param correlationDataArray - correlation data that needs to be pushed
+ * @param payloadDataArray - payload data that needs to be pushed
+ * @return
+ * @throws DataPublisherConfigurationException
+ */
+ boolean publishEvent(String streamName, String version, Object[] metaDataArray, Object[] correlationDataArray,
+ Object[] payloadDataArray) throws DataPublisherConfigurationException;
+
+ /**
+ * This service can be used to retrieve all the event for the query.
+ * @param tableName is the name of the table that events need to be retrieved
+ * @param query is query to be executed.
+ * @return the record list
+ * @throws DeviceManagementAnalyticsException
+ */
+ List getAllEventsForDevice(String tableName, String query) throws DeviceManagementAnalyticsException;
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsServiceImpl.java
new file mode 100644
index 0000000000..26cf6ee74a
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics/src/main/java/org/wso2/carbon/device/mgt/analytics/service/DeviceAnalyticsServiceImpl.java
@@ -0,0 +1,121 @@
+/*
+ * 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.service;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
+import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
+import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
+import org.wso2.carbon.analytics.datasource.commons.Record;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.databridge.agent.DataPublisher;
+import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils;
+import org.wso2.carbon.device.mgt.analytics.AnalyticsDataRecord;
+import org.wso2.carbon.device.mgt.analytics.DeviceDataPublisher;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+import org.wso2.carbon.device.mgt.analytics.exception.DeviceManagementAnalyticsException;
+import org.wso2.carbon.device.mgt.analytics.internal.DeviceAnalyticsDataHolder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the implementation of Osgi Service which can be used to publish and retireved
+ * event/records.
+ */
+public class DeviceAnalyticsServiceImpl implements DeviceAnalyticsService {
+ private static Log log = LogFactory.getLog(DeviceAnalyticsServiceImpl.class);
+
+ /**
+ * @param streamName is the name of the stream that the data needs to pushed
+ * @param version is the version of the stream
+ * @param metaDataArray - meta data that needs to pushed
+ * @param correlationDataArray - correlation data that needs to be pushed
+ * @param payloadDataArray - payload data that needs to be pushed
+ * @return
+ * @throws DataPublisherConfigurationException
+ */
+ @Override
+ public boolean publishEvent(String streamName, String version, Object[] metaDataArray,
+ Object[] correlationDataArray,
+ Object[] payloadDataArray) throws DataPublisherConfigurationException {
+ DataPublisher dataPublisher = DeviceDataPublisher.getInstance().getDataPublisher();
+ if (dataPublisher != null) {
+ String streamId = DataBridgeCommonsUtils.generateStreamId(streamName, version);
+ return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray, correlationDataArray,
+ payloadDataArray);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param tableName is the name of the table that events need to be retrieved
+ * @param query is query to be executed.
+ * @return
+ * @throws AnalyticsException
+ */
+ @Override
+ public List getAllEventsForDevice(String tableName, String query) throws
+ DeviceManagementAnalyticsException {
+ try {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ AnalyticsDataAPI analyticsDataAPI = DeviceAnalyticsDataHolder.getInstance().getAnalyticsDataAPI();
+ int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
+ if (eventCount == 0) {
+ return new ArrayList<>();
+ }
+ AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest();
+ drillDownRequest.setQuery(query);
+ drillDownRequest.setTableName(tableName);
+ drillDownRequest.setRecordCount(eventCount);
+ List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
+ List recordIds = getRecordIds(resultEntries);
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
+ List records = AnalyticsDataServiceUtils.listRecords(analyticsDataAPI, response);
+ return getAnalyticsDataRecords(records);
+ } catch (AnalyticsException e) {
+ throw new DeviceManagementAnalyticsException(
+ "Failed fetch data for table " + tableName + "with the query " + query);
+ }
+ }
+
+ private List getRecordIds(List searchResults) {
+ List ids = new ArrayList<>();
+ for (SearchResultEntry searchResult : searchResults) {
+ ids.add(searchResult.getId());
+ }
+ return ids;
+ }
+
+ private List getAnalyticsDataRecords(List records) {
+ List analyticsDataRecords = new ArrayList<>();
+ for (Record record : records) {
+ AnalyticsDataRecord analyticsDataRecord = new AnalyticsDataRecord(record.getValues());
+ analyticsDataRecords.add(analyticsDataRecord);
+ }
+ return analyticsDataRecords;
+ }
+
+}
\ No newline at end of file
diff --git a/components/device-mgt/pom.xml b/components/device-mgt/pom.xml
index 69693628cc..8a9e12116f 100644
--- a/components/device-mgt/pom.xml
+++ b/components/device-mgt/pom.xml
@@ -40,6 +40,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
@@ -61,4 +62,5 @@
+
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/pom.xml
new file mode 100644
index 0000000000..25a175c40e
--- /dev/null
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/pom.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt
+ device-mgt-feature
+ 1.1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.device.mgt.analytics.feature
+ pom
+ 1.1.0-SNAPSHOT
+ WSO2 Carbon - Device Management Server Feature
+ http://wso2.org
+ This feature contains bundles related to device analytics data publisher
+
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.analytics
+
+
+
+
+
+
+ maven-resources-plugin
+ 2.6
+
+
+ copy-resources
+ generate-resources
+
+ copy-resources
+
+
+ src/main/resources
+
+
+ resources
+
+ build.properties
+ p2.inf
+
+
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.device.mgt.analytics
+ ../../../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:${carbon.device.mgt.version}
+
+
+
+ org.wso2.carbon.core.server:${carbon.kernel.version}
+
+
+
+
+
+
+
+
+
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/build.properties b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/build.properties
new file mode 100644
index 0000000000..9c86577d76
--- /dev/null
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/build.properties
@@ -0,0 +1 @@
+custom = true
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/conf/device-analytics-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/conf/device-analytics-config.xml
new file mode 100644
index 0000000000..5baa363c69
--- /dev/null
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/conf/device-analytics-config.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ true
+ tcp://localhost:7611
+ admin
+ admin
+
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/p2.inf b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/p2.inf
new file mode 100644
index 0000000000..417de1a4cc
--- /dev/null
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.analytics.feature/src/main/resources/p2.inf
@@ -0,0 +1,2 @@
+instructions.configure = \
+org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/conf/device-analytics-config.xml,target:${installFolder}/../../conf/etc/device-analytics-config.xml,overwrite:true);\
\ No newline at end of file
diff --git a/features/device-mgt/pom.xml b/features/device-mgt/pom.xml
index 6cfce70787..485f2bfca0 100644
--- a/features/device-mgt/pom.xml
+++ b/features/device-mgt/pom.xml
@@ -37,6 +37,7 @@
org.wso2.carbon.device.mgt.server.feature
org.wso2.carbon.device.mgt.extensions.feature
+ org.wso2.carbon.device.mgt.analytics.feature
diff --git a/features/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration.server.feature/pom.xml b/features/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration.server.feature/pom.xml
index b2f2b73159..f2adbd5fcc 100644
--- a/features/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration.server.feature/pom.xml
+++ b/features/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration.server.feature/pom.xml
@@ -141,7 +141,7 @@
com.googlecode.json-simple.wso2:json-simple:${json-simple.version}
- org.json.wso2:json:${json.wso2.version}
+ org.json.wso2:json:${commons-json.version}
diff --git a/pom.xml b/pom.xml
index d9521c88a0..80cb822ac6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -258,6 +258,12 @@
org.wso2.carbon.email.sender.core
${carbon.device.mgt.version}
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.analytics
+ ${carbon.device.mgt.version}
+
+
@@ -1240,7 +1246,7 @@
org.json.wso2
json
- ${json.wso2.version}
+ ${commons-json.version}
com.google.code.gson
@@ -1295,7 +1301,6 @@
${commons-collections.version}
-
mysql
@@ -1304,6 +1309,47 @@
test
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.core
+ ${carbon.analytics.common.version}
+
+
+ org.wso2.carbon.commons
+ org.wso2.carbon.databridge.commons
+ ${carbon.commons.version}
+
+
+ org.wso2.carbon.commons
+ org.wso2.carbon.databridge.commons.thrift
+ ${carbon.commons.version}
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.commons
+ ${carbon.analytics.common.version}
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.agent
+ ${carbon.analytics.common.version}
+
+
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ ${carbon.analytics.version}
+
+
+
+
+ org.wso2.carbon.registry
+ org.wso2.carbon.registry.indexing
+ ${carbon.registry.version}
+
+
@@ -1508,6 +1554,7 @@
6.1.1
4.4.3
+ [4.4.0, 4.5.0)
1.5.4
1.3
@@ -1576,6 +1623,18 @@
4.3.0
+
+ 5.0.11-SNAPSHOT
+ [5.0.11,6.0.0)
+
+
+ 1.0.6-SNAPSHOT
+ [1.0.6,2.0.0]
+
+
+ 4.4.8
+ [4.4.8, 5.0.0)
+
2.7.16
2.5.11
@@ -1595,7 +1654,7 @@
2.26.1.wso2v3
- 2.0.0.wso2v1
+ 2.0.0.wso2v1
2.3.1
1.1.1
1.2