Merge pull request #803 from ayyoob/devicetype-3.1.0

Adding Device type API Implementation
revert-70aa11f8
Geeth 8 years ago committed by GitHub
commit 63c8e87d98

@ -42,6 +42,7 @@ public class APIUtil {
private static Log log = LogFactory.getLog(APIUtil.class);
private static final String DEFAULT_CDMF_API_TAG = "device_management";
private static final String DEFAULT_AGENT_API_TAG = "device_agent";
private static final String DEFAULT_CERT_API_TAG = "scep_management";
public static final String PERMISSION_PROPERTY_NAME = "name";
@ -106,6 +107,7 @@ public class APIUtil {
List<String> allowedApisTags = getDeviceManagementProviderService().getAvailableDeviceTypes();
allowedApisTags.add(DEFAULT_CDMF_API_TAG);
allowedApisTags.add(DEFAULT_CERT_API_TAG);
allowedApisTags.add(DEFAULT_AGENT_API_TAG);
return allowedApisTags;
}

@ -112,7 +112,7 @@
org.w3c.dom,
org.wso2.carbon.context,
org.wso2.carbon.device.mgt.common.*,
org.wso2.carbon.device.mgt.extensions.*,
org.wso2.carbon.device.mgt.extensions.device.type.template.*,
org.wso2.carbon.registry.api,
org.wso2.carbon.registry.core,
org.wso2.carbon.registry.core.*,

@ -29,12 +29,12 @@ import org.osgi.framework.ServiceRegistration;
import org.w3c.dom.Document;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.exception.DeviceTypeConfigurationException;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.internal.DeviceTypeManagementDataHolder;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.DeviceTypeConfigIdentifier;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.DeviceTypeManagerService;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.util.DeviceTypeConfigUtil;
import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeConfigIdentifier;
import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeManagerService;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.exception.DeviceTypeConfigurationException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

@ -1,123 +0,0 @@
/*
* 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.extensions.device.type.deployer;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.AbstractDeployer;
import org.apache.axis2.deployment.DeploymentException;
import org.apache.axis2.deployment.repository.util.DeploymentFileData;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* This is the device deployer that will read and deploy the device type ui files from
* "deployment/server/devicetypes-ui"
* directory.
*/
public class DeviceTypeUIDeployer extends AbstractDeployer {
private static Log log = LogFactory.getLog(DeviceTypeUIDeployer.class);
protected Map<String, String> deviceTypeDeployedUIMap = new ConcurrentHashMap<String, String>();
private static final String DEVICEMGT_JAGGERY_APP_PATH = CarbonUtils.getCarbonRepository() + File.separator
+ "jaggeryapps" + File.separator + "devicemgt" + File.separator + "app" + File.separator + "units"
+ File.separator;
private static final String UNIT_PREFIX = "cdmf.unit.device.type";
@Override
public void init(ConfigurationContext configurationContext) {
}
@Override
public void setDirectory(String s) {
}
@Override
public void setExtension(String s) {
}
@Override
public void deploy(DeploymentFileData deploymentFileData) throws DeploymentException {
if (!deploymentFileData.getFile().isDirectory()) {
return;
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
if (tenantDomain != null && !tenantDomain.isEmpty()) {
File jaggeryAppPath = new File(
DEVICEMGT_JAGGERY_APP_PATH + tenantDomain + "." + deploymentFileData.getName());
try {
if (!jaggeryAppPath.exists()) {
FileUtils.forceMkdir(jaggeryAppPath);
FileUtils.copyDirectory(deploymentFileData.getFile(), jaggeryAppPath);
File[] listOfFiles = jaggeryAppPath.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
String content = FileUtils.readFileToString(listOfFiles[i]);
FileUtils.writeStringToFile(listOfFiles[i], content.replaceAll(UNIT_PREFIX
, tenantDomain + "." + UNIT_PREFIX));
}
}
} else {
log.debug("units already exists " + deploymentFileData.getName());
}
this.deviceTypeDeployedUIMap.put(deploymentFileData.getAbsolutePath(),
jaggeryAppPath.getAbsolutePath());
} catch (IOException e) {
if (jaggeryAppPath.exists()) {
try {
FileUtils.deleteDirectory(jaggeryAppPath);
} catch (IOException e1) {
log.error("Failed to delete directory " + jaggeryAppPath.getAbsolutePath());
}
}
log.error("Cannot deploy deviceType ui : " + deploymentFileData.getName(), e);
throw new DeploymentException(
"Device type ui file " + deploymentFileData.getName() + " is not deployed ", e);
}
} else {
log.error("Cannot deploy deviceType ui: " + deploymentFileData.getName());
}
}
@Override
public void undeploy(String filePath) throws DeploymentException {
try {
String jaggeryUnitPath = this.deviceTypeDeployedUIMap.remove(filePath);
FileUtils.deleteDirectory(new File(jaggeryUnitPath));
log.info("Device Type units un deployed successfully.");
} catch (IOException e) {
throw new DeploymentException("Failed to remove the units: " + filePath);
}
}
}

@ -1,198 +0,0 @@
/*
* 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.extensions.device.type.deployer.config;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the org.wso2.carbon package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {
private final static QName _DeviceTypeConfiguration_QNAME = new QName("", "DeviceTypeConfiguration");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.wso2.carbon
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link DeviceTypeConfiguration }
*
*/
public DeviceTypeConfiguration createDeviceTypeConfiguration() {
return new DeviceTypeConfiguration();
}
/**
* Create an instance of {@link Operation }
*
*/
public Operation createOperation() {
return new Operation();
}
/**
* Create an instance of {@link Attributes }
*
*/
public Attributes createAttributes() {
return new Attributes();
}
/**
* Create an instance of {@link ProvisioningConfig }
*
*/
public ProvisioningConfig createProvisioningConfig() {
return new ProvisioningConfig();
}
/**
* Create an instance of {@link TableConfig }
*
*/
public TableConfig createTableConfig() {
return new TableConfig();
}
/**
* Create an instance of {@link Table }
*
*/
public Table createTable() {
return new Table();
}
/**
* Create an instance of {@link Property }
*
*/
public Property createProperty() {
return new Property();
}
/**
* Create an instance of {@link JndiConfig }
*
*/
public JndiConfig createJndiConfig() {
return new JndiConfig();
}
/**
* Create an instance of {@link FormParameters }
*
*/
public FormParameters createFormParameters() {
return new FormParameters();
}
/**
* Create an instance of {@link Features }
*
*/
public Features createFeatures() {
return new Features();
}
/**
* Create an instance of {@link Feature }
*
*/
public Feature createFeature() {
return new Feature();
}
/**
* Create an instance of {@link PushNotificationProvider }
*
*/
public PushNotificationProvider createPushNotificationProvider() {
return new PushNotificationProvider();
}
/**
* Create an instance of {@link DataSource }
*
*/
public DataSource createDataSource() {
return new DataSource();
}
/**
* Create an instance of {@link ConfigProperties }
*
*/
public ConfigProperties createConfigProperties() {
return new ConfigProperties();
}
/**
* Create an instance of {@link License }
*
*/
public License createLicense() {
return new License();
}
/**
* Create an instance of {@link DeviceDetails }
*
*/
public DeviceDetails createDeviceDetails() {
return new DeviceDetails();
}
/**
* Create an instance of {@link QueryParameters }
*
*/
public QueryParameters createQueryParameters() {
return new QueryParameters();
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link DeviceTypeConfiguration }{@code >}}
*
*/
@XmlElementDecl(namespace = "", name = "DeviceTypeConfiguration")
public JAXBElement<DeviceTypeConfiguration> createDeviceTypeConfiguration(DeviceTypeConfiguration value) {
return new JAXBElement<DeviceTypeConfiguration>(_DeviceTypeConfiguration_QNAME, DeviceTypeConfiguration.class, null, value);
}
}

@ -28,7 +28,7 @@ import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.utils.ConfigurationContextService;
/**
* @scr.component name="org.wso2.carbon.device.mgt.iot.internal.DeviceTypeManagementServiceComponent"
* @scr.component name="org.wso2.carbon.device.mgt.iot.internal.DeviceTypeExtensionServiceComponent"
* immediate="true"
* @scr.reference name="config.context.service"
* interface="org.wso2.carbon.utils.ConfigurationContextService"

@ -19,7 +19,7 @@
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.util;
import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.exception.DeviceTypeConfigurationException;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.exception.DeviceTypeConfigurationException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;

@ -22,9 +22,6 @@ package org.wso2.carbon.device.mgt.extensions.device.type.deployer.util;
* This holds the constants used for this bundle.
*/
public class DeviceTypePluginConstants {
public static final String MEDIA_TYPE_XML = "application/xml";
public static final String CHARSET_UTF8 = "UTF8";
public static final String LANGUAGE_CODE_ENGLISH_US = "en_US";
public static final String CDMF_UI_TYPE = "devicetype/ui";
public static final String CDMF_UI_TYPE_DIR = "devicetypes-ui";

@ -1,152 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<DeviceTypeConfiguration name="samples">
<DeviceDetails table-id="SAMPLE_DEVICE_1"/>
<Features>
<Feature code="abc">
<Name>abc</Name>
<Description>this is a feature</Description>
<Operation context="/bulb/{state}" method="PUT" type="application/json">
<QueryParameters>
<Parameter>deviceId</Parameter>
</QueryParameters>
<FormParameters>
<Parameter>test</Parameter>
</FormParameters>
</Operation>
</Feature>
</Features>
<Claimable enabled="true"/>
<Sensors table-id="SAMPLE_DEVICE_2">
<Sensor code="CPU_Temperature">
<Name>temperature sensor fitted</Name>
<StreamDefinition>org.wso2.temperature.stream</StreamDefinition>
<Description>this is a sensor</Description>
<SensorStaticProperties>
<Property name="unit">celcius</Property>
<Property name="model_number">atmeggga11234</Property>
</SensorStaticProperties>
</Sensor>
<Sensor code="DHT11_Temperature">
<Name>temperature sensor fitted</Name>
<StreamDefinition>org.wso2.temperature.stream</StreamDefinition>
<Description>this is a sensor</Description>
<SensorStaticProperties>
<Property name="unit">celcius</Property>
</SensorStaticProperties>
<SensorDynamicProperties>
<Property name="model_number"/>
</SensorDynamicProperties>
</Sensor>
</Sensors>
<ProvisioningConfig>
<SharedWithAllTenants>false</SharedWithAllTenants>
</ProvisioningConfig>
<DeviceAuthorizationConfig>
<authorizationRequired>true</authorizationRequired>
</DeviceAuthorizationConfig>
<PushNotificationProvider type="MQTT">
<FileBasedProperties>true</FileBasedProperties>
<!--if file based properties is set to false then the configuration will be picked from platform configuration-->
<ConfigProperties>
<Property Name="mqttAdapterName">sample.mqtt.adapter</Property>
<Property Name="url">tcp://localhost:1883</Property>
<Property Name="username">admin</Property>
<Property Name="password">admin</Property>
<Property Name="qos">0</Property>
<Property Name="scopes"/>
<Property Name="clearSession">true</Property>
</ConfigProperties>
</PushNotificationProvider>
<PolicyMonitoring enabled="true"/>
<License>
<Language>en_US</Language>
<Version>1.0.0</Version>
<Text>This is license text</Text>
</License>
<TaskConfiguration>
<Enable>true</Enable>
<Frequency>600000</Frequency>
<Operations>
<Operation>
<Name>DEVICE_INFO</Name>
<RecurrentTimes>1</RecurrentTimes>
</Operation>
<Operation>
<Name>APPLICATION_LIST</Name>
<RecurrentTimes>5</RecurrentTimes>
</Operation>
<Operation>
<Name>DEVICE_LOCATION</Name>
<RecurrentTimes>1</RecurrentTimes>
</Operation>
</Operations>
</TaskConfiguration>
<DataSource>
<jndiConfig>
<name>jdbc/SampleDM_DB</name>
</jndiConfig>
<tableConfig>
<Table name="SAMPLE_DEVICE_1">
<PrimaryKey>SAMPLE_DEVICE_ID</PrimaryKey>
<Attributes>
<Attribute>column1</Attribute>
<Attribute>column2</Attribute>
</Attributes>
</Table>
</tableConfig>
</DataSource>
<InitialOperationConfig>
<Operations>
<Operation>DEVICE_INFO</Operation>
<Operation>APPLICATION_LIST</Operation>
<Operation>DEVICE_LOCATION</Operation>
</Operations>
</InitialOperationConfig>
<!--This configures the Task service for the device-type. Given below are the property definitions.
<RequireStatusMonitoring> - This will enable or disable status monitoring for that particular device-type.
<Frequency> - The time interval (in seconds) in which the task should run for this device-type
<IdleTimeToMarkInactive> - The time duration (in seconds) in which the device can be moved to inactive status
which means the device will be moved to inactive status if that device does not
contact the server within that time period.
<IdleTimeToMarkUnreachable> - The time duration (in seconds) in which the device can be moved to unreachable status
which means the device will be moved to unreachable status if that device does not
contact the server within that time period.
-->
<DeviceStatusTaskConfig>
<RequireStatusMonitoring>false</RequireStatusMonitoring>
<Frequency>300</Frequency>
<IdleTimeToMarkInactive>600</IdleTimeToMarkInactive>
<IdleTimeToMarkUnreachable>300</IdleTimeToMarkUnreachable>
</DeviceStatusTaskConfig>
</DeviceTypeConfiguration>

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.8-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.pull.notification</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Pull Notification Provider Implementation</name>
<description>WSO2 Carbon - Pull Notification Provider Implementation</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.mgt.core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Bundle-Version>${carbon.device.mgt.version}</Bundle-Version>
<Bundle-Description>Pull Notification Provider Bundle</Bundle-Description>
<Export-Package>
!org.wso2.carbon.device.mgt.extensions.pull.notification.internal,
org.wso2.carbon.device.mgt.extensions.pull.notification.*
</Export-Package>
<Import-Package>
org.osgi.framework,
org.osgi.service.component,
org.apache.commons.logging,
org.wso2.carbon.device.mgt.common.*,
org.wso2.carbon.device.mgt.core.service
org.wso2.carbon.policy.mgt.core.*,
org.wso2.carbon.policy.mgt.core,
com.google.gson,
org.wso2.carbon.device.mgt.core.service.*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,102 @@
/*
* Copyright (c) 2017, 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.extensions.pull.notification;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.extensions.pull.notification.internal.PullNotificationDataHolder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class PullNotificationSubscriberImpl implements PullNotificationSubscriber {
public final class OperationCodes {
private OperationCodes() {
throw new AssertionError();
}
public static final String POLICY_MONITOR = "POLICY_MONITOR";
}
private static final Log log = LogFactory.getLog(PullNotificationSubscriberImpl.class);
public void init(Map<String, String> properties) {
}
@Override
public void execute(DeviceIdentifier deviceIdentifier, Operation operation) throws PullNotificationExecutionFailedException {
try {
if (!Operation.Status.ERROR.equals(operation.getStatus()) && operation.getCode() != null &&
OperationCodes.POLICY_MONITOR.equals(operation.getCode())) {
if (log.isDebugEnabled()) {
log.info("Received compliance status from POLICY_MONITOR operation ID: " + operation.getId());
}
List<ComplianceFeature> features = getComplianceFeatures(operation.getPayLoad());
PullNotificationDataHolder.getInstance().getPolicyManagerService()
.checkCompliance(deviceIdentifier, features);
} else {
PullNotificationDataHolder.getInstance().getDeviceManagementProviderService().updateOperation(
deviceIdentifier, operation);
}
} catch (OperationManagementException e) {
throw new PullNotificationExecutionFailedException(e);
} catch (PolicyComplianceException e) {
throw new PullNotificationExecutionFailedException("Invalid payload format compliant feature", e);
}
}
public void clean() {
}
private static List<ComplianceFeature> getComplianceFeatures(Object compliancePayload) throws
PolicyComplianceException {
String compliancePayloadString = new Gson().toJson(compliancePayload);
if (compliancePayload == null) {
return null;
}
// Parsing json string to get compliance features.
JsonElement jsonElement = new JsonParser().parse(compliancePayloadString);
JsonArray jsonArray = jsonElement.getAsJsonArray();
Gson gson = new Gson();
ComplianceFeature complianceFeature;
List<ComplianceFeature> complianceFeatures = new ArrayList<ComplianceFeature>(jsonArray.size());
for (JsonElement element : jsonArray) {
complianceFeature = gson.fromJson(element, ComplianceFeature.class);
complianceFeatures.add(complianceFeature);
}
return complianceFeatures;
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, 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.extensions.pull.notification.internal;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
public class PullNotificationDataHolder {
private DeviceManagementProviderService deviceManagementProviderService;
private PolicyManagerService policyManagerService;
private static PullNotificationDataHolder thisInstance = new PullNotificationDataHolder();
public static PullNotificationDataHolder getInstance() {
return thisInstance;
}
public DeviceManagementProviderService getDeviceManagementProviderService() {
return deviceManagementProviderService;
}
public void setDeviceManagementProviderService(DeviceManagementProviderService deviceManagementProviderService) {
this.deviceManagementProviderService = deviceManagementProviderService;
}
public PolicyManagerService getPolicyManagerService() {
return policyManagerService;
}
public void setPolicyManagerService(PolicyManagerService policyManagerService) {
this.policyManagerService = policyManagerService;
}
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2017, 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.extensions.pull.notification.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.core.service.DeviceManagementProviderService;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
/**
* @scr.component name="org.wso2.carbon.device.mgt.extensions.pull.notification.internal.PullNotificationServiceComponent" immediate="true"
* @scr.reference name="carbon.device.mgt.provider"
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
* cardinality="1..1"
* policy="dynamic"
* bind="setDeviceManagementProviderService"
* unbind="unsetDeviceManagementProviderService"
* @scr.reference name="org.wso2.carbon.policy.mgt.core"
* interface="org.wso2.carbon.policy.mgt.core.PolicyManagerService"
* cardinality="1..1"
* policy="dynamic"
* bind="setPolicyManagerService"
* unbind="unsetPolicyManagerService"
*/
public class PullNotificationServiceComponent {
private static final Log log = LogFactory.getLog(PullNotificationServiceComponent.class);
@SuppressWarnings("unused")
protected void activate(ComponentContext componentContext) {
try {
//Do nothing
if (log.isDebugEnabled()) {
log.debug("pull notification provider implementation bundle has been successfully " +
"initialized");
}
} catch (Throwable e) {
log.error("Error occurred while initializing pull notification provider " +
"implementation bundle", e);
}
}
protected void deactivate(ComponentContext componentContext) {
//Do nothing
}
protected void setDeviceManagementProviderService(DeviceManagementProviderService deviceManagementProviderService) {
PullNotificationDataHolder.getInstance().setDeviceManagementProviderService(deviceManagementProviderService);
}
protected void unsetDeviceManagementProviderService(DeviceManagementProviderService deviceManagementProviderService) {
PullNotificationDataHolder.getInstance().setDeviceManagementProviderService(null);
}
protected void setPolicyManagerService(PolicyManagerService policyManagerService) {
PullNotificationDataHolder.getInstance().setPolicyManagerService(policyManagerService);
}
protected void unsetPolicyManagerService(PolicyManagerService policyManagerService) {
PullNotificationDataHolder.getInstance().setPolicyManagerService(null);
}
}

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.8-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.http</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - HTTP Based Push Notification Provider Implementation</name>
<description>WSO2 Carbon - HTTP Based Push Notification Provider Implementation</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.governance</groupId>
<artifactId>org.wso2.carbon.governance.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.registry.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.registry.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
<artifactId>axiom</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.org.scannotation</groupId>
<artifactId>scannotation</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.tomcat</groupId>
<artifactId>tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2</artifactId>
</dependency>
<dependency>
<groupId>commons-lang.wso2</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.json.wso2</groupId>
<artifactId>json</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Bundle-Version>${carbon.device.mgt.version}</Bundle-Version>
<Bundle-Description>MQTT Based Push Notification Provider Bundle</Bundle-Description>
<Export-Package>
!org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.internal,
org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.*
</Export-Package>
<Import-Package>
org.apache.commons.logging,
org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.device.mgt.common.operation.mgt,
org.wso2.carbon.device.mgt.common.push.notification,
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.core.service,
org.osgi.framework,
org.wso2.carbon.device.mgt.core.operation.mgt,
org.wso2.carbon.core,
com.google.gson,
org.apache.commons.httpclient.*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -16,24 +16,22 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.http;
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.dao;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationProvider;
public class DeviceTypePluginDAOManager {
public class HTTPBasedPushNotificationProvider implements PushNotificationProvider {
private DeviceTypePluginDAO deviceTypePluginDAO;
private DeviceTypeDAOHandler deviceTypeDAOHandler;
public DeviceTypePluginDAOManager(String datasourceName, DeviceDAODefinition deviceDAODefinition) {
deviceTypeDAOHandler = new DeviceTypeDAOHandler(datasourceName);
deviceTypePluginDAO = new DeviceTypePluginDAO(deviceDAODefinition, deviceTypeDAOHandler);
@Override
public String getType() {
return "HTTP";
}
public DeviceTypePluginDAO getDeviceDAO() {
return deviceTypePluginDAO;
@Override
public NotificationStrategy getNotificationStrategy(PushNotificationConfig config) {
return new HTTPNotificationStrategy(config);
}
public DeviceTypeDAOHandler getDeviceTypeDAOHandler() {
return deviceTypeDAOHandler;
}
}
}

@ -0,0 +1,94 @@
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.http;
import com.google.gson.Gson;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import java.net.UnknownHostException;
public class HTTPMessageExecutor implements Runnable {
private String url;
private String authorizationHeader;
private String payload;
private HostConfiguration hostConfiguration;
private HttpClient httpClient;
private static final String APPLIATION_JSON = "application/json";
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final Log log = LogFactory.getLog(HTTPMessageExecutor.class);
public HTTPMessageExecutor(NotificationContext notificationContext, String authorizationHeader, String url
, HostConfiguration hostConfiguration, HttpClient httpClient) {
this.url = url;
this.authorizationHeader = authorizationHeader;
Gson gson = new Gson();
this.payload = gson.toJson(notificationContext);
this.hostConfiguration = hostConfiguration;
this.httpClient = httpClient;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAuthorizationHeader() {
return authorizationHeader;
}
public void setAuthorizationHeader(String authorizationHeader) {
this.authorizationHeader = authorizationHeader;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public HttpClient getHttpClient() {
return httpClient;
}
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
public void run() {
EntityEnclosingMethod method = null;
try {
method = new PostMethod(this.getUrl());
method.setRequestEntity(new StringRequestEntity(this.getPayload(), APPLIATION_JSON, "UTF-8"));
if (authorizationHeader != null && authorizationHeader.isEmpty()) {
method.setRequestHeader(AUTHORIZATION_HEADER, authorizationHeader);
}
this.getHttpClient().executeMethod(hostConfiguration, method);
} catch (UnknownHostException e) {
log.error("Push Notification message dropped " + url, e);
throw new InvalidConfigurationException("invalid host: url", e);
} catch (Throwable e) {
log.error("Push Notification message dropped ", e);
throw new InvalidConfigurationException("Push Notification message dropped, " + e.getMessage(), e);
} finally {
if (method != null) {
method.releaseConnection();
}
}
}
}

@ -0,0 +1,103 @@
/*
* 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.extensions.push.notification.provider.http;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationExecutionFailedException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
public class HTTPNotificationStrategy implements NotificationStrategy {
private static final Log log = LogFactory.getLog(HTTPNotificationStrategy.class);
private final PushNotificationConfig config;
private static final String URL_PROPERTY = "url";
private static final String AUTHORIZATION_HEADER_PROPERTY = "authorization";
private String endpoint;
private static ExecutorService executorService;
private HttpClient httpClient = null;
private HostConfiguration hostConfiguration;
private String authorizationHeaderValue;
private String uri;
public HTTPNotificationStrategy(PushNotificationConfig config) {
this.config = config;
if (this.config == null) {
throw new InvalidConfigurationException("Properties Cannot be found");
}
endpoint = config.getProperties().get(URL_PROPERTY);
if (endpoint == null || endpoint.isEmpty()) {
throw new InvalidConfigurationException("Property - 'url' cannot be found");
}
try {
this.uri = endpoint;
URL url = new URL(endpoint);
hostConfiguration = new HostConfiguration();
hostConfiguration.setHost(url.getHost(), url.getPort(), url.getProtocol());
this.authorizationHeaderValue = config.getProperties().get(AUTHORIZATION_HEADER_PROPERTY);
executorService = Executors.newFixedThreadPool(1);
httpClient = new HttpClient();
} catch (MalformedURLException e) {
throw new InvalidConfigurationException("Property - 'url' is malformed.", e);
}
}
@Override
public void init() {
}
@Override
public void execute(NotificationContext ctx) throws PushNotificationExecutionFailedException {
try {
executorService.submit(new HTTPMessageExecutor(ctx, authorizationHeaderValue, uri, hostConfiguration
, httpClient));
} catch (RejectedExecutionException e) {
log.error("Failed to publish to external endpoint url: " + endpoint, e);
}
}
@Override
public NotificationContext buildContext() {
return null;
}
@Override
public void undeploy() {
executorService.shutdown();
}
@Override
public PushNotificationConfig getConfig() {
return config;
}
}

@ -0,0 +1,49 @@
/*
* 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.extensions.push.notification.provider.http.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
/**
* @scr.component name="org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.internal.HTTPPushNotificationServiceComponent" immediate="true"
*/
public class HTTPPushNotificationServiceComponent {
private static final Log log = LogFactory.getLog(HTTPPushNotificationServiceComponent.class);
@SuppressWarnings("unused")
protected void activate(ComponentContext componentContext) {
try {
if (log.isDebugEnabled()) {
log.debug("Initializing HTTP based push notification provider implementation bundle");
}
//Do nothing
if (log.isDebugEnabled()) {
log.debug("HTTP based push notification provider implementation bundle has been successfully " +
"initialized");
}
} catch (Throwable e) {
log.error("Error occurred while initializing HTTP based push notification provider " +
"implementation bundle", e);
}
}
}

@ -21,8 +21,8 @@ package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
@ -147,7 +147,7 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
for (ProfileOperation profileOperation : profileOperations) {
Map<String, String> dynamicProperties = new HashMap<>();
String topic = tenantDomain + "/"
+ deviceType + "/" + deviceId + "/" + profileOperation.getType()
+ deviceType + "/" + deviceId + "/operation/" + profileOperation.getType()
.toString().toLowerCase() + "/" + profileOperation.getCode().toLowerCase();
dynamicProperties.put("topic", topic);
MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(adapterName, dynamicProperties,
@ -157,14 +157,17 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
} else {
Map<String, String> dynamicProperties = new HashMap<>();
String topic = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + "/"
+ ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/" + operation.getType()
.toString().toLowerCase() + "/" + operation.getCode();
+ ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/operation/"
+ operation.getType().toString().toLowerCase() + "/" + operation.getCode() + "/" + operation.getId();
dynamicProperties.put("topic", topic);
if (operation.getPayLoad() == null) {
operation.setPayLoad("");
Object payload;
if ("command".equals(operation.getType().toString().toLowerCase())) {
payload = operation.getCode();
} else {
payload = operation.getPayLoad();
}
MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(adapterName, dynamicProperties,
operation.getPayLoad());
payload);
}

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;

@ -34,10 +34,12 @@
<url>http://wso2.org</url>
<modules>
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.http</module>
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm</module>
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt</module>
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp</module>
<module>org.wso2.carbon.device.mgt.extensions.device.type.deployer</module>
<module>org.wso2.carbon.device.mgt.extensions.pull.notification</module>
</modules>
</project>

@ -125,7 +125,8 @@
javax.xml.*,
javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional,
org.w3c.dom,
org.wso2.carbon.base
org.wso2.carbon.base,
org.wso2.carbon.utils.multitenancy
</Import-Package>
</instructions>
</configuration>

@ -167,6 +167,16 @@
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
@ -280,16 +290,6 @@
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.receiver.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.stream.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.commons</groupId>
@ -327,7 +327,41 @@
<version>${carbon.identity.framework.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.datasource.commons</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.dataservice.commons</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.receiver.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.stream.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.publisher.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.stream.persistence.stub</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,45 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.jaxrs.beans;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.util.List;
@ApiModel(value = "OperationRequest", description = "Operation details together with deviceIdentifier")
public class OperationRequest {
@ApiModelProperty(name = "deviceIdentifiers", value = "list of devices that needs to be verified against the user", required = true)
List<String> deviceIdentifiers;
@ApiModelProperty(name = "operation", value = "operation data", required = false)
Operation operation;
public List<String> getDeviceIdentifiers() {
return deviceIdentifiers;
}
public void setDeviceIdentifiers(List<String> deviceIdentifiers) {
this.deviceIdentifiers = deviceIdentifiers;
}
public Operation getOperation() {
return operation;
}
public void setOperation(Operation operation) {
this.operation = operation;
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
/**
* This hold the attribute definition.
*/
public class Attribute {
@ApiModelProperty(value = "Event Attribute Name")
@JsonProperty("name")
private String name;
@ApiModelProperty(value = "Event Attribute Type")
@JsonProperty("type")
private AttributeType type;
public Attribute() {
}
public Attribute(String name, AttributeType attributeType) {
this.name = name;
this.type = attributeType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AttributeType getType() {
return type;
}
public void setType(AttributeType type) {
this.type = type;
}
}

@ -0,0 +1,32 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
/**
* This hold the definition of the attribute type for the attributes.
*/
public enum AttributeType {
STRING, LONG, BOOL, INT, FLOAT, DOUBLE;
@Override
public String toString() {
return super.toString().toLowerCase();
}
}

@ -0,0 +1,53 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
/**
* This hold stats data record
*/
public class DeviceTypeEvent {
private EventAttributeList eventAttributes;
private TransportType transport;
@ApiModelProperty(value = "Attributes related to device type event")
@JsonProperty("eventAttributes")
public EventAttributeList getEventAttributeList() {
return eventAttributes;
}
public void setEventAttributeList(
EventAttributeList eventAttributes) {
this.eventAttributes = eventAttributes;
}
@ApiModelProperty(value = "Transport to be used for device to server communication.")
@JsonProperty("transport")
public TransportType getTransportType() {
return transport;
}
public void setTransportType(TransportType transport) {
this.transport = transport;
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult;
import java.util.ArrayList;
import java.util.List;
/**
* This holds event attributes
*/
public class EventAttributeList {
private List<Attribute> attributes = new ArrayList<>();
@ApiModelProperty(value = "List of Event Attributes")
@JsonProperty("attributes")
public List<Attribute> getList() {
return attributes;
}
public void setList(List<Attribute> attributes) {
this.attributes = attributes;
}
}

@ -0,0 +1,59 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.Device;
import java.util.ArrayList;
import java.util.List;
import org.wso2.carbon.analytics.datasource.commons.Record;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult;
/**
* This hold stats data record
*/
public class EventRecords extends BasePaginatedResult {
private List<Record> records = new ArrayList<>();
@ApiModelProperty(value = "List of records returned")
@JsonProperty("records")
public List<Record> getRecord() {
return records;
}
public void setList(List<Record> records) {
this.records = records;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{\n");
sb.append(" count: ").append(getCount()).append(",\n");
sb.append(" records: [").append(records).append("\n");
sb.append("]}\n");
return sb.toString();
}
}

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017, 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.jaxrs.beans.analytics;
/**
* This hold the default transport types support by the server.
*/
public enum TransportType {
HTTP, MQTT;
}

@ -0,0 +1,608 @@
/*
* 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.jaxrs.service.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "DeviceAgent Service"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/device/agent"),
})
}
),
tags = {
@Tag(name = "device_agent, device_management", description = "")
}
)
@Api(value = "Device Agent", description = "Device Agent Service")
@Path("/device/agent")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Scopes(
scopes = {
@Scope(
name = "Enroll Device",
description = "Register a device",
key = "perm:device:enroll",
permissions = {"/device-mgt/devices/owning-device/add"}
),
@Scope(
name = "Modify Device",
description = "Modify a device",
key = "perm:device:modify",
permissions = {"/device-mgt/devices/owning-device/modify"}
),
@Scope(
name = "Disenroll Device",
description = "Disenroll a device",
key = "perm:device:disenroll",
permissions = {"/device-mgt/devices/owning-device/remove"}
),
@Scope(
name = "Publish Event",
description = "publish device event",
key = "perm:device:publish-event",
permissions = {"/device-mgt/devices/owning-device/event"}
),
@Scope(
name = "Getting Device Operation Details",
description = "Getting Device Operation Details",
key = "perm:device:operations",
permissions = {"/device-mgt/devices/owning-device/view"}
)
}
)
public interface DeviceAgentService {
@POST
@Path("/enroll")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create a device instance",
notes = "Create a device Instance",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully created a device instance.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version" +
" of the requested resource.\n"),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n A deviceType with the specified device type was not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving the device details.",
response = ErrorResponse.class)
})
Response enrollDevice(@ApiParam(name = "device", value = "Device object with data.", required = true)
@Valid Device device);
@DELETE
@Path("/enroll/{type}/{id}")
@ApiOperation(
httpMethod = "DELETE",
value = "Unregistering a Device",
notes = "Use this REST API to unregister a device.",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:disenroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully disenrolled the device."),
@ApiResponse(
code = 404,
message = "Not Found. \n The specified resource does not exist."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while dis-enrolling the device.")
})
Response disEnrollDevice(
@ApiParam(name = "type", value = "The unique device identifier.") @PathParam("type") String type,
@ApiParam(name = "id", value = "The unique device identifier.") @PathParam("id") String id);
@PUT
@Path("/enroll/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "modify device",
notes = "modify device",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:modify")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully updated device instance.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version" +
" of the requested resource.\n"),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n A deviceType with the specified device type was not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving the device details.",
response = ErrorResponse.class)
})
Response updateDevice(@ApiParam(name = "type", value = "The device type, such as ios, android or windows....etc", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId,
@ApiParam(name = "device", value = "Device object with data.", required = true)
@Valid Device updateDevice);
@POST
@Path("/events/publish/{type}/{deviceId}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Publishing Events",
notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event")
})
}
)
@ApiResponses(
value = {
@ApiResponse(code = 200, message = "OK. \n Successfully published the event",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")
}),
@ApiResponse(
code = 303,
message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error."),
@ApiResponse(
code = 415,
message = "Unsupported media type. \n The format of the requested entity was not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while publishing events.")
})
Response publishEvents(
@ApiParam(
name = "payloadData",
value = "Information of the agent event to be published on DAS.")
@Valid
Map<String, Object> payloadData,
@ApiParam(
name = "type",
value = "name of the device type")
@PathParam("type") String type,
@ApiParam(
name = "deviceId",
value = "deviceId of the device")
@PathParam("deviceId") String deviceId);
@POST
@Path("/events/publish/data/{type}/{deviceId}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Publishing Events data only",
notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event")
})
}
)
@ApiResponses(
value = {
@ApiResponse(code = 200, message = "OK. \n Successfully published the event",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")
}),
@ApiResponse(
code = 303,
message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error."),
@ApiResponse(
code = 415,
message = "Unsupported media type. \n The format of the requested entity was not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while publishing events.")
})
Response publishEvents(
@ApiParam(
name = "payloadData",
value = "Information of the agent event to be published on DAS.")
@Valid
List<Object> payloadData,
@ApiParam(
name = "type",
value = "name of the device type")
@PathParam("type") String type,
@ApiParam(
name = "deviceId",
value = "deviceId of the device")
@PathParam("deviceId") String deviceId);
@GET
@Path("/pending/operations/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get pending operation of the given device",
notes = "Returns the Operations.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved the operations.",
response = OperationList.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
Response getPendingOperations(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId);
@GET
@Path("/next-pending/operation/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get pending operation of the given device",
notes = "Returns the Operation.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved the operation.",
response = Operation.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
Response getNextPendingOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId);
@PUT
@Path("/operations/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "Update Operation",
notes = "Update the Operations.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully updated the operations.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
Response updateOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId,
@ApiParam(name = "operation", value = "Operation object with data.", required = true)
@Valid Operation operation);
@GET
@Path("/status/operations/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get pending operation of the given device",
notes = "Returns the Operations.",
tags = "Device Agent Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved the operations.",
response = OperationList.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
Response getOperationsByDeviceAndStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId,
@ApiParam(name = "status", value = "status of the operation.", required = true)
@QueryParam("status")Operation.Status status);
}

@ -0,0 +1,347 @@
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.DeviceTypeEvent;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventRecords;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.TransportType;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "DeviceEventManagement"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/events"),
})
}
),
tags = {
@Tag(name = "device_management", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Add or Delete Event Definition for device type",
description = "Add or Delete Event Definition for device type",
key = "perm:device-types:events",
permissions = {"/device-mgt/device-type/add"}
),
@Scope(
name = "Get Events Details of a Device Type",
description = "Get Events Details of a Device Type",
key = "perm:device-types:events:view",
permissions = {"/device-mgt/devices/owning-device/view"}
)
}
)
@Path("/events")
@Api(value = "Device Event Management", description = "This API corresponds to all tasks related to device " +
"event management")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface DeviceEventManagementService {
@POST
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Add Event Type Defnition",
notes = "Add the event definition for the device.",
tags = "Device Event Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully added the event defintion.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 400,
message =
"Bad Request. \n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response deployDeviceTypeEventDefinition(@ApiParam(name = "type", value = "name of the device type", required = false)
@PathParam("type")String deviceType,
@ApiParam(name = "deviceTypeEvent", value = "DeviceTypeEvent object with data.", required = true)
@Valid DeviceTypeEvent deviceTypeEvent);
@DELETE
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "DELETE",
value = "Delete Event Type Defnition",
notes = "Delete the event definition for the device.",
tags = "Device Event Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully deleted the event definition.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 400,
message =
"Bad Request. \n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response deleteDeviceTypeEventDefinitions(@ApiParam(name = "type", value = "name of the device type", required = false)
@PathParam("type")String deviceType);
@GET
@Path("/{type}/{deviceId}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Device Events",
notes = "Get the events for the device.",
tags = "Device Event Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the event definition.",
response = EventRecords.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 400,
message =
"Bad Request. \n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response getData(@ApiParam(name = "deviceId", value = "id of the device ", required = false)
@PathParam("deviceId") String deviceId,
@ApiParam(name = "from", value = "unix timestamp to retrieve", required = false)
@QueryParam("from") long from,
@ApiParam(name = "to", value = "unix time to retrieve", required = false)
@QueryParam("to") long to,
@ApiParam(name = "type", value = "name of the device type", required = false)
@PathParam("type") String deviceType,
@ApiParam(name = "offset", value = "offset of the records that needs to be picked up", required = false)
@QueryParam("offset") int offset,
@ApiParam(name = "limit", value = "limit of the records that needs to be picked up", required = false)
@QueryParam("limit") int limit);
@GET
@Path("last-known/{type}/{deviceId}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Last Known Device Events",
notes = "Get the Last Known events for the device.",
tags = "Device Event Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the event.",
response = EventRecords.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 400,
message =
"Bad Request. \n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response getLastKnownData(@ApiParam(name = "deviceId", value = "id of the device ", required = false)
@PathParam("deviceId") String deviceId,
@ApiParam(name = "type", value = "name of the device type", required = false)
@PathParam("type") String deviceType);
@GET
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Event Type Defnition",
notes = "Get the event definition for the device.",
tags = "Device Event Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the event defintion.",
response = DeviceTypeEvent.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 400,
message =
"Bad Request. \n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response getDeviceTypeEventDefinition(@ApiParam(name = "type", value = "name of the device type", required = false)
@PathParam("type")String deviceType) ;
}

@ -32,17 +32,22 @@ import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.search.SearchContext;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@ -56,6 +61,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
/**
* Device related REST-API. This can be used to manipulated device related details.
@ -443,6 +449,60 @@ public interface DeviceManagementService {
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
@PUT
@Path("/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get device enrollment status",
notes = "Get device enrollment status",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully created a device instance.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version" +
" of the requested resource.\n"),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n A deviceType with the specified device type was not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving the device details.",
response = ErrorResponse.class)
})
Response isEnrolled(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true)
@PathParam("type") String type,
@ApiParam(name = "id", value = "The device id.", required = true)
@PathParam("id") String deviceId);
@GET
@Path("/{type}/{id}/location")
@ -1253,4 +1313,62 @@ public interface DeviceManagementService {
@QueryParam("newStatus")
EnrolmentInfo.Status newStatus);
@POST
@Path("/{type}/operations")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Add operation to set of devices for a given device type",
notes = "Returns the Activity Related to the operation.",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "OK. \n Successfully added the operation.",
response = Activity.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
Response addOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows... etc.", required = true)
@PathParam("type") String type,
@ApiParam(name = "deviceOperation", value = "Operation object with device ids.", required = true)
@Valid OperationRequest operationRequest);
}

@ -31,6 +31,7 @@ import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ResponseHeader;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
@ -206,4 +207,103 @@ public interface DeviceTypeManagementService {
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
@GET
@Path("/all/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of a Device Type",
notes = "Get the details of a device by searching via the device type and the tenant domain.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypeByName(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String type);
@GET
@Path("/all")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Retrieve device types information",
notes = "Retrieve device types information.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypes();
}

@ -0,0 +1,227 @@
/*
* 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.jaxrs.service.api.admin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "DeviceTypeManagementAdminService"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/admin/device-types"),
})
}
),
tags = {
@Tag(name = "device_management", description = "")
}
)
@Path("/admin/device-types")
@Api(value = "Device Type Management Administrative Service", description = "This an API intended to be used by " +
"'internal' components to log in as an admin user and do a selected number of operations. " +
"Further, this is strictly restricted to admin users only ")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Scopes(
scopes = {
@Scope(
name = "Getting Details of a Device",
description = "Getting Details of a Device",
key = "perm:admin:device-type",
permissions = {"/device-mgt/admin/device-type"}
)
}
)
public interface DeviceTypeManagementAdminService {
@GET
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting the Supported Device Type with Meta Definition",
notes = "Get the list of device types supported by WSO2 IoT.",
tags = "Device Type Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the list of supported device types.",
response = DeviceTypeList.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 304,
message =
"Not Modified. \n Empty body because the client already has the latest version " +
"of the requested resource.\n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response getDeviceTypes();
@POST
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Add a Device Type",
notes = "Add the details of a device type.",
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully added the device type.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response addDeviceType(@ApiParam(
name = "type",
value = "The device type such as ios, android, windows or fire-alarm.",
required = true)DeviceType deviceType);
@PUT
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "Update Device Type",
notes = "Update the details of a device type.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully updated the device type.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response updateDeviceType(@ApiParam(
name = "type",
value = "The device type such as ios, android, windows or fire-alarm.",
required = true) DeviceType deviceType);
}

@ -0,0 +1,574 @@
/*
* 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.jaxrs.service.impl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.axis2.AxisFault;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Attribute;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceAgentService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub;
import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto;
import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import javax.validation.Valid;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Path("/device/agent")
public class DeviceAgentServiceImpl implements DeviceAgentService {
private static final Log log = LogFactory.getLog(DeviceAgentServiceImpl.class);
private static final String POLICY_MONITOR = "POLICY_MONITOR";
@POST
@Path("/enroll")
@Override
public Response enrollDevice(@Valid Device device) {
if (device == null) {
String errorMessage = "The payload of the device enrollment is incorrect.";
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
try {
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
if (device.getType() == null || device.getDeviceIdentifier() == null) {
String errorMessage = "The payload of the device enrollment is incorrect.";
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
Device existingDevice = dms.getDevice(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
if (existingDevice != null && existingDevice.getEnrolmentInfo() != null && existingDevice
.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) {
String errorMessage = "An active enrolment exists";
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser());
device.getEnrolmentInfo().setDateOfEnrolment(System.currentTimeMillis());
device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis());
boolean status = dms.enrollDevice(device);
return Response.status(Response.Status.OK).entity(status).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while enrolling the device, which carries the id '" +
device.getDeviceIdentifier() + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (InvalidConfigurationException e) {
log.error("failed to add operation", e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
@DELETE
@Path("/enroll/{type}/{id}")
@Override
public Response disEnrollDevice(@PathParam("type") String type, @PathParam("id") String id) {
boolean result;
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type);
try {
result = DeviceMgtAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier);
if (result) {
return Response.status(Response.Status.OK).build();
} else {
return Response.status(Response.Status.NO_CONTENT).entity(type + " device that carries id '" + id +
"' has not been dis-enrolled").build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while enrolling the device, which carries the id '" + id + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@PUT
@Path("/enroll/{type}/{id}")
@Override
public Response updateDevice(@PathParam("type") String type, @PathParam("id") String id, @Valid Device updateDevice) {
Device device;
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(id);
deviceIdentifier.setType(type);
try {
device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
} catch (DeviceManagementException e) {
String msg = "Error occurred while getting enrollment details of the device that carries the id '" +
id + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
if (updateDevice == null) {
String errorMessage = "The payload of the device enrollment is incorrect.";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
if (device == null) {
String errorMessage = "The device to be modified doesn't exist.";
log.error(errorMessage);
return Response.status(Response.Status.NOT_FOUND).entity(errorMessage).build();
}
if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE ) {
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
DeviceMgtAPIUtils.getDeviceAccessAuthorizationService();
boolean status;
try {
status = deviceAccessAuthorizationService.isUserAuthorized(new DeviceIdentifier(id, type));
} catch (DeviceAccessAuthorizationException e) {
String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" +
id + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
if (!status) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
if(updateDevice.getEnrolmentInfo() != null) {
device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis());
device.setEnrolmentInfo(device.getEnrolmentInfo());
}
device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser());
if(updateDevice.getDeviceInfo() != null) {
device.setDeviceInfo(updateDevice.getDeviceInfo());
}
device.setDeviceIdentifier(id);
if(updateDevice.getDescription() != null) {
device.setDescription(updateDevice.getDescription());
}
if(updateDevice.getName() != null) {
device.setName(updateDevice.getName());
}
if(updateDevice.getFeatures() != null) {
device.setFeatures(updateDevice.getFeatures());
}
if(updateDevice.getProperties() != null) {
device.setProperties(updateDevice.getProperties());
}
boolean result;
try {
device.setType(type);
result = DeviceMgtAPIUtils.getDeviceManagementService().modifyEnrollment(device);
if (result) {
return Response.status(Response.Status.ACCEPTED).build();
} else {
return Response.status(Response.Status.NOT_MODIFIED).build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" +
id + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@POST
@Path("/events/publish/{type}/{deviceId}")
@Override
public Response publishEvents(@Valid Map<String, Object> payload, @PathParam("type") String type
, @PathParam("deviceId") String deviceId) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
try {
if (payload == null) {
String msg = "invalid payload structure";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} else {
boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized
(new DeviceIdentifier(type, deviceId));
if (!authorized) {
String msg = "Does not have permission to access the device.";
return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build();
}
}
Object metaData[] = new Object[1];
metaData[0] = deviceId;
EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type);
if (eventAttributeList == null) {
String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain);
eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto(
streamName + ":" + Constants.DEFAULT_STREAM_VERSION);
if (eventStreamDefinitionDto == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
} else {
EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData();
List<Attribute> attributes = new ArrayList<>();
for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) {
attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName()
, AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase())));
}
if (payload.size() != attributes.size()) {
String msg = "Payload does not match with the stream definition";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
eventAttributeList = new EventAttributeList();
eventAttributeList.setList(attributes);
DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList);
}
}
int i = 0;
Object[] payloadData = new Object[eventAttributeList.getList().size()];
for (Attribute attribute : eventAttributeList.getList()) {
if (attribute.getType() == AttributeType.INT) {
payloadData[i] = ((Double) payload.get(attribute.getName())).intValue();
} else if (attribute.getType() == AttributeType.LONG) {
payloadData[i] = ((Double) payload.get(attribute.getName())).longValue();
} else {
payloadData[i] = payload.get(attribute.getName());
}
i++;
}
if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type
, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain())
, Constants.DEFAULT_STREAM_VERSION, metaData
, null, payloadData)) {
return Response.status(Response.Status.OK).build();
} else {
String msg = "Error occurred while publishing the event.";
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} catch (DataPublisherConfigurationException e) {
String msg = "Error occurred while publishing the event.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (DeviceAccessAuthorizationException e) {
String msg = "Error occurred when checking for authorization";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (AxisFault e) {
log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RemoteException e) {
log.error("Failed to connect with the remote services:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (JWTClientException e) {
log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (UserStoreException e) {
log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} finally {
if (eventStreamAdminServiceStub != null) {
try {
eventStreamAdminServiceStub.cleanup();
} catch (AxisFault axisFault) {
log.warn("Failed to clean eventStreamAdminServiceStub");
}
}
}
}
@POST
@Path("/events/publish/data/{type}/{deviceId}")
@Override
public Response publishEvents(@Valid List<Object> payload, @PathParam("type") String type
, @PathParam("deviceId") String deviceId) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
try {
if (payload == null) {
String msg = "Invalid payload structure";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} else {
boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized
(new DeviceIdentifier(type, deviceId));
if (!authorized) {
String msg = "Does not have permission to access the device.";
return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build();
}
}
Object metaData[] = new Object[1];
metaData[0] = deviceId;
EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type);
if (eventAttributeList == null) {
String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain);
eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto(
streamName + ":" + Constants.DEFAULT_STREAM_VERSION);
if (eventStreamDefinitionDto == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
} else {
EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData();
List<Attribute> attributes = new ArrayList<>();
for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) {
attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName()
, AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase())));
}
if (payload.size() != attributes.size()) {
String msg = "Payload does not match with the stream definition";
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
eventAttributeList = new EventAttributeList();
eventAttributeList.setList(attributes);
DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList);
}
}
int i = 0;
Object[] payloadData = new Object[eventAttributeList.getList().size()];
for (Attribute attribute : eventAttributeList.getList()) {
if (attribute.getType() == AttributeType.INT) {
payloadData[i] = ((Double) payload.get(i)).intValue();
} else if (attribute.getType() == AttributeType.LONG) {
payloadData[i] = ((Double) payload.get(i)).longValue();
} else {
payloadData[i] = payload.get(i);
}
i++;
}
if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type
, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain())
, Constants.DEFAULT_STREAM_VERSION, metaData
, null, payloadData)) {
return Response.status(Response.Status.OK).build();
} else {
String msg = "Error occurred while publishing the event.";
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} catch (DataPublisherConfigurationException e) {
String msg = "Error occurred while publishing the event.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (DeviceAccessAuthorizationException e) {
String msg = "Error occurred when checking for authorization";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (AxisFault e) {
log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RemoteException e) {
log.error("Failed to connect with the remote services:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (JWTClientException e) {
log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (UserStoreException e) {
log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} finally {
if (eventStreamAdminServiceStub != null) {
try {
eventStreamAdminServiceStub.cleanup();
} catch (AxisFault axisFault) {
log.warn("Failed to clean eventStreamAdminServiceStub");
}
}
}
}
@GET
@Path("/pending/operations/{type}/{id}")
public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) {
try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type);
if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) {
String msg = "Device not found for identifier '" + deviceId + "'";
log.error(msg);
return Response.status(Response.Status.NO_CONTENT).entity(msg).build();
}
List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations(
deviceIdentifier);
OperationList operationsList = new OperationList();
operationsList.setList(operations);
operationsList.setCount(operations.size());
return Response.status(Response.Status.OK).entity(operationsList).build();
} catch (OperationManagementException e) {
String errorMessage = "Issue in retrieving operation management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
}
}
@GET
@Path("/next-pending/operation/{type}/{id}")
public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) {
try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device type is invalid";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type);
if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) {
String msg = "Device not found for identifier '" + deviceId + "'";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation(
deviceIdentifier);
return Response.status(Response.Status.OK).entity(operation).build();
} catch (OperationManagementException e) {
String errorMessage = "Issue in retrieving operation management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
}
}
@PUT
@Path("/operations/{type}/{id}")
public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) {
try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device type is invalid";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (operation == null) {
String errorMessage = "Operation cannot empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type);
if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) {
String msg = "Device not found for identifier '" + deviceId + "'";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
if (!Operation.Status.ERROR.equals(operation.getStatus()) && operation.getCode() != null &&
POLICY_MONITOR.equals(operation.getCode())) {
if (log.isDebugEnabled()) {
log.info("Received compliance status from POLICY_MONITOR operation ID: " + operation.getId());
}
List<ComplianceFeature> features = getComplianceFeatures(operation.getPayLoad());
DeviceMgtAPIUtils.getPolicyManagementService().checkCompliance(deviceIdentifier, features);
} else {
DeviceMgtAPIUtils.getDeviceManagementService().updateOperation(deviceIdentifier, operation);
}
return Response.status(Response.Status.OK).build();
} catch (OperationManagementException e) {
String errorMessage = "Issue in retrieving operation management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
} catch (PolicyComplianceException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
}
}
@GET
@Path("/status/operations/{type}/{id}")
public Response getOperationsByDeviceAndStatus(@PathParam("type") String type, @PathParam("id") String deviceId,
@QueryParam("status") Operation.Status status) {
if (status == null) {
String errorMessage = "Status is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Invalid Device Type";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService()
.getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status);
OperationList operationsList = new OperationList();
operationsList.setList(operations);
operationsList.setCount(operations.size());
return Response.status(Response.Status.OK).entity(operationsList).build();
} catch (OperationManagementException e) {
String errorMessage = "Issue in retrieving operation management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving device management service";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
}
}
private static List<ComplianceFeature> getComplianceFeatures(Object compliancePayload) throws
PolicyComplianceException {
String compliancePayloadString = new Gson().toJson(compliancePayload);
if (compliancePayload == null) {
return null;
}
// Parsing json string to get compliance features.
JsonElement jsonElement = new JsonParser().parse(compliancePayloadString);
JsonArray jsonArray = jsonElement.getAsJsonArray();
Gson gson = new Gson();
ComplianceFeature complianceFeature;
List<ComplianceFeature> complianceFeatures = new ArrayList<ComplianceFeature>(jsonArray.size());
for (JsonElement element : jsonArray) {
complianceFeature = gson.fromJson(element, ComplianceFeature.class);
complianceFeatures.add(complianceFeature);
}
return complianceFeatures;
}
}

@ -0,0 +1,590 @@
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Stub;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.dataservice.commons.SortType;
import org.wso2.carbon.analytics.stream.persistence.stub
.EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException;
import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub;
import org.wso2.carbon.analytics.stream.persistence.stub.dto.AnalyticsTable;
import org.wso2.carbon.analytics.stream.persistence.stub.dto.AnalyticsTableRecord;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.DeviceTypeEvent;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventRecords;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Attribute;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.TransportType;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceEventManagementService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceCallbackHandler;
import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub;
import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceCallbackHandler;
import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub;
import org.wso2.carbon.event.receiver.stub.types.BasicInputAdapterPropertyDto;
import org.wso2.carbon.event.receiver.stub.types.EventReceiverConfigurationDto;
import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub;
import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto;
import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import javax.validation.Valid;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
/**
* This is used for device type integration with DAS, to create streams and receiver dynamically and a common endpoint
* to retrieve data.
*/
@Path("/events")
public class DeviceEventManagementServiceImpl implements DeviceEventManagementService {
private static final Log log = LogFactory.getLog(DeviceEventManagementServiceImpl.class);
private static final String DEFAULT_EVENT_STORE_NAME = "EVENT_STORE";
private static final String DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE = "secured-websocket";
private static final String OAUTH_MQTT_ADAPTER_TYPE = "oauth-mqtt";
private static final String THRIFT_ADAPTER_TYPE = "iot-event";
private static final String DEFAULT_DEVICE_ID_ATTRIBUTE = "deviceId";
private static final String DEFAULT_META_DEVICE_ID_ATTRIBUTE = "meta_deviceId";
private static final String MQTT_CONTENT_TRANSFORMER = "device-meta-transformer";
private static final String MQTT_CONTENT_TRANSFORMER_TYPE = "contentTransformer";
private static final String MQTT_CONTENT_VALIDATOR_TYPE = "contentValidator";
private static final String MQTT_CONTENT_VALIDATOR = "default";
private static final String TIMESTAMP_FIELD_NAME = "_timestamp";
/**
* Retrieves the stream definition from das for the given device type.
* @return dynamic event attribute list
*/
@GET
@Path("/{type}")
@Override
public Response getDeviceTypeEventDefinition(@PathParam("type") String deviceType) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null;
try {
if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
String errorMessage = "Invalid device type";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain);
eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto(
streamName + ":" + Constants.DEFAULT_STREAM_VERSION);
if (eventStreamDefinitionDto == null) {
return Response.status(Response.Status.NO_CONTENT).build();
}
EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData();
EventAttributeList eventAttributeList = new EventAttributeList();
List<Attribute> attributes = new ArrayList<>();
for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) {
attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName()
, AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase())));
}
eventAttributeList.setList(attributes);
DeviceTypeEvent deviceTypeEvent = new DeviceTypeEvent();
deviceTypeEvent.setEventAttributeList(eventAttributeList);
deviceTypeEvent.setTransportType(TransportType.HTTP);
eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub();
EventReceiverConfigurationDto eventReceiverConfigurationDto = eventReceiverAdminServiceStub
.getActiveEventReceiverConfiguration(getReceiverName(deviceType, tenantDomain, TransportType.MQTT));
if (eventReceiverConfigurationDto != null) {
deviceTypeEvent.setTransportType(TransportType.MQTT);
}
return Response.ok().entity(deviceTypeEvent).build();
} catch (AxisFault e) {
log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RemoteException e) {
log.error("Failed to connect with the remote services:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (JWTClientException e) {
log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (UserStoreException e) {
log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceManagementException e) {
log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} finally {
cleanup(eventStreamAdminServiceStub);
cleanup(eventReceiverAdminServiceStub);
}
}
/**
* Deploy Event Stream, Receiver, Publisher and Store Configuration.
*/
@POST
@Path("/{type}")
@Override
public Response deployDeviceTypeEventDefinition(@PathParam("type") String deviceType,
@Valid DeviceTypeEvent deviceTypeEvent) {
TransportType transportType = deviceTypeEvent.getTransportType();
EventAttributeList eventAttributes = deviceTypeEvent.getEventAttributeList();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
try {
if (eventAttributes == null || eventAttributes.getList() == null || eventAttributes.getList().size() == 0 ||
deviceType == null || transportType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
String errorMessage = "Invalid Payload";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain);
String streamNameWithVersion = streamName + ":" + Constants.DEFAULT_STREAM_VERSION;
publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes);
publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType);
publishEventStore(streamName, Constants.DEFAULT_STREAM_VERSION, eventAttributes);
publishWebsocketPublisherDefinition(streamNameWithVersion, deviceType);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes);
publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType);
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
return Response.ok().build();
} catch (AxisFault e) {
log.error("Failed to create event definitions for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RemoteException e) {
log.error("Failed to connect with the remote services:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (JWTClientException e) {
log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (UserStoreException e) {
log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceManagementException e) {
log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException e) {
log.error("Failed to create event store for, tenantDomain: " + tenantDomain + " deviceType" + deviceType,
e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
/**
* Delete device type specific artifacts from DAS.
*/
@DELETE
@Path("/{type}")
@Override
public Response deleteDeviceTypeEventDefinitions(@PathParam("type") String deviceType) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null;
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = null;
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
EventReceiverAdminServiceStub tenantBasedEventReceiverAdminServiceStub = null;
EventStreamAdminServiceStub tenantBasedEventStreamAdminServiceStub = null;
try {
if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
String errorMessage = "Invalid device type";
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher";
String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain);
eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + Constants.DEFAULT_STREAM_VERSION) == null) {
return Response.status(Response.Status.NO_CONTENT).build();
}
eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, Constants.DEFAULT_STREAM_VERSION);
EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler =
new EventReceiverAdminServiceCallbackHandler() {};
EventPublisherAdminServiceCallbackHandler eventPublisherAdminServiceCallbackHandler =
new EventPublisherAdminServiceCallbackHandler() {};
String eventReceiverName = getReceiverName(deviceType, tenantDomain, TransportType.MQTT);
eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub();
if (eventReceiverAdminServiceStub.getInactiveEventReceiverConfigurationContent(eventReceiverName) == null) {
eventReceiverName = getReceiverName(deviceType, tenantDomain, TransportType.HTTP);
}
eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName
, eventReceiverAdminServiceCallbackHandler);
eventPublisherAdminServiceStub = DeviceMgtAPIUtils.getEventPublisherAdminServiceStub();
eventPublisherAdminServiceStub.startundeployInactiveEventPublisherConfiguration(eventPublisherName
, eventPublisherAdminServiceCallbackHandler);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
tenantBasedEventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub();
tenantBasedEventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
tenantBasedEventStreamAdminServiceStub.removeEventStreamDefinition(streamName,
Constants.DEFAULT_STREAM_VERSION);
tenantBasedEventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(
eventReceiverName, eventReceiverAdminServiceCallbackHandler);
}
} finally {
cleanup(tenantBasedEventReceiverAdminServiceStub);
cleanup(tenantBasedEventStreamAdminServiceStub);
PrivilegedCarbonContext.endTenantFlow();
}
return Response.ok().build();
} catch (AxisFault e) {
log.error("Failed to delete event definitions for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RemoteException e) {
log.error("Failed to connect with the remote services:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (JWTClientException e) {
log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (UserStoreException e) {
log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceManagementException e) {
log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} finally {
cleanup(eventStreamAdminServiceStub);
cleanup(eventPublisherAdminServiceStub);
cleanup(eventReceiverAdminServiceStub);
cleanup(eventReceiverAdminServiceStub);
cleanup(eventStreamAdminServiceStub);
}
}
/**
* Returns device specific data for the give period of time.
*/
@GET
@Path("/{type}/{deviceId}")
@Override
public Response getData(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to, @PathParam("type") String deviceType, @QueryParam("offset")
int offset, @QueryParam("limit") int limit) {
if (from == 0 || to == 0) {
String errorMessage = "Invalid values for from/to";
return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build();
}
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId
+ " AND _timestamp : [" + fromDate + " TO " + toDate + "]";
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain));
try {
if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
String errorMessage = "Invalid device type";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField(TIMESTAMP_FIELD_NAME, SortType.DESC);
sortByFields.add(sortByField);
EventRecords eventRecords = getAllEventsForDevice(sensorTableName, query, sortByFields, offset, limit);
return Response.status(Response.Status.OK.getStatusCode()).entity(eventRecords).build();
} catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceManagementException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
}
/**
* Returns the last know data point of the device type.
*/
@GET
@Path("/last-known/{type}/{deviceId}")
@Override
public Response getLastKnownData(@PathParam("deviceId") String deviceId, @PathParam("type") String deviceType) {
String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId;
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain));
try {
if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
String errorMessage = "Invalid device type";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField(TIMESTAMP_FIELD_NAME, SortType.DESC);
sortByFields.add(sortByField);
EventRecords eventRecords = getAllEventsForDevice(sensorTableName, query, sortByFields, 0, 1);
return Response.status(Response.Status.OK.getStatusCode()).entity(eventRecords).build();
} catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceManagementException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
}
private void publishEventReceivers(String streamNameWithVersion, TransportType transportType
, String requestedTenantDomain, String deviceType)
throws RemoteException, UserStoreException, JWTClientException {
EventReceiverAdminServiceStub receiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub();
try {
TransportType transportTypeToBeRemoved = TransportType.HTTP;
if (transportType == TransportType.HTTP) {
transportTypeToBeRemoved = TransportType.MQTT;
}
String eventRecieverNameTobeRemoved = getReceiverName(deviceType, requestedTenantDomain, transportTypeToBeRemoved);
EventReceiverConfigurationDto eventReceiverConfigurationDto = receiverAdminServiceStub
.getActiveEventReceiverConfiguration(eventRecieverNameTobeRemoved);
if (eventReceiverConfigurationDto != null) {
EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler =
new EventReceiverAdminServiceCallbackHandler() {};
receiverAdminServiceStub.startundeployActiveEventReceiverConfiguration(eventRecieverNameTobeRemoved
, eventReceiverAdminServiceCallbackHandler);
}
String adapterType = OAUTH_MQTT_ADAPTER_TYPE;
BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[];
if (transportType == TransportType.MQTT) {
basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[3];
basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("topic", requestedTenantDomain
+ "/" + deviceType + "/+/events");
basicInputAdapterPropertyDtos[1] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_TRANSFORMER_TYPE
, MQTT_CONTENT_TRANSFORMER);
basicInputAdapterPropertyDtos[2] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_VALIDATOR_TYPE
, MQTT_CONTENT_VALIDATOR);
} else {
adapterType = THRIFT_ADAPTER_TYPE;
basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[1];
basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("events.duplicated.in.cluster", "false");
}
String eventRecieverName = getReceiverName(deviceType, requestedTenantDomain, transportType);
if (receiverAdminServiceStub.getActiveEventReceiverConfiguration(eventRecieverName) == null) {
if (transportType == TransportType.MQTT) {
receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion
, adapterType, null, basicInputAdapterPropertyDtos, false);
} else {
receiverAdminServiceStub.deployWso2EventReceiverConfiguration(eventRecieverName, streamNameWithVersion
, adapterType, null, null, null, basicInputAdapterPropertyDtos, false, null);
}
}
} finally {
cleanup(receiverAdminServiceStub);
}
}
private void publishStreamDefinitons(String streamName, String version, String deviceType
, EventAttributeList eventAttributes)
throws RemoteException, UserStoreException, JWTClientException {
EventStreamAdminServiceStub eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub();
try {
EventStreamDefinitionDto eventStreamDefinitionDto = new EventStreamDefinitionDto();
eventStreamDefinitionDto.setName(streamName);
eventStreamDefinitionDto.setVersion(version);
EventStreamAttributeDto eventStreamAttributeDtos[] =
new EventStreamAttributeDto[eventAttributes.getList().size()];
EventStreamAttributeDto metaStreamAttributeDtos[] =
new EventStreamAttributeDto[1];
int i = 0;
for (Attribute attribute : eventAttributes.getList()) {
EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto();
eventStreamAttributeDto.setAttributeName(attribute.getName());
eventStreamAttributeDto.setAttributeType(attribute.getType().toString());
eventStreamAttributeDtos[i] = eventStreamAttributeDto;
i++;
}
EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto();
eventStreamAttributeDto.setAttributeName(DEFAULT_DEVICE_ID_ATTRIBUTE);
eventStreamAttributeDto.setAttributeType(AttributeType.STRING.toString());
metaStreamAttributeDtos[0] = eventStreamAttributeDto;
eventStreamDefinitionDto.setPayloadData(eventStreamAttributeDtos);
eventStreamDefinitionDto.setMetaData(metaStreamAttributeDtos);
String streamId = streamName + ":" + version;
if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) {
eventStreamAdminServiceStub.editEventStreamDefinitionAsDto(eventStreamDefinitionDto, streamId);
} else {
eventStreamAdminServiceStub.addEventStreamDefinitionAsDto(eventStreamDefinitionDto);
}
} finally {
cleanup(eventStreamAdminServiceStub);
}
}
private void publishEventStore(String streamName, String version, EventAttributeList eventAttributes)
throws RemoteException, UserStoreException, JWTClientException,
EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException {
EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub =
DeviceMgtAPIUtils.getEventStreamPersistenceAdminServiceStub();
try {
AnalyticsTable analyticsTable = new AnalyticsTable();
analyticsTable.setRecordStoreName(DEFAULT_EVENT_STORE_NAME);
analyticsTable.setStreamVersion(version);
analyticsTable.setTableName(streamName);
analyticsTable.setMergeSchema(false);
analyticsTable.setPersist(true);
AnalyticsTableRecord analyticsTableRecords[] = new AnalyticsTableRecord[eventAttributes.getList().size() + 1];
int i = 0;
for (Attribute attribute : eventAttributes.getList()) {
AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord();
analyticsTableRecord.setColumnName(attribute.getName());
analyticsTableRecord.setColumnType(attribute.getType().toString().toUpperCase());
analyticsTableRecord.setFacet(false);
analyticsTableRecord.setIndexed(false);
analyticsTableRecord.setPersist(true);
analyticsTableRecord.setPrimaryKey(false);
analyticsTableRecord.setScoreParam(false);
analyticsTableRecords[i] = analyticsTableRecord;
i++;
}
AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord();
analyticsTableRecord.setColumnName(DEFAULT_META_DEVICE_ID_ATTRIBUTE);
analyticsTableRecord.setColumnType(AttributeType.STRING.toString().toUpperCase());
analyticsTableRecord.setFacet(false);
analyticsTableRecord.setIndexed(true);
analyticsTableRecord.setPersist(true);
analyticsTableRecord.setPrimaryKey(false);
analyticsTableRecord.setScoreParam(false);
analyticsTableRecords[i] = analyticsTableRecord;
analyticsTable.setAnalyticsTableRecords(analyticsTableRecords);
eventStreamPersistenceAdminServiceStub.addAnalyticsTable(analyticsTable);
} finally {
cleanup(eventStreamPersistenceAdminServiceStub);
}
}
private void publishWebsocketPublisherDefinition(String streamNameWithVersion, String deviceType)
throws RemoteException, UserStoreException, JWTClientException {
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = DeviceMgtAPIUtils
.getEventPublisherAdminServiceStub();
try {
String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher";
if (eventPublisherAdminServiceStub.getActiveEventPublisherConfiguration(eventPublisherName) == null) {
eventPublisherAdminServiceStub.deployJsonEventPublisherConfiguration(eventPublisherName
, streamNameWithVersion, DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE, null, null
, null, false);
}
} finally {
cleanup(eventPublisherAdminServiceStub);
}
}
private BasicInputAdapterPropertyDto getBasicInputAdapterPropertyDto(String key, String value) {
BasicInputAdapterPropertyDto basicInputAdapterPropertyDto = new BasicInputAdapterPropertyDto();
basicInputAdapterPropertyDto.setKey(key);
basicInputAdapterPropertyDto.setValue(value);
return basicInputAdapterPropertyDto;
}
private String getTableName(String streamName) {
return streamName.toUpperCase().replace('.', '_');
}
private String getReceiverName(String deviceType, String tenantDomain, TransportType transportType) {
return deviceType.replace(" ", "_").trim() + "-" + tenantDomain + "-" + transportType.toString() + "-receiver";
}
private static AnalyticsDataAPI getAnalyticsDataAPI() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
AnalyticsDataAPI analyticsDataAPI =
(AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
if (analyticsDataAPI == null) {
String msg = "Analytics api service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return analyticsDataAPI;
}
private static EventRecords getAllEventsForDevice(String tableName, String query, List<SortByField> sortByFields
, int offset, int limit) throws AnalyticsException {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
EventRecords eventRecords = new EventRecords();
int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
if (eventCount == 0) {
eventRecords.setCount(0);
}
List<SearchResultEntry> resultEntries = analyticsDataAPI.search(tenantId, tableName, query, offset, limit,
sortByFields);
List<String> recordIds = getRecordIds(resultEntries);
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
eventRecords.setCount(eventCount);
eventRecords.setList(AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response));
return eventRecords;
}
private static List<String> getRecordIds(List<SearchResultEntry> searchResults) {
List<String> ids = new ArrayList<>();
for (SearchResultEntry searchResult : searchResults) {
ids.add(searchResult.getId());
}
return ids;
}
private void cleanup(Stub stub) {
if (stub != null) {
try {
stub.cleanup();
} catch (AxisFault axisFault) {
log.warn("Failed to clean the stub " + stub.getClass());
}
}
}
}

@ -24,10 +24,13 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
@ -35,6 +38,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
@ -44,6 +48,8 @@ import org.wso2.carbon.device.mgt.common.search.SearchContext;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
@ -51,6 +57,7 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceCompliance;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
@ -58,6 +65,8 @@ import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.security.auth.login.Configuration;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@ -83,6 +92,27 @@ import java.util.List;
public class DeviceManagementServiceImpl implements DeviceManagementService {
private static final Log log = LogFactory.getLog(DeviceManagementServiceImpl.class);
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
@GET
@Path("/{type}/{id}/status")
@Override
public Response isEnrolled(@PathParam("type") String type, @PathParam("id") String id) {
boolean result;
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type);
try {
result = DeviceMgtAPIUtils.getDeviceManagementService().isEnrolled(deviceIdentifier);
if (result) {
return Response.status(Response.Status.OK).build();
} else {
return Response.status(Response.Status.NO_CONTENT).build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while checking enrollment status of the device.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@GET
@Override
@ -552,7 +582,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
RequestValidationUtil.validateDeviceIdentifier(type, id);
PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService();
Policy policy;
NonComplianceData complianceData = null;
NonComplianceData complianceData;
DeviceCompliance deviceCompliance = new DeviceCompliance();
try {
@ -618,4 +648,78 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@POST
@Path("/{type}/operations")
public Response addOperation(@PathParam("type") String type, @Valid OperationRequest operationRequest) {
try {
if (operationRequest == null || operationRequest.getDeviceIdentifiers() == null
|| operationRequest.getOperation() == null) {
String errorMessage = "Operation cannot be empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device Type is invalid";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
Operation.Type operationType = operationRequest.getOperation().getType();
if (operationType == Operation.Type.COMMAND || operationType == Operation.Type.CONFIG) {
DeviceIdentifier deviceIdentifier;
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
for (String deviceId : operationRequest.getDeviceIdentifiers()) {
deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(type);
deviceIdentifiers.add(deviceIdentifier);
}
Operation operation;
if (operationType == Operation.Type.COMMAND) {
Operation commandOperation = operationRequest.getOperation();
operation = new CommandOperation();
operation.setType(Operation.Type.COMMAND);
operation.setCode(commandOperation.getCode());
operation.setEnabled(commandOperation.isEnabled());
operation.setStatus(commandOperation.getStatus());
} else {
Operation configOperation = operationRequest.getOperation();
operation = new ConfigOperation();
operation.setType(Operation.Type.CONFIG);
operation.setCode(configOperation.getCode());
operation.setEnabled(configOperation.isEnabled());
operation.setPayLoad(configOperation.getPayLoad());
operation.setStatus(configOperation.getStatus());
}
String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date());
operation.setCreatedTimeStamp(date);
Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type, operation,
deviceIdentifiers);
return Response.status(Response.Status.CREATED).entity(activity).build();
} else {
String message = "Only Command and Config operation is supported through this api";
return Response.status(Response.Status.NOT_ACCEPTABLE).entity(message).build();
}
} catch (InvalidDeviceException e) {
String errorMessage = "Invalid Device Identifiers found.";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (OperationManagementException e) {
String errorMessage = "Issue in retrieving operation management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (InvalidConfigurationException e) {
log.error("failed to add operation", e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
}

@ -23,6 +23,9 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -35,7 +38,9 @@ import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@Path("/device-types")
@ -86,4 +91,62 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
return Response.status(Response.Status.OK).entity(features).build();
}
@Override
@GET
@Path("/config")
public Response getDeviceTypes() {
try {
List<DeviceType> deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes();
List<DeviceType> filteredDeviceTypes = new ArrayList<>();
for (DeviceType deviceType : deviceTypes) {
filteredDeviceTypes.add(clearMetaEntryInfo(deviceType));
}
return Response.status(Response.Status.OK).entity(filteredDeviceTypes).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while fetching device type.";
log.error(msg, e);
return Response.serverError().entity(msg).build();
}
}
@Override
@GET
@Path("/config/{type}")
public Response getDeviceTypeByName(@PathParam("type") String type) {
if (type != null && type.length() > 0) {
try {
DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type);
if (deviceType == null) {
String msg = "Device type does not exist, " + type;
return Response.status(Response.Status.NO_CONTENT).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(deviceType).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while fetching device type.";
log.error(msg, e);
return Response.serverError().entity(msg).build();
}
} else {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
/**
* This cleans up the configs that should not be exposed to iot users.
* @param deviceType
* @return
*/
private DeviceType clearMetaEntryInfo(DeviceType deviceType) {
DeviceTypeMetaDefinition metaDefinition = deviceType.getDeviceTypeMetaDefinition();
if (metaDefinition != null) {
metaDefinition.setInitialOperationConfig(null);
if (metaDefinition.getPushNotificationConfig() != null) {
metaDefinition.setPushNotificationConfig(new PushNotificationConfig(metaDefinition.
getPushNotificationConfig().getType(), false, null));
}
deviceType.setDeviceTypeMetaDefinition(metaDefinition);
}
return deviceType;
}
}

@ -54,13 +54,13 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
@QueryParam("offset") int offset,
@QueryParam("limit") int limit) {
RequestValidationUtil.validatePaginationParameters(offset, limit);
int currentTenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (MultitenantConstants.SUPER_TENANT_ID != currentTenantId) {
return Response.status(Response.Status.UNAUTHORIZED).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(
"Current logged in user is not authorized to perform this operation").build()).build();
}
try {
int currentTenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (MultitenantConstants.SUPER_TENANT_ID != currentTenantId) {
return Response.status(Response.Status.UNAUTHORIZED).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(
"Current logged in user is not authorized to perform this operation").build()).build();
}
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(DeviceMgtAPIUtils.getTenantId(tenantDomain));

@ -0,0 +1,124 @@
/*
* 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.jaxrs.service.impl.admin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypeManagementAdminService;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Path("/admin/device-types")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagementAdminService {
private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminServiceImpl.class);
private static final String DEVICETYPE_REGEX_PATTERN = "^[^ /]+$";
private static final Pattern patternMatcher = Pattern.compile(DEVICETYPE_REGEX_PATTERN);
@GET
@Override
public Response getDeviceTypes() {
try {
List<DeviceType> deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes();
return Response.status(Response.Status.OK).entity(deviceTypes).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while fetching the list of device types.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@Override
@POST
public Response addDeviceType(DeviceType deviceType) {
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
try {
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) != null) {
String msg = "Device type already available, " + deviceType.getName();
return Response.status(Response.Status.CONFLICT).entity(msg).build();
}
Matcher matcher = patternMatcher.matcher(deviceType.getName());
if(matcher.find()) {
DeviceManagementService httpDeviceTypeManagerService =
DeviceMgtAPIUtils.getDeviceTypeGeneratorService()
.populateDeviceManagementService(deviceType.getName(),
deviceType.getDeviceTypeMetaDefinition());
DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService);
return Response.status(Response.Status.OK).build();
} else {
return Response.status(Response.Status.BAD_REQUEST).entity("Device type name does not match the pattern "
+ DEVICETYPE_REGEX_PATTERN).build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while adding a device type.";
log.error(msg, e);
return Response.serverError().entity(msg).build();
} catch (InvalidConfigurationException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
} else {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
@Override
@PUT
public Response updateDeviceType(DeviceType deviceType) {
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
try {
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) == null) {
String msg = "Device type does not exist, " + deviceType.getName();
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
DeviceManagementService httpDeviceTypeManagerService = DeviceMgtAPIUtils.getDeviceTypeGeneratorService()
.populateDeviceManagementService(deviceType.getName(), deviceType.getDeviceTypeMetaDefinition());
DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService);
return Response.status(Response.Status.OK).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while updating the device type.";
log.error(msg, e);
return Response.serverError().entity(msg).build();
} catch (InvalidConfigurationException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
} else {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
}

@ -27,8 +27,10 @@ public class Constants {
public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname";
public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname";
public static final String PRIMARY_USER_STORE = "PRIMARY";
public static final String DEFAULT_STREAM_VERSION = "1.0.0";
public static final String SCOPE = "scope";
public final class ErrorMessages {
private ErrorMessages () { throw new AssertionError(); }

@ -18,26 +18,48 @@
package org.wso2.carbon.device.mgt.jaxrs.util;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.java.security.SSLProtocolSocketFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException;
import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub;
import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub;
import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import org.wso2.carbon.identity.user.store.count.AbstractCountRetrieverFactory;
import org.wso2.carbon.identity.user.store.count.UserStoreCountRetriever;
@ -56,7 +78,22 @@ import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import javax.cache.Cache;
import javax.cache.Caching;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.ws.rs.core.MediaType;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
/**
@ -66,7 +103,51 @@ public class DeviceMgtAPIUtils {
public static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON_TYPE;
private static final String NOTIFIER_FREQUENCY = "notifierFrequency";
private static final String STREAM_DEFINITION_PREFIX = "iot.per.device.stream.";
private static final String DEFAULT_HTTP_PROTOCOL = "https";
private static final String EVENT_RECIEVER_CONTEXT = "EventReceiverAdminService/";
private static final String EVENT_PUBLISHER_CONTEXT = "EventPublisherAdminService/";
private static final String EVENT_STREAM_CONTEXT = "EventStreamAdminService/";
private static final String EVENT_PERSISTENCE_CONTEXT = "EventStreamPersistenceAdminService/";
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String AUTHORIZATION_HEADER_VALUE = "Bearer";
public static final String DAS_PORT = "${iot.analytics.https.port}";
public static final String DAS_HOST_NAME = "${iot.analytics.host}";
private static final String KEY_STORE_TYPE = "JKS";
private static final String TRUST_STORE_TYPE = "JKS";
private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type
private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type
private static final String SSLV3 = "SSLv3";
private static final String EVENT_CACHE_MANAGER_NAME = "mqttAuthorizationCacheManager";
private static final String EVENT_CACHE_NAME = "mqttAuthorizationCache";
public static final String DAS_ADMIN_SERVICE_EP = "https://" + DAS_HOST_NAME + ":" + DAS_PORT + "/services/";
private static SSLContext sslContext;
private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class);
private static KeyStore keyStore;
private static KeyStore trustStore;
private static char[] keyStorePassword;
static {
String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password");
String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Password");
String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location");
String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Location");
//Call to load the keystore.
try {
loadKeyStore(keyStoreLocation, keyStorePassword);
//Call to load the TrustStore.
loadTrustStore(trustStoreLocation, trustStorePassword);
//Create the SSL context with the loaded TrustStore/keystore.
initSSLConnection();
} catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException
| UnrecoverableKeyException | KeyManagementException e) {
log.error("publishing dynamic event receiver is failed due to " + e.getMessage(), e);
}
}
public static int getNotifierFrequency(PlatformConfiguration tenantConfiguration) {
List<ConfigurationEntry> configEntryList = tenantConfiguration.getConfiguration();
@ -115,6 +196,30 @@ public class DeviceMgtAPIUtils {
return deviceManagementProviderService;
}
public static DeviceTypeGeneratorService getDeviceTypeGeneratorService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceTypeGeneratorService deviceTypeGeneratorService =
(DeviceTypeGeneratorService) ctx.getOSGiService(DeviceTypeGeneratorService.class, null);
if (deviceTypeGeneratorService == null) {
String msg = "DeviceTypeGeneratorService service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return deviceTypeGeneratorService;
}
public static boolean isValidDeviceIdentifier(DeviceIdentifier deviceIdentifier) throws DeviceManagementException {
Device device = getDeviceManagementService().getDevice(deviceIdentifier);
if (device == null || device.getDeviceIdentifier() == null ||
device.getDeviceIdentifier().isEmpty() || device.getEnrolmentInfo() == null) {
return false;
} else if (EnrolmentInfo.Status.REMOVED.equals(device.getEnrolmentInfo().getStatus())) {
return false;
}
return true;
}
public static UserStoreCountRetriever getUserStoreCountRetrieverService()
throws UserStoreCounterException {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
@ -367,4 +472,212 @@ public class DeviceMgtAPIUtils {
return username;
}
public static EventsPublisherService getEventPublisherService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
EventsPublisherService eventsPublisherService =
(EventsPublisherService) ctx.getOSGiService(EventsPublisherService.class, null);
if (eventsPublisherService == null) {
String msg = "Event Publisher service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return eventsPublisherService;
}
public static String getStreamDefinition(String deviceType, String tenantDomain) {
return STREAM_DEFINITION_PREFIX + tenantDomain + "." + deviceType.replace(" ", ".");
}
public static EventStreamAdminServiceStub getEventStreamAdminServiceStub()
throws AxisFault, UserStoreException, JWTClientException {
EventStreamAdminServiceStub eventStreamAdminServiceStub = new EventStreamAdminServiceStub(
Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_STREAM_CONTEXT));
Options streamOptions = eventStreamAdminServiceStub._getServiceClient().getOptions();
if (streamOptions == null) {
streamOptions = new Options();
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName() + "@" + tenantDomain;
JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient();
String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
jwtClient.getJwtToken(username).getBytes()));
List<Header> list = new ArrayList<>();
Header httpHeader = new Header();
httpHeader.setName(AUTHORIZATION_HEADER);
httpHeader.setValue(authValue);
list.add(httpHeader);//"https"
streamOptions.setProperty(HTTPConstants.HTTP_HEADERS, list);
streamOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER
, new Protocol(DEFAULT_HTTP_PROTOCOL
, (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext)
, Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT))));
eventStreamAdminServiceStub._getServiceClient().setOptions(streamOptions);
return eventStreamAdminServiceStub;
}
public static EventReceiverAdminServiceStub getEventReceiverAdminServiceStub()
throws AxisFault, UserStoreException, JWTClientException {
EventReceiverAdminServiceStub receiverAdminServiceStub = new EventReceiverAdminServiceStub(
Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_RECIEVER_CONTEXT));
Options eventReciverOptions = receiverAdminServiceStub._getServiceClient().getOptions();
if (eventReciverOptions == null) {
eventReciverOptions = new Options();
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName() + "@" + tenantDomain;
JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient();
String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
jwtClient.getJwtToken(username).getBytes()));
List<Header> list = new ArrayList<>();
Header httpHeader = new Header();
httpHeader.setName(AUTHORIZATION_HEADER);
httpHeader.setValue(authValue);
list.add(httpHeader);
eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list);
eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER
, new Protocol(DEFAULT_HTTP_PROTOCOL
, (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext)
, Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT))));
receiverAdminServiceStub._getServiceClient().setOptions(eventReciverOptions);
return receiverAdminServiceStub;
}
public static EventPublisherAdminServiceStub getEventPublisherAdminServiceStub()
throws AxisFault, UserStoreException, JWTClientException {
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = new EventPublisherAdminServiceStub(
Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PUBLISHER_CONTEXT));
Options eventReciverOptions = eventPublisherAdminServiceStub._getServiceClient().getOptions();
if (eventReciverOptions == null) {
eventReciverOptions = new Options();
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName() + "@" + tenantDomain;
JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient();
String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
jwtClient.getJwtToken(username).getBytes()));
List<Header> list = new ArrayList<>();
Header httpHeader = new Header();
httpHeader.setName(AUTHORIZATION_HEADER);
httpHeader.setValue(authValue);
list.add(httpHeader);
eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list);
eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER
, new Protocol(DEFAULT_HTTP_PROTOCOL
, (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext)
, Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT))));
eventPublisherAdminServiceStub._getServiceClient().setOptions(eventReciverOptions);
return eventPublisherAdminServiceStub;
}
public static EventStreamPersistenceAdminServiceStub getEventStreamPersistenceAdminServiceStub()
throws AxisFault, UserStoreException, JWTClientException {
EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub
= new EventStreamPersistenceAdminServiceStub(
Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PERSISTENCE_CONTEXT));
Options eventReciverOptions = eventStreamPersistenceAdminServiceStub._getServiceClient().getOptions();
if (eventReciverOptions == null) {
eventReciverOptions = new Options();
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName() + "@" + tenantDomain;
JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient();
String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
jwtClient.getJwtToken(username).getBytes()));
List<Header> list = new ArrayList<>();
Header httpHeader = new Header();
httpHeader.setName(AUTHORIZATION_HEADER);
httpHeader.setValue(authValue);
list.add(httpHeader);
eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list);
eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER
, new Protocol(DEFAULT_HTTP_PROTOCOL
, (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext)
, Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT))));
eventStreamPersistenceAdminServiceStub._getServiceClient().setOptions(eventReciverOptions);
return eventStreamPersistenceAdminServiceStub;
}
/**
* This method is used to create the Cache that holds the event definition of the device type..
* @return Cachemanager
*/
public static synchronized Cache<String, EventAttributeList> getDynamicEventCache() {
return Caching.getCacheManagerFactory().getCacheManager(EVENT_CACHE_MANAGER_NAME).getCache(EVENT_CACHE_NAME);
}
/**
* Loads the keystore.
*
* @param keyStorePath - the path of the keystore
* @param ksPassword - the keystore password
*/
private static void loadKeyStore(String keyStorePath, String ksPassword)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
InputStream fis = null;
try {
keyStorePassword = ksPassword.toCharArray();
keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
fis = new FileInputStream(keyStorePath);
keyStore.load(fis, keyStorePassword);
} finally {
if (fis != null) {
fis.close();
}
}
}
/**
* Loads the trustore
*
* @param trustStorePath - the trustore path in the filesystem.
* @param tsPassword - the truststore password
*/
private static void loadTrustStore(String trustStorePath, String tsPassword)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
InputStream fis = null;
try {
trustStore = KeyStore.getInstance(TRUST_STORE_TYPE);
fis = new FileInputStream(trustStorePath);
trustStore.load(fis, tsPassword.toCharArray());
} finally {
if (fis != null) {
fis.close();
}
}
}
/**
* Initializes the SSL Context
*/
private static void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException,
KeyStoreException, KeyManagementException {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE);
keyManagerFactory.init(keyStore, keyStorePassword);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE);
trustManagerFactory.init(trustStore);
// Create and initialize SSLContext for HTTPS communication
sslContext = SSLContext.getInstance(SSLV3);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(sslContext);
}
}

@ -29,6 +29,7 @@
<ref bean="deviceManagementAdminService"/>
<ref bean="deviceAccessAuthorizationAdminService"/>
<ref bean="deviceTypeManagementService"/>
<ref bean="configurationManagementService"/>
<ref bean="activityProviderService"/>
<ref bean="notificationManagementService"/>
<ref bean="policyManagementService"/>
@ -40,8 +41,9 @@
<ref bean="groupManagementAdminService"/>
<ref bean="applicationManagementAdminService"/>
<ref bean="deviceTypeManagementAdminService"/>
<ref bean="deviceTypeManagementAdminService"/>
<ref bean="deviceAnalyticsArtifactUploaderAdminService"/>
<ref bean="deviceAnalyticsArtifactUploaderAdminService"/>
<ref bean="deviceEventManagementService"/>
<ref bean="deviceAgentService"/>
<ref bean="swaggerResource"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
@ -70,7 +72,8 @@
</bean>
<bean id="deviceManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceManagementServiceImpl"/>
<bean id="deviceTypeManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.ConfigurationServiceImpl"/>
<bean id="deviceTypeManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceTypeManagementServiceImpl"/>
<bean id="configurationManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.ConfigurationServiceImpl"/>
<bean id="activityProviderService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.ActivityProviderServiceImpl"/>
<bean id="notificationManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.NotificationManagementServiceImpl"/>
<bean id="policyManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.PolicyManagementServiceImpl"/>
@ -82,10 +85,11 @@
<bean id="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/>
<bean id="groupManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.GroupManagementAdminServiceImpl"/>
<bean id="userManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.UserManagementAdminServiceImpl"/>
<bean id="deviceTypeManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceTypeManagementServiceImpl"/>
<bean id="deviceTypeManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceTypeManagementAdminServiceImpl"/>
<bean id="deviceAccessAuthorizationAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceAccessAuthorizationAdminServiceImpl"/>
<bean id="deviceAnalyticsArtifactUploaderAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceAnalyticsArtifactUploaderAdminServiceImpl"/>
<bean id="deviceEventManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceEventManagementServiceImpl"/>
<bean id="deviceAgentService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceAgentServiceImpl"/>
<bean id="jsonProvider" class="org.wso2.carbon.device.mgt.jaxrs.common.GsonMessageBodyHandler"/>
<!--<bean id="errorHandler" class="org.wso2.carbon.device.mgt.jaxrs.common.ErrorHandler"/>-->

@ -30,7 +30,7 @@ public class Device implements Serializable {
private static final long serialVersionUID = 1998101711L;
@ApiModelProperty(name = "id", value = "ID of the device in the WSO2 EMM device information database.",
@ApiModelProperty(name = "id", value = "ID of the device in the device information database.",
required = true)
private int id;

@ -56,7 +56,7 @@ public class DeviceIdentifier implements Serializable{
}
public void setType(String type) {
this.type = type.toLowerCase();
this.type = type.trim();
}
public String getId() {
return id;
@ -73,4 +73,4 @@ public class DeviceIdentifier implements Serializable{
", type='" + type + '\'' +
'}';
}
}
}

@ -16,10 +16,10 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp;
package org.wso2.carbon.device.mgt.common;
/**
* This exception is thrown whether the xmpp configured with invalid configuration.
* This exception is thrown when configured with invalid configuration.
*/
public class InvalidConfigurationException extends RuntimeException {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2017, 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
@ -16,30 +16,29 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt;
package org.wso2.carbon.device.mgt.common.pull.notification;
/**
* This exception is thrown whether the mqtt configured with invalid configuration.
*/
public class InvalidConfigurationException extends RuntimeException {
public class PullNotificationExecutionFailedException extends Exception {
private static final long serialVersionUID = -3151279311923070297L;
public InvalidConfigurationException(String msg, Exception nestedEx) {
public PullNotificationExecutionFailedException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public InvalidConfigurationException(String message, Throwable cause) {
public PullNotificationExecutionFailedException(String message, Throwable cause) {
super(message, cause);
}
public InvalidConfigurationException(String msg) {
public PullNotificationExecutionFailedException(String msg) {
super(msg);
}
public InvalidConfigurationException() {
public PullNotificationExecutionFailedException() {
super();
}
public InvalidConfigurationException(Throwable cause) {
public PullNotificationExecutionFailedException(Throwable cause) {
super(cause);
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2017, 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.common.pull.notification;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.util.Map;
/**
* This will handle the execution flow when a device sends a payload to IoT Server.
*/
public interface PullNotificationSubscriber {
void init(Map<String, String> properties);
void execute(DeviceIdentifier deviceIdentifier, Operation operation) throws PullNotificationExecutionFailedException;
void clean();
}

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.common.spi;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
/**
@ -47,6 +48,8 @@ public interface DeviceManagementService {
InitialOperationConfig getInitialOperationConfig();
PullNotificationSubscriber getPullNotificationSubscriber();
DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig();
}

@ -0,0 +1,13 @@
package org.wso2.carbon.device.mgt.common.spi;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
/**
* This implementation populates device management service.
*/
public interface DeviceTypeGeneratorService {
DeviceManagementService populateDeviceManagementService(String deviceTypeName
, DeviceTypeMetaDefinition deviceTypeMetaDefinition);
}

@ -0,0 +1,25 @@
/*
* 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.common.type.mgt;
public interface DeviceTypeDefinitionProvider {
DeviceTypeMetaDefinition getDeviceTypeMetaDefinition();
}

@ -0,0 +1,86 @@
package org.wso2.carbon.device.mgt.common.type.mgt;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import java.util.List;
public class DeviceTypeMetaDefinition {
private List<String> properties;
private List<Feature> features;
private boolean claimable;
private PushNotificationConfig pushNotificationConfig;
private boolean policyMonitoringEnabled;
private InitialOperationConfig initialOperationConfig;
private License license;
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<String> getProperties() {
return properties;
}
public void setProperties(List<String> properties) {
this.properties = properties;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
public boolean isClaimable() {
return claimable;
}
public void setClaimable(boolean isClaimable) {
this.claimable = isClaimable;
}
public PushNotificationConfig getPushNotificationConfig() {
return pushNotificationConfig;
}
public void setPushNotificationConfig(
PushNotificationConfig pushNotificationConfig) {
this.pushNotificationConfig = pushNotificationConfig;
}
public boolean isPolicyMonitoringEnabled() {
return policyMonitoringEnabled;
}
public void setPolicyMonitoringEnabled(boolean policyMonitoringEnabled) {
this.policyMonitoringEnabled = policyMonitoringEnabled;
}
public InitialOperationConfig getInitialOperationConfig() {
return initialOperationConfig;
}
public void setInitialOperationConfig(InitialOperationConfig initialOperationConfig) {
this.initialOperationConfig = initialOperationConfig;
}
public License getLicense() {
return license;
}
public void setLicense(License license) {
this.license = license;
}
}

@ -17,11 +17,14 @@
*/
package org.wso2.carbon.device.mgt.core;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.core.dto.DeviceManagementServiceHolder;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
@ -30,6 +33,8 @@ import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationProvider;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeDefinitionProvider;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
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.dto.DeviceType;
@ -52,19 +57,20 @@ import java.util.Map;
public class DeviceManagementPluginRepository implements DeviceManagerStartupListener {
private Map<DeviceTypeIdentifier, DeviceManagementService> providers;
private Map<DeviceTypeServiceIdentifier, DeviceManagementServiceHolder> providers;
private boolean isInitiated;
private static final Log log = LogFactory.getLog(DeviceManagementPluginRepository.class);
private OperationManagerRepository operationManagerRepository;
private static final long DEFAULT_UPDATE_TIMESTAMP = 900000L;
public DeviceManagementPluginRepository() {
this.operationManagerRepository = new OperationManagerRepository();
providers = Collections.synchronizedMap(new HashMap<DeviceTypeIdentifier, DeviceManagementService>());
providers = Collections.synchronizedMap(new HashMap<DeviceTypeServiceIdentifier, DeviceManagementServiceHolder>());
DeviceManagementServiceComponent.registerStartupListener(this);
}
public void addDeviceManagementProvider(DeviceManagementService provider) throws DeviceManagementException {
String deviceType = provider.getType().toLowerCase();
String deviceType = provider.getType();
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
String tenantDomain = provisioningConfig.getProviderTenantDomain();
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
@ -77,10 +83,29 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
if (isInitiated) {
/* Initializing Device Management Service Provider */
provider.init();
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants);
DeviceTypeMetaDefinition deviceTypeDefinition = null;
if (provider instanceof DeviceTypeDefinitionProvider) {
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(
provider.getType());
DeviceManagementServiceHolder existingProvider = providers.get(deviceTypeIdentifier);
deviceTypeDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMetaDefinition();
if (existingProvider != null && !(existingProvider.getDeviceManagementService()
instanceof DeviceTypeDefinitionProvider)) {
throw new DeviceManagementException("Definition of device type " + provider.getType()
+ " is already available through sharing.");
}
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(provider.getType(), tenantId);
existingProvider = providers.get(deviceTypeIdentifier);
if (existingProvider != null) {
removeDeviceManagementProvider(provider);
}
}
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants, deviceTypeDefinition);
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType,
provider.getDeviceManager().
requireDeviceAuthorization());
provider.getDeviceManager()
.requireDeviceAuthorization());
registerPushNotificationStrategy(provider);
registerMonitoringTask(provider);
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
@ -88,40 +113,45 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
registerDeviceStatusMonitoringTask(deviceTypeObj, provider);
}
}
DeviceManagementServiceHolder deviceManagementServiceHolder = new DeviceManagementServiceHolder(provider);
if (isSharedWithAllTenants) {
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType);
providers.put(deviceTypeIdentifier, provider);
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType);
providers.put(deviceTypeIdentifier, deviceManagementServiceHolder);
} else {
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType, tenantId);
providers.put(deviceTypeIdentifier, provider);
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType, tenantId);
providers.put(deviceTypeIdentifier, deviceManagementServiceHolder);
}
}
}
public void removeDeviceManagementProvider(DeviceManagementService provider)
throws DeviceManagementException {
String deviceTypeName = provider.getType().toLowerCase();
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
DeviceTypeIdentifier deviceTypeIdentifier;
String deviceTypeName = provider.getType();
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig();
DeviceTypeServiceIdentifier deviceTypeIdentifier;
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
if (provisioningConfig.isSharedWithAllTenants()) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName);
providers.remove(deviceTypeIdentifier);
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName);
} else {
int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName, providerTenantId);
providers.remove(deviceTypeIdentifier);
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName, providerTenantId);
}
PullNotificationSubscriber pullNotificationSubscriber = provider.getPullNotificationSubscriber();
if (pullNotificationSubscriber != null) {
pullNotificationSubscriber.clean();
}
providers.remove(deviceTypeIdentifier);
unregisterPushNotificationStrategy(deviceTypeIdentifier);
unregisterMonitoringTask(provider);
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
DeviceType deviceTypeObj = DeviceManagerUtil.getDeviceType(deviceTypeIdentifier.getDeviceType(),
deviceTypeIdentifier.getTenantId());
deviceTypeIdentifier.getTenantId());
unregisterDeviceStatusMonitoringTask(deviceTypeObj, provider);
}
}
private void unregisterPushNotificationStrategy(DeviceTypeIdentifier deviceTypeIdentifier) {
private void unregisterPushNotificationStrategy(DeviceTypeServiceIdentifier deviceTypeIdentifier) {
OperationManager operationManager = operationManagerRepository.getOperationManager(
deviceTypeIdentifier);
if (operationManager != null) {
@ -135,20 +165,82 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
public DeviceManagementService getDeviceManagementService(String type, int tenantId) {
//Priority need to be given to the tenant before public.
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(type.toLowerCase(), tenantId);
DeviceManagementService provider = providers.get(deviceTypeIdentifier);
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type, tenantId);
DeviceManagementServiceHolder provider = providers.get(deviceTypeIdentifier);
if (provider == null) {
deviceTypeIdentifier = new DeviceTypeIdentifier(type.toLowerCase());
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type);
provider = providers.get(deviceTypeIdentifier);
if (provider == null) {
try {
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type, tenantId);
if (deviceType == null) {
return null;
}
DeviceTypeMetaDefinition deviceTypeMetaDefinition = deviceType.getDeviceTypeMetaDefinition();
if (deviceTypeMetaDefinition != null) {
DeviceManagementService deviceTypeManagerService = DeviceManagementDataHolder.getInstance()
.getDeviceTypeGeneratorService().populateDeviceManagementService(type, deviceTypeMetaDefinition);
if (deviceTypeManagerService == null) {
log.error("Failing to retrieve the device type service for " + type);
return null;
}
addDeviceManagementProvider(deviceTypeManagerService);
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type, tenantId);
provider = providers.get(deviceTypeIdentifier);
}
} catch (DeviceManagementException e) {
log.error("Failing to retrieve the device type service for " + type, e);
return null;
}
}
if (provider == null) {
log.error("Device Type Definition not found for " + type);
return null;
}
} else {
// retrieves per tenant device type management service
if (provider.getDeviceManagementService() instanceof DeviceTypeDefinitionProvider) {
//handle updates.
long updatedTimestamp = provider.getTimestamp();
if (System.currentTimeMillis() - updatedTimestamp > DEFAULT_UPDATE_TIMESTAMP) {
try {
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type,tenantId);
DeviceTypeMetaDefinition deviceTypeMetaDefinition = deviceType.getDeviceTypeMetaDefinition();
if (deviceTypeMetaDefinition != null) {
Gson gson = new Gson();
String dbStoredDefinition = gson.toJson(deviceTypeMetaDefinition);
deviceTypeMetaDefinition = ((DeviceTypeDefinitionProvider)
provider.getDeviceManagementService()).getDeviceTypeMetaDefinition();
String cachedDefinition = gson.toJson(deviceTypeMetaDefinition);
if (!cachedDefinition.equals(dbStoredDefinition)) {
DeviceManagementService deviceTypeManagerService = DeviceManagementDataHolder.getInstance()
.getDeviceTypeGeneratorService().populateDeviceManagementService(type, deviceTypeMetaDefinition);
if (deviceTypeManagerService == null) {
log.error("Failing to retrieve the device type service for " + type);
return null;
}
addDeviceManagementProvider(deviceTypeManagerService);
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(type, tenantId);
provider = providers.get(deviceTypeIdentifier);
} else {
provider.setTimestamp(System.currentTimeMillis());
}
}
} catch (DeviceManagementException e) {
log.error("Failing to retrieve the device type service for " + type, e);
return null;
}
}
}
}
return provider;
return provider.getDeviceManagementService();
}
public Map<DeviceTypeIdentifier, DeviceManagementService> getAllDeviceManagementServices(int tenantId) {
Map<DeviceTypeIdentifier, DeviceManagementService> tenantProviders = new HashMap<>();
for (DeviceTypeIdentifier identifier : providers.keySet()) {
public Map<DeviceTypeServiceIdentifier, DeviceManagementService> getAllDeviceManagementServices(int tenantId) {
Map<DeviceTypeServiceIdentifier, DeviceManagementService> tenantProviders = new HashMap<>();
for (DeviceTypeServiceIdentifier identifier : providers.keySet()) {
if (identifier.getTenantId() == tenantId || identifier.isSharedWithAllTenant()) {
tenantProviders.put(identifier, providers.get(identifier));
tenantProviders.put(identifier, providers.get(identifier).getDeviceManagementService());
}
}
return tenantProviders;
@ -162,12 +254,12 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
deviceManagementService.getProvisioningConfig().getProviderTenantDomain(), true);
try {
boolean isSharedWithAllTenants = deviceManagementService.getProvisioningConfig().isSharedWithAllTenants();
DeviceTypeIdentifier deviceTypeIdentifier;
DeviceTypeServiceIdentifier deviceTypeIdentifier;
if (isSharedWithAllTenants) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType());
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceManagementService.getType());
} else {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType(), tenantId);
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceManagementService.getType(), tenantId);
}
if (pushNoteConfig != null) {
@ -268,10 +360,13 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
public OperationManager getOperationManager(String deviceType, int tenantId) {
//Priority need to be given to the tenant before public.
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType.toLowerCase(), tenantId);
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType, tenantId);
if (getDeviceManagementService(deviceType, tenantId) == null) {
return null;
}
OperationManager operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
if (operationManager == null) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType.toLowerCase());
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceType);
operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
}
return operationManager;
@ -281,14 +376,26 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
public void notifyObserver() {
String deviceTypeName;
synchronized (providers) {
for (DeviceManagementService provider : providers.values()) {
for (DeviceManagementServiceHolder deviceManagementServiceHolder : providers.values()) {
DeviceManagementService provider= deviceManagementServiceHolder.getDeviceManagementService();
try {
provider.init();
deviceTypeName = provider.getType().toLowerCase();
deviceTypeName = provider.getType();
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
int tenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
DeviceManagerUtil.registerDeviceType(deviceTypeName, tenantId,
provisioningConfig.isSharedWithAllTenants());
DeviceTypeMetaDefinition deviceTypeDefinition = null;
if (provider instanceof DeviceTypeDefinitionProvider) {
deviceTypeDefinition = ((DeviceTypeDefinitionProvider) provider).getDeviceTypeMetaDefinition();
DeviceTypeServiceIdentifier deviceTypeIdentifier = new DeviceTypeServiceIdentifier(
provider.getType(), tenantId);
DeviceManagementServiceHolder existingProvider = providers.get(deviceTypeIdentifier);
if (existingProvider != null) {
removeDeviceManagementProvider(provider);
}
}
DeviceManagerUtil.registerDeviceType(deviceTypeName, tenantId
, provisioningConfig.isSharedWithAllTenants(), deviceTypeDefinition);
registerPushNotificationStrategy(provider);
registerMonitoringTask(provider);

@ -22,6 +22,7 @@ import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
import org.wso2.carbon.device.mgt.core.config.pagination.PaginationConfiguration;
import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration;
import org.wso2.carbon.device.mgt.core.config.pull.notification.PullNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.status.task.DeviceStatusTaskConfig;
import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration;
@ -42,6 +43,7 @@ public final class DeviceManagementConfig {
private PolicyConfiguration policyConfiguration;
private PaginationConfiguration paginationConfiguration;
private PushNotificationConfiguration pushNotificationConfiguration;
private PullNotificationConfiguration pullNotificationConfiguration;
private DeviceStatusTaskConfig deviceStatusTaskConfig;
private DeviceCacheConfiguration deviceCacheConfiguration;
private GeoLocationConfiguration geoLocationConfiguration;
@ -101,6 +103,15 @@ public final class DeviceManagementConfig {
this.pushNotificationConfiguration = pushNotificationConfiguration;
}
@XmlElement(name = "PullNotificationConfiguration", required = true)
public PullNotificationConfiguration getPullNotificationConfiguration() {
return pullNotificationConfiguration;
}
public void setPullNotificationConfiguration(PullNotificationConfiguration pullNotificationConfiguration) {
this.pullNotificationConfiguration = pullNotificationConfiguration;
}
@XmlElement(name = "DeviceStatusTaskConfig", required = true)
public DeviceStatusTaskConfig getDeviceStatusTaskConfig() {
return deviceStatusTaskConfig;

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017, 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.core.config.pull.notification;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class is for Pull notification related Configurations
*/
@XmlRootElement(name = "PullNotificationConfiguration")
public class PullNotificationConfiguration {
private boolean enabled;
@XmlElement(name = "Enabled", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

@ -55,7 +55,7 @@ public interface DeviceTypeDAO {
* @return return only the device types that are associated with the provider tenant.
* @throws DeviceManagementDAOException
*/
List<String> getDeviceTypesByProvider(int tenantId) throws DeviceManagementDAOException;
List<DeviceType> getDeviceTypesByProvider(int tenantId) throws DeviceManagementDAOException;
/**
* @return sharedWithAllDeviceTypes This returns public shared device types.

@ -121,7 +121,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
@ -154,7 +154,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?" ;
stmt = conn.prepareStatement(sql);
int paramIdx = 1;
@ -189,7 +189,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? AND e.STATUS = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
@ -223,7 +223,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND d.DEVICE_IDENTIFICATION = ? ) d1 WHERE d1.ID = e.DEVICE_ID ORDER BY e.DATE_OF_LAST_UPDATE DESC";
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? ) d1 WHERE d1.ID = e.DEVICE_ID ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
@ -253,7 +253,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"d.ID = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"d.ID = ? AND t.ID = d.DEVICE_TYPE_ID AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
@ -317,7 +317,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, " +
"d.NAME, d.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND t.NAME = ? " +
"AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
"AND t.ID = d.DEVICE_TYPE_ID AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, type);
stmt.setInt(2, tenantId);

@ -17,6 +17,8 @@
*/
package org.wso2.carbon.device.mgt.core.dao.impl;
import com.google.gson.Gson;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO;
@ -27,7 +29,9 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DeviceTypeDAOImpl implements DeviceTypeDAO {
@ -40,10 +44,18 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
try {
conn = this.getConnection();
stmt = conn.prepareStatement(
"INSERT INTO DM_DEVICE_TYPE (NAME,PROVIDER_TENANT_ID,SHARED_WITH_ALL_TENANTS) VALUES (?,?,?)");
"INSERT INTO DM_DEVICE_TYPE (NAME,PROVIDER_TENANT_ID,SHARED_WITH_ALL_TENANTS,DEVICE_TYPE_META" +
",LAST_UPDATED_TIMESTAMP) VALUES (?,?,?,?,?)");
stmt.setString(1, deviceType.getName());
stmt.setInt(2, providerTenantId);
stmt.setBoolean(3, isSharedWithAllTenants);
String deviceMeta = null;
if (deviceType.getDeviceTypeMetaDefinition() != null) {
Gson gson = new Gson();
deviceMeta = gson.toJson(deviceType.getDeviceTypeMetaDefinition());
}
stmt.setString(4, deviceMeta);
stmt.setTimestamp(5, new Timestamp(new Date().getTime()));
stmt.execute();
} catch (SQLException e) {
throw new DeviceManagementDAOException(
@ -54,8 +66,29 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
}
@Override
public void updateDeviceType(DeviceType deviceType, int tenantId)
throws DeviceManagementDAOException {
public void updateDeviceType(DeviceType deviceType, int tenantId) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
stmt = conn.prepareStatement("UPDATE DM_DEVICE_TYPE SET DEVICE_TYPE_META = ?, LAST_UPDATED_TIMESTAMP = ? " +
"WHERE NAME = ? AND PROVIDER_TENANT_ID = ?");
String deviceMeta = null;
if (deviceType.getDeviceTypeMetaDefinition() != null) {
Gson gson = new Gson();
deviceMeta = gson.toJson(deviceType.getDeviceTypeMetaDefinition());
}
stmt.setString(1, deviceMeta);
stmt.setTimestamp(2, new Timestamp(new Date().getTime()));
stmt.setString(3, deviceType.getName());
stmt.setInt(4, tenantId);
stmt.execute();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while updating device type'" +
deviceType.getName() + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, null);
}
}
@Override
@ -67,8 +100,8 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
try {
conn = this.getConnection();
String sql =
"SELECT ID AS DEVICE_TYPE_ID, NAME AS DEVICE_TYPE FROM DM_DEVICE_TYPE where PROVIDER_TENANT_ID =" +
"? OR SHARED_WITH_ALL_TENANTS = ?";
"SELECT ID AS DEVICE_TYPE_ID, NAME AS DEVICE_TYPE, DEVICE_TYPE_META,LAST_UPDATED_TIMESTAMP " +
"FROM DM_DEVICE_TYPE where PROVIDER_TENANT_ID =? OR SHARED_WITH_ALL_TENANTS = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setBoolean(2, true);
@ -78,6 +111,12 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
DeviceType deviceType = new DeviceType();
deviceType.setId(rs.getInt("DEVICE_TYPE_ID"));
deviceType.setName(rs.getString("DEVICE_TYPE"));
String devicetypeMeta = rs.getString("DEVICE_TYPE_META");
if (devicetypeMeta != null && devicetypeMeta.length() > 0) {
Gson gson = new Gson();
deviceType.setDeviceTypeMetaDefinition(gson.fromJson(devicetypeMeta
, DeviceTypeMetaDefinition.class));
}
deviceTypes.add(deviceType);
}
return deviceTypes;
@ -89,21 +128,30 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
}
@Override
public List<String> getDeviceTypesByProvider(int tenantId) throws DeviceManagementDAOException {
public List<DeviceType> getDeviceTypesByProvider(int tenantId) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<String> deviceTypes = new ArrayList<>();
List<DeviceType> deviceTypes = new ArrayList<>();
try {
conn = this.getConnection();
String sql =
"SELECT NAME AS DEVICE_TYPE FROM DM_DEVICE_TYPE where PROVIDER_TENANT_ID =?";
"SELECT NAME AS DEVICE_TYPE, DEVICE_TYPE_META FROM DM_DEVICE_TYPE where PROVIDER_TENANT_ID =?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
rs = stmt.executeQuery();
while (rs.next()) {
deviceTypes.add(rs.getString("DEVICE_TYPE"));
DeviceType deviceType = new DeviceType();
deviceType.setName(rs.getString("DEVICE_TYPE"));
String devicetypeMeta = rs.getString("DEVICE_TYPE_META");
if (devicetypeMeta != null && devicetypeMeta.length() > 0) {
Gson gson = new Gson();
deviceType.setDeviceTypeMetaDefinition(gson.fromJson(devicetypeMeta
, DeviceTypeMetaDefinition.class));
}
deviceTypes.add(deviceType);
}
return deviceTypes;
} catch (SQLException e) {
@ -146,7 +194,7 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
ResultSet rs = null;
try {
conn = this.getConnection();
String sql = "SELECT ID AS DEVICE_TYPE_ID, NAME AS DEVICE_TYPE FROM DM_DEVICE_TYPE WHERE ID = ?";
String sql = "SELECT ID AS DEVICE_TYPE_ID, DEVICE_TYPE_META, NAME AS DEVICE_TYPE FROM DM_DEVICE_TYPE WHERE ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, id);
rs = stmt.executeQuery();
@ -155,6 +203,13 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
deviceType = new DeviceType();
deviceType.setId(rs.getInt("DEVICE_TYPE_ID"));
deviceType.setName(rs.getString("DEVICE_TYPE"));
String devicetypeMeta = rs.getString("DEVICE_TYPE_META");
if (devicetypeMeta != null && devicetypeMeta.length() > 0) {
Gson gson = new Gson();
deviceType.setDeviceTypeMetaDefinition(gson.fromJson(devicetypeMeta
, DeviceTypeMetaDefinition.class));
}
}
return deviceType;
} catch (SQLException e) {
@ -174,7 +229,7 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
DeviceType deviceType = null;
try {
conn = this.getConnection();
String sql = "SELECT ID AS DEVICE_TYPE_ID FROM DM_DEVICE_TYPE WHERE (PROVIDER_TENANT_ID =? OR " +
String sql = "SELECT ID AS DEVICE_TYPE_ID, DEVICE_TYPE_META FROM DM_DEVICE_TYPE WHERE (PROVIDER_TENANT_ID =? OR " +
"SHARED_WITH_ALL_TENANTS = ?) AND NAME =?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
@ -185,6 +240,12 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO {
deviceType = new DeviceType();
deviceType.setId(rs.getInt("DEVICE_TYPE_ID"));
deviceType.setName(type);
String devicetypeMeta = rs.getString("DEVICE_TYPE_META");
if (devicetypeMeta != null && devicetypeMeta.length() > 0) {
Gson gson = new Gson();
deviceType.setDeviceTypeMetaDefinition(gson.fromJson(devicetypeMeta
, DeviceTypeMetaDefinition.class));
}
}
return deviceType;
} catch (SQLException e) {

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, 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.core.dto;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
/**
* This holds the information of the registered device management service against the device type
* definition loaded timestamp. This is used to handle device type update scenario.
*/
public class DeviceManagementServiceHolder {
private DeviceManagementService deviceManagementService;
private long timestamp;
public DeviceManagementServiceHolder(DeviceManagementService deviceManagementService) {
this.deviceManagementService = deviceManagementService;
this.timestamp = System.currentTimeMillis();
}
public DeviceManagementService getDeviceManagementService() {
return deviceManagementService;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}

@ -18,8 +18,11 @@
package org.wso2.carbon.device.mgt.core.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import java.io.Serializable;
@ -33,6 +36,10 @@ public class DeviceType implements Serializable {
@ApiModelProperty(name = "name", value = "Device type name", required = true)
private String name;
@JsonProperty("metaDefinition")
@ApiModelProperty(name = "metaDefinition", value = "Device type definition", required = true)
private DeviceTypeMetaDefinition deviceTypeMetaDefinition;
public DeviceType() {
}
@ -40,6 +47,7 @@ public class DeviceType implements Serializable {
this.name = name;
}
@JsonIgnore
public int getId() {
return id;
}
@ -56,4 +64,13 @@ public class DeviceType implements Serializable {
this.name = name;
}
public DeviceTypeMetaDefinition getDeviceTypeMetaDefinition() {
return deviceTypeMetaDefinition;
}
public void setDeviceTypeMetaDefinition(
DeviceTypeMetaDefinition deviceTypeMetaDefinition) {
this.deviceTypeMetaDefinition = deviceTypeMetaDefinition;
}
}

@ -15,26 +15,26 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common;
package org.wso2.carbon.device.mgt.core.dto;
import java.io.Serializable;
/**
* This class holds the information of the device type and its provider tenant.
*/
public class DeviceTypeIdentifier implements Serializable {
public class DeviceTypeServiceIdentifier implements Serializable {
private String deviceType;
private int tenantId;
private static final int DEFAULT_SHARE_WITH_ALL_TENANTS_ID = -1;
public DeviceTypeIdentifier(String deviceType, int tenantId) {
this.deviceType = deviceType.toLowerCase();
public DeviceTypeServiceIdentifier(String deviceType, int tenantId) {
this.deviceType = deviceType;
this.tenantId = tenantId;
}
public DeviceTypeIdentifier(String deviceType) {
this.deviceType = deviceType.toLowerCase();
public DeviceTypeServiceIdentifier(String deviceType) {
this.deviceType = deviceType;
this.tenantId = DEFAULT_SHARE_WITH_ALL_TENANTS_ID;
}
@ -59,8 +59,8 @@ public class DeviceTypeIdentifier implements Serializable {
@Override
public boolean equals(Object obj) {
return (obj instanceof DeviceTypeIdentifier) && deviceType.equals(
((DeviceTypeIdentifier) obj).deviceType) && tenantId == ((DeviceTypeIdentifier) obj).tenantId;
return (obj instanceof DeviceTypeServiceIdentifier) && deviceType.equals(
((DeviceTypeServiceIdentifier) obj).deviceType) && tenantId == ((DeviceTypeServiceIdentifier) obj).tenantId;
}
public boolean isSharedWithAllTenant() {

@ -19,15 +19,16 @@
package org.wso2.carbon.device.mgt.core.internal;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig;
import org.wso2.carbon.device.mgt.core.config.license.LicenseConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
@ -65,6 +66,7 @@ public class DeviceManagementDataHolder {
private PushNotificationProviderRepository pushNotificationProviderRepository;
private DeviceTaskManagerService deviceTaskManagerService;
private DeviceStatusTaskManagerService deviceStatusTaskManagerService;
private DeviceTypeGeneratorService deviceTypeGeneratorService;
private Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<DeviceType, DeviceStatusTaskPluginConfig>());
@ -244,7 +246,7 @@ public class DeviceManagementDataHolder {
this.deviceStatusTaskPluginConfigs.put(deviceType, deviceStatusTaskPluginConfig);
}
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig(DeviceTypeIdentifier deviceType) {
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig(DeviceTypeServiceIdentifier deviceType) {
return this.deviceStatusTaskPluginConfigs.get(deviceType);
}
@ -255,4 +257,13 @@ public class DeviceManagementDataHolder {
public void removeDeviceStatusTaskPluginConfig(DeviceType deviceType) {
this.deviceStatusTaskPluginConfigs.remove(deviceType);
}
public DeviceTypeGeneratorService getDeviceTypeGeneratorService() {
return deviceTypeGeneratorService;
}
public void setDeviceTypeGeneratorService(
DeviceTypeGeneratorService deviceTypeGeneratorService) {
this.deviceTypeGeneratorService = deviceTypeGeneratorService;
}
}

@ -31,6 +31,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementExcept
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagerProviderServiceImpl;
@ -108,6 +109,12 @@ import java.util.concurrent.TimeUnit;
* policy="dynamic"
* bind="setEmailSenderService"
* unbind="unsetEmailSenderService"
* @scr.reference name="device.type.generator.service"
* interface="org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService"
* cardinality="0..1"
* policy="dynamic"
* bind="setDeviceTypeGeneratorService"
* unbind="unsetDeviceTypeGeneratorService"
*/
public class DeviceManagementServiceComponent {
@ -313,7 +320,7 @@ public class DeviceManagementServiceComponent {
try {
if (log.isDebugEnabled()) {
log.debug("Setting Device Management Service Provider: '" +
deviceManagementService.getType() + "'");
deviceManagementService.getType() + "'");
}
synchronized (LOCK) {
deviceManagers.add(deviceManagementService);
@ -444,6 +451,30 @@ public class DeviceManagementServiceComponent {
}
DeviceManagementDataHolder.getInstance().setDeviceTaskManagerService(null);
}
/**
* sets DeviceTypeGeneratorService.
*
* @param deviceTypeGeneratorService An Instance of DeviceTypeGeneratorService
*/
protected void setDeviceTypeGeneratorService(DeviceTypeGeneratorService deviceTypeGeneratorService) {
if (log.isDebugEnabled()) {
log.debug("Un setting Device DeviceTypeGeneratorService");
}
DeviceManagementDataHolder.getInstance().setDeviceTypeGeneratorService(deviceTypeGeneratorService);
}
/**
* sets DeviceTypeGeneratorService.
*
* @param deviceTypeGeneratorService An Instance of DeviceTypeGeneratorService
*/
protected void unsetDeviceTypeGeneratorService(DeviceTypeGeneratorService deviceTypeGeneratorService) {
if (log.isDebugEnabled()) {
log.debug("Un setting Device DeviceTypeGeneratorService");
}
DeviceManagementDataHolder.getInstance().setDeviceTypeGeneratorService(null);
}
}

@ -194,6 +194,8 @@ public class OperationManagerImpl implements OperationManager {
if (log.isDebugEnabled()) {
log.debug("Sending push notification to " + deviceId + " from add operation method.");
}
operation.setId(operationId);
operation.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId);
notificationStrategy.execute(new NotificationContext(deviceId, operation));
operationMappingDAO.updateOperationMapping(operationId, enrolmentId, org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.COMPLETED);
} catch (PushNotificationExecutionFailedException e) {
@ -539,7 +541,7 @@ public class OperationManagerImpl implements OperationManager {
Operation.Status.valueOf(operation.getStatus().
toString()));
}
if (isUpdated && operation.getOperationResponse() != null) {
if (operation.getOperationResponse() != null) {
operationDAO.addOperationResponse(enrolmentId, operationId, operation.getOperationResponse());
}
OperationManagementDAOFactory.commitTransaction();

@ -18,7 +18,7 @@
*/
package org.wso2.carbon.device.mgt.core.operation.mgt;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import java.util.Map;
@ -26,21 +26,21 @@ import java.util.concurrent.ConcurrentHashMap;
public class OperationManagerRepository {
private Map<DeviceTypeIdentifier, OperationManager> operationManagers;
private Map<DeviceTypeServiceIdentifier, OperationManager> operationManagers;
public OperationManagerRepository() {
operationManagers = new ConcurrentHashMap<>();
}
public void addOperationManager(DeviceTypeIdentifier type, OperationManager operationManager) {
public void addOperationManager(DeviceTypeServiceIdentifier type, OperationManager operationManager) {
operationManagers.put(type, operationManager);
}
public OperationManager getOperationManager(DeviceTypeIdentifier type) {
public OperationManager getOperationManager(DeviceTypeServiceIdentifier type) {
return operationManagers.get(type);
}
public void removeOperationManager(DeviceTypeIdentifier type) {
public void removeOperationManager(DeviceTypeServiceIdentifier type) {
operationManagers.remove(type);
}

@ -178,6 +178,7 @@ public class ConfigOperationDAOImpl extends GenericOperationDAOImpl {
ois = new ObjectInputStream(bais);
configOperation = (ConfigOperation) ois.readObject();
configOperation.setStatus(status);
configOperation.setId(rs.getInt("OPERATION_ID"));
operations.add(configOperation);
}
} catch (IOException e) {

@ -32,7 +32,10 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import java.util.Date;
import java.util.HashMap;
@ -558,6 +561,32 @@ public interface DeviceManagementProviderService {
*/
boolean changeDeviceStatus(DeviceIdentifier deviceIdentifier, EnrolmentInfo.Status newStatus)
throws DeviceManagementException;
/**
* This will handle add and update of device type services.
* @param deviceManagementService
*/
void registerDeviceType(DeviceManagementService deviceManagementService) throws DeviceManagementException;
/**
* This retrieves the device type info for the given type
* @param deviceType name of the type.
* @throws DeviceManagementException
*/
DeviceType getDeviceType(String deviceType) throws DeviceManagementException;
/**
* This retrieves the device type info for the given type
* @throws DeviceManagementException
*/
List<DeviceType> getDeviceTypes() throws DeviceManagementException;
/**
* This retrieves the device pull notification payload and passes to device type pull notification subscriber.
* @throws PullNotificationExecutionFailedException
*/
void notifyPullNotificationSubscriber(DeviceIdentifier deviceIdentifier, Operation operation)
throws PullNotificationExecutionFailedException;
List<Integer> getDeviceEnrolledTenants() throws DeviceManagementException;
}

@ -28,7 +28,9 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
@ -776,7 +778,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
@Override
public List<String> getAvailableDeviceTypes() throws DeviceManagementException {
List<String> deviceTypesProvidedByTenant;
List<DeviceType> deviceTypesProvidedByTenant;
List<String> publicSharedDeviceTypesInDB;
List<String> deviceTypesResponse = new ArrayList<>();
try {
@ -784,17 +786,17 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
int tenantId = this.getTenantId();
deviceTypesProvidedByTenant = deviceTypeDAO.getDeviceTypesByProvider(tenantId);
publicSharedDeviceTypesInDB = deviceTypeDAO.getSharedDeviceTypes();
Map<DeviceTypeIdentifier, DeviceManagementService> registeredTypes =
Map<DeviceTypeServiceIdentifier, DeviceManagementService> registeredTypes =
pluginRepository.getAllDeviceManagementServices(tenantId);
Set<String> deviceTypeSetForTenant = new HashSet<>();
if (registeredTypes != null) {
if (deviceTypesProvidedByTenant != null) {
for (String deviceType : deviceTypesProvidedByTenant) {
DeviceTypeIdentifier providerKey = new DeviceTypeIdentifier(deviceType, tenantId);
if (registeredTypes.get(providerKey) != null) {
deviceTypesResponse.add(deviceType);
deviceTypeSetForTenant.add(deviceType);
for (DeviceType deviceType : deviceTypesProvidedByTenant) {
DeviceTypeServiceIdentifier providerKey = new DeviceTypeServiceIdentifier(deviceType.getName(), tenantId);
if (registeredTypes.get(providerKey) != null || deviceType.getDeviceTypeMetaDefinition() != null) {
deviceTypesResponse.add(deviceType.getName());
deviceTypeSetForTenant.add(deviceType.getName());
}
}
}
@ -802,7 +804,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
// priority to that
if (publicSharedDeviceTypesInDB != null) {
for (String deviceType : publicSharedDeviceTypesInDB) {
DeviceTypeIdentifier providerKey = new DeviceTypeIdentifier(deviceType);
DeviceTypeServiceIdentifier providerKey = new DeviceTypeServiceIdentifier(deviceType);
if (registeredTypes.get(providerKey) != null && !deviceTypeSetForTenant.contains(deviceType)) {
deviceTypesResponse.add(deviceType);
}
@ -885,15 +887,16 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
@Deprecated
public void notifyOperationToDevices(Operation operation, List<DeviceIdentifier> deviceIds)
throws DeviceManagementException {
for (DeviceIdentifier deviceId : deviceIds) {
DeviceManagementService dms =
pluginRepository.getDeviceManagementService(deviceId.getType(), this.getTenantId());
//TODO FIX THIS WITH PUSH NOTIFICATIONS
//dms.notifyOperationToDevices(operation, deviceIds);
}
// for (DeviceIdentifier deviceId : deviceIds) {
// DeviceManagementService dms =
// pluginRepository.getDeviceManagementService(deviceId.getType(), this.getTenantId());
// //TODO FIX THIS WITH PUSH NOTIFICATIONS
// //dms.notifyOperationToDevices(operation, deviceIds);
// }
}
@ -1615,6 +1618,65 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
}
@Override
public void registerDeviceType(DeviceManagementService deviceManagementService) throws DeviceManagementException {
if (deviceManagementService != null) {
pluginRepository.addDeviceManagementProvider(deviceManagementService);
}
}
@Override
public DeviceType getDeviceType(String deviceType) throws DeviceManagementException {
try {
DeviceManagementDAOFactory.openConnection();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
return deviceTypeDAO.getDeviceType(deviceType, tenantId);
} catch (DeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while obtaining the device type " + deviceType, e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while opening a connection to the data source", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override
public List<DeviceType> getDeviceTypes() throws DeviceManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
DeviceManagementDAOFactory.openConnection();
return deviceTypeDAO.getDeviceTypes(tenantId);
} catch (DeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while obtaining the device types for tenant "
+ tenantId, e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while opening a connection to the data source", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override
public void notifyPullNotificationSubscriber(DeviceIdentifier deviceIdentifier, Operation operation)
throws PullNotificationExecutionFailedException {
DeviceManagementService dms =
pluginRepository.getDeviceManagementService(deviceIdentifier.getType(), this.getTenantId());
if (dms == null) {
String message = "Device type '" + deviceIdentifier.getType() + "' does not have an associated device management " +
"plugin registered within the framework";
if (log.isDebugEnabled()) {
log.debug(message);
}
throw new PullNotificationExecutionFailedException(message);
}
PullNotificationSubscriber pullNotificationSubscriber = dms.getPullNotificationSubscriber();
if (pullNotificationSubscriber == null) {
throw new PullNotificationExecutionFailedException("Pull Notification Subscriber is not configured " +
"for device type" + deviceIdentifier.getType());
}
pullNotificationSubscriber.execute(deviceIdentifier, operation);
}
/**
* Returns all the device-info including location of the given device.
*/
@ -1727,4 +1789,4 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
private void removeDeviceFromCache(DeviceIdentifier deviceIdentifier) {
DeviceCacheManagerImpl.getInstance().removeDeviceFromCache(deviceIdentifier, this.getTenantId());
}
}
}

@ -33,6 +33,7 @@ import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.cache.DeviceCacheKey;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
@ -130,7 +131,8 @@ public final class DeviceManagerUtil {
* @param isSharedWithAllTenants is this device type shared with all tenants.
* @return status of the operation
*/
public static boolean registerDeviceType(String typeName, int tenantId, boolean isSharedWithAllTenants)
public static boolean registerDeviceType(String typeName, int tenantId, boolean isSharedWithAllTenants
, DeviceTypeMetaDefinition deviceTypeDefinition)
throws DeviceManagementException {
boolean status;
try {
@ -140,7 +142,13 @@ public final class DeviceManagerUtil {
if (deviceType == null) {
deviceType = new DeviceType();
deviceType.setName(typeName);
deviceType.setDeviceTypeMetaDefinition(deviceTypeDefinition);
deviceTypeDAO.addDeviceType(deviceType, tenantId, isSharedWithAllTenants);
} else {
if (deviceTypeDefinition != null) {
deviceType.setDeviceTypeMetaDefinition(deviceTypeDefinition);
deviceTypeDAO.updateDeviceType(deviceType, tenantId);
}
}
DeviceManagementDAOFactory.commitTransaction();
status = true;
@ -175,7 +183,7 @@ public final class DeviceManagerUtil {
throw new DeviceManagementException("Error occurred while fetching the device type '"
+ typeName + "'", e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while fetching the device type '"
throw new DeviceManagementException("SQL Error occurred while fetching the device type '"
+ typeName + "'", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
@ -528,4 +536,4 @@ public final class DeviceManagerUtil {
}
return deviceCache;
}
}
}

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
@ -77,7 +78,13 @@ public class TestDeviceManagementService implements DeviceManagementService {
return null;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return null;
}
@Override
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig() {
return null;
}
}
}

@ -1,6 +1,8 @@
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
ID INT AUTO_INCREMENT NOT NULL,
NAME VARCHAR(300) NULL DEFAULT NULL,
DEVICE_TYPE_META VARCHAR(20000) NULL DEFAULT NULL,
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL,
PROVIDER_TENANT_ID INTEGER DEFAULT 0,
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (ID)

@ -50,10 +50,6 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
<artifactId>axiom</artifactId>
@ -62,10 +58,18 @@
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
@ -77,14 +81,14 @@
<Bundle-Version>${carbon.device.mgt.version}</Bundle-Version>
<Bundle-Description>Device Management Extensions Bundle</Bundle-Description>
<Export-Package>
!org.wso2.carbon.device.mgt.extensions.internal,
org.wso2.carbon.device.mgt.extensions.*
</Export-Package>
<Import-Package>
org.wso2.carbon.governance.api.*,
javax.xml.namespace;resolution:=optional,
org.wso2.carbon.device.mgt.core.*,
org.wso2.carbon.context,
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.common.*,
org.wso2.carbon.device.mgt.common.license.mgt,
org.wso2.carbon.registry.api,
org.wso2.carbon.registry.core,
@ -93,8 +97,23 @@
org.wso2.carbon.base,
javax.xml.bind,
org.apache.commons.logging,
org.wso2.carbon.utils
org.wso2.carbon.utils,
javax.naming,
javax.sql,
javax.xml,
javax.xml.bind.annotation,
javax.xml.parsers;resolution:=optional,
org.apache.commons.lang,
org.osgi.service.component,
org.w3c.dom,
org.wso2.carbon.ndatasource.core,
org.wso2.carbon.registry.core.service,
org.wso2.carbon.utils.dbcreator,
org.wso2.carbon.utils.multitenancy,
org.osgi.framework
</Import-Package>
<DynamicImport-Package>org.wso2.carbon.device.mgt.extensions.pull.notification,
org.wso2.carbon.device.mgt.extensions.pull.notification.*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>

@ -15,7 +15,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template;
package org.wso2.carbon.device.mgt.extensions.device.type.template;
import java.io.Serializable;

@ -0,0 +1,14 @@
package org.wso2.carbon.device.mgt.extensions.device.type.template;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
public class DeviceTypeGeneratorServiceImpl implements DeviceTypeGeneratorService {
@Override
public DeviceManagementService populateDeviceManagementService(String deviceTypeName
, DeviceTypeMetaDefinition deviceTypeMetaDefinition) {
return new HTTPDeviceTypeManagerService(deviceTypeName, deviceTypeMetaDefinition);
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template;
package org.wso2.carbon.device.mgt.extensions.device.type.template;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -32,14 +32,14 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.*;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.util.DeviceTypePluginConstants;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.exception.DeviceTypeDeployerFileException;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.exception.DeviceTypeMgtPluginException;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.dao.DeviceDAODefinition;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.dao.DeviceTypePluginDAOManager;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.feature.ConfigurationBasedFeatureManager;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.util.DeviceTypeUtils;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.*;
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException;
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceDAODefinition;
import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.feature.ConfigurationBasedFeatureManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypePluginConstants;
import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils;
import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
@ -108,7 +108,7 @@ public class DeviceTypeManager implements DeviceManager {
}
} catch (LicenseManagementException e) {
String msg = "Error occurred while adding default license for " + deviceType + " devices";
throw new DeviceTypeDeployerFileException(msg, e);
throw new DeviceTypeDeployerPayloadException(msg, e);
}
claimable = false;
if (deviceTypeConfiguration.getClaimable() != null ) {
@ -120,7 +120,7 @@ public class DeviceTypeManager implements DeviceManager {
defaultPlatformConfiguration = this.getDefaultConfiguration();
} catch (DeviceManagementException e) {
String msg = "Error occurred while default platform configuration";
throw new DeviceTypeDeployerFileException(msg, e);
throw new DeviceTypeDeployerPayloadException(msg, e);
}
DeviceDetails deviceDetails = deviceTypeConfiguration.getDeviceDetails();
@ -139,7 +139,7 @@ public class DeviceTypeManager implements DeviceManager {
}
}
if (deviceDefinitionTable == null) {
throw new DeviceTypeDeployerFileException("Could not find definition for table: " + tableName);
throw new DeviceTypeDeployerPayloadException("Could not find definition for table: " + tableName);
}
propertiesExist = true;
@ -166,11 +166,17 @@ public class DeviceTypeManager implements DeviceManager {
}
deviceTypePluginDAOManager = new DeviceTypePluginDAOManager(datasourceName, deviceDAODefinition);
} else {
throw new DeviceTypeDeployerFileException("Invalid datasource name.");
throw new DeviceTypeDeployerPayloadException("Invalid datasource name.");
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} else {
if (deviceDetails.getProperties() != null && deviceDetails.getProperties().getProperty() != null
&& deviceDetails.getProperties().getProperty().size() > 0 ) {
deviceTypePluginDAOManager = new DeviceTypePluginDAOManager(deviceType, deviceDetails);
propertiesExist = true;
}
}
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template;
package org.wso2.carbon.device.mgt.extensions.device.type.template;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -31,15 +31,20 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.ConfigProperties;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.TaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceStatusTaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.policy.mgt.DefaultPolicyMonitoringManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigProperties;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceStatusTaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PolicyMonitoring;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PullNotificationSubscriberConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.TaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.policy.mgt.DefaultPolicyMonitoringManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.pull.notification.PullNotificationSubscriberLoader;
import java.util.ArrayList;
import java.util.HashMap;
@ -62,6 +67,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
private List<MonitoringOperation> monitoringOperations;
private PolicyMonitoringManager policyMonitoringManager;
private InitialOperationConfig initialOperationConfig;
private PullNotificationSubscriber pullNotificationSubscriber;
private DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig;
public DeviceTypeManagerService(DeviceTypeConfigIdentifier deviceTypeConfigIdentifier,
@ -76,9 +82,8 @@ public class DeviceTypeManagerService implements DeviceManagementService {
this.setInitialOperationConfig(deviceTypeConfiguration);
this.deviceStatusTaskPluginConfig = new DeviceStatusTaskPluginConfig();
this.setDeviceStatusTaskPluginConfig(deviceTypeConfiguration.getDeviceStatusTaskConfiguration());
if (deviceTypeConfiguration.getPolicyMonitoring() != null ) {
this.policyMonitoringManager = new DefaultPolicyMonitoringManager();
}
this.setPolicyMonitoringManager(deviceTypeConfiguration.getPolicyMonitoring());
this.setPullNotificationSubscriber(deviceTypeConfiguration.getPullNotificationSubscriberConfig());
}
@Override
@ -179,6 +184,11 @@ public class DeviceTypeManagerService implements DeviceManagementService {
return initialOperationConfig;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return pullNotificationSubscriber;
}
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig() {
return deviceStatusTaskPluginConfig;
}
@ -204,8 +214,24 @@ public class DeviceTypeManagerService implements DeviceManagementService {
protected void setInitialOperationConfig(DeviceTypeConfiguration deviceTypeConfiguration) {
if (deviceTypeConfiguration.getOperations() != null) {
List<String> ops = deviceTypeConfiguration.getOperations();
if (ops != null && !ops.isEmpty()) {
initialOperationConfig.setOperations(ops);
if (!ops.isEmpty() && deviceTypeConfiguration.getFeatures() != null
&& deviceTypeConfiguration.getFeatures().getFeature() != null) {
List<String> validOps = new ArrayList<>();
for (String operation : ops) {
boolean isFeatureExist = false;
for (Feature feature : deviceTypeConfiguration.getFeatures().getFeature()) {
if (feature.getCode().equals(operation)) {
isFeatureExist = true;
break;
}
}
if (isFeatureExist) {
validOps.add(operation);
} else {
log.warn("Couldn't fine a valid feature for the operation : " + operation);
}
}
initialOperationConfig.setOperations(validOps);
}
}
}
@ -221,4 +247,21 @@ public class DeviceTypeManagerService implements DeviceManagementService {
}
return propertMap;
}
private void setPolicyMonitoringManager(PolicyMonitoring policyMonitoring) {
if (policyMonitoring != null && policyMonitoring.isEnabled()) {
this.policyMonitoringManager = new DefaultPolicyMonitoringManager();
}
}
private void setPullNotificationSubscriber(PullNotificationSubscriberConfig pullNotificationSubscriberConfig) {
if (pullNotificationSubscriberConfig != null) {
String className = pullNotificationSubscriberConfig.getClassName();
if (className != null && !className.isEmpty()) {
PullNotificationSubscriberLoader pullNotificationSubscriberLoader = new PullNotificationSubscriberLoader
(className, pullNotificationSubscriberConfig.getConfigProperties());
this.pullNotificationSubscriber = pullNotificationSubscriberLoader.getPullNotificationSubscriber();
}
}
}
}

@ -0,0 +1,181 @@
/*
* 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.extensions.device.type.template;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeDefinitionProvider;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Claimable;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigProperties;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceDetails;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Features;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.License;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PolicyMonitoring;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Properties;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ProvisioningConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PullNotificationSubscriberConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* This inherits the capabiliy that is provided through the file based device type manager service.
* This will create and instance of device management service through a json payload.
*/
public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService implements DeviceTypeDefinitionProvider {
private DeviceTypeMetaDefinition deviceTypeMetaDefinition;
private static final String DEFAULT_PULL_NOTIFICATION_CLASS_NAME = "org.wso2.carbon.device.mgt.extensions.pull.notification.PullNotificationSubscriberImpl";
public HTTPDeviceTypeManagerService(String deviceTypeName, DeviceTypeMetaDefinition deviceTypeMetaDefinition) {
super(getDeviceTypeConfigIdentifier(deviceTypeName), getDeviceTypeConfiguration(
deviceTypeName, deviceTypeMetaDefinition));
this.deviceTypeMetaDefinition = deviceTypeMetaDefinition;
}
private static DeviceTypeConfiguration getDeviceTypeConfiguration(String deviceTypeName, DeviceTypeMetaDefinition
deviceTypeMetaDefinition) {
DeviceTypeConfiguration deviceTypeConfiguration = new DeviceTypeConfiguration();
if (deviceTypeMetaDefinition != null) {
Claimable claimable = new Claimable();
claimable.setEnabled(deviceTypeMetaDefinition.isClaimable());
deviceTypeConfiguration.setClaimable(claimable);
if (deviceTypeMetaDefinition.getProperties() != null &&
deviceTypeMetaDefinition.getProperties().size() > 0) {
DeviceDetails deviceDetails = new DeviceDetails();
Properties properties = new Properties();
properties.addProperties(deviceTypeMetaDefinition.getProperties());
deviceDetails.setProperties(properties);
deviceTypeConfiguration.setDeviceDetails(deviceDetails);
}
if (deviceTypeMetaDefinition.getFeatures() != null && deviceTypeMetaDefinition.getFeatures().size() > 0) {
Features features = new Features();
List<org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature> featureList
= new ArrayList<>();
for (Feature feature : deviceTypeMetaDefinition.getFeatures()) {
org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature configFeature = new org
.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature();
if (feature.getCode() != null && feature.getName() != null) {
configFeature.setCode(feature.getCode());
configFeature.setDescription(feature.getDescription());
configFeature.setName(feature.getName());
if (feature.getMetadataEntries() != null && feature.getMetadataEntries().size() > 0) {
List<String> metaValues = new ArrayList<>();
for (Feature.MetadataEntry metadataEntry : feature.getMetadataEntries()) {
metaValues.add(metadataEntry.getValue().toString());
}
configFeature.setMetaData(metaValues);
}
featureList.add(configFeature);
}
}
features.addFeatures(featureList);
deviceTypeConfiguration.setFeatures(features);
}
deviceTypeConfiguration.setName(deviceTypeName);
//TODO: Add it to the license management service.
// if (deviceTypeMetaDefinition.getLicense() != null) {
// License license = new License();
// license.setLanguage(deviceTypeMetaDefinition.getLicense().getLanguage());
// license.setText(deviceTypeMetaDefinition.getLicense().getText());
// license.setVersion(deviceTypeMetaDefinition.getLicense().getVersion());
// deviceTypeConfiguration.setLicense(license);
// }
PolicyMonitoring policyMonitoring = new PolicyMonitoring();
policyMonitoring.setEnabled(deviceTypeMetaDefinition.isPolicyMonitoringEnabled());
deviceTypeConfiguration.setPolicyMonitoring(policyMonitoring);
ProvisioningConfig provisioningConfig = new ProvisioningConfig();
provisioningConfig.setSharedWithAllTenants(false);
deviceTypeConfiguration.setProvisioningConfig(provisioningConfig);
PushNotificationConfig pushNotificationConfig = deviceTypeMetaDefinition.getPushNotificationConfig();
if (pushNotificationConfig != null) {
PushNotificationProvider pushNotificationProvider = new PushNotificationProvider();
pushNotificationProvider.setType(pushNotificationConfig.getType());
//default schedule value will be true.
pushNotificationProvider.setScheduled(true);
if (pushNotificationConfig.getProperties() != null &&
pushNotificationConfig.getProperties().size() > 0) {
ConfigProperties configProperties = new ConfigProperties();
List<Property> properties = new ArrayList<>();
for (Map.Entry<String, String> entry : pushNotificationConfig.getProperties().entrySet()) {
Property property = new Property();
property.setName(entry.getKey());
property.setValue(entry.getValue());
properties.add(property);
}
configProperties.addProperties(properties);
pushNotificationProvider.setConfigProperties(configProperties);
}
pushNotificationProvider.setFileBasedProperties(true);
deviceTypeConfiguration.setPushNotificationProvider(pushNotificationProvider);
}
// This is commented until the task registration handling issue is solved
// OperationMonitoringTaskConfig operationMonitoringTaskConfig = deviceTypeMetaDefinition.getTaskConfig();
// if (operationMonitoringTaskConfig != null) {
// TaskConfiguration taskConfiguration = new TaskConfiguration();
// taskConfiguration.setEnabled(operationMonitoringTaskConfig.isEnabled());
// taskConfiguration.setFrequency(operationMonitoringTaskConfig.getFrequency());
// if (operationMonitoringTaskConfig.getMonitoringOperation() != null) {
// List<TaskConfiguration.Operation> operations = new ArrayList<>();
// for (MonitoringOperation monitoringOperation : operationMonitoringTaskConfig
// .getMonitoringOperation()) {
// TaskConfiguration.Operation operation = new TaskConfiguration.Operation();
// operation.setOperationName(monitoringOperation.getTaskName());
// operation.setRecurrency(monitoringOperation.getRecurrentTimes());
// operations.add(operation);
// }
// taskConfiguration.setOperations(operations);
// }
// deviceTypeConfiguration.setTaskConfiguration(taskConfiguration);
// }
if (deviceTypeMetaDefinition.getInitialOperationConfig() != null) {
InitialOperationConfig initialOperationConfig = deviceTypeMetaDefinition.getInitialOperationConfig();
deviceTypeConfiguration.setOperations(initialOperationConfig.getOperations());
}
}
PullNotificationSubscriberConfig pullNotificationSubscriber = new PullNotificationSubscriberConfig();
pullNotificationSubscriber.setClassName(DEFAULT_PULL_NOTIFICATION_CLASS_NAME);
deviceTypeConfiguration.setPullNotificationSubscriberConfig(pullNotificationSubscriber);
return deviceTypeConfiguration;
}
private static DeviceTypeConfigIdentifier getDeviceTypeConfigIdentifier(String deviceType) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
return new DeviceTypeConfigIdentifier(deviceType, tenantDomain);
}
@Override
public DeviceTypeMetaDefinition getDeviceTypeMetaDefinition() {
return deviceTypeMetaDefinition;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import java.util.ArrayList;
import java.util.List;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import java.util.ArrayList;
import java.util.List;
@ -83,4 +83,8 @@ public class ConfigProperties {
return this.property;
}
public void addProperties(List<Property> property) {
this.property = property;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -17,7 +17,7 @@
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,13 +16,13 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
/**
@ -44,61 +44,61 @@ import javax.xml.bind.annotation.XmlValue;
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DeviceDetails", propOrder = {
"value"
"properties"
})
public class DeviceDetails {
@XmlValue
protected String value;
@XmlAttribute(name = "table-id")
protected String tableId;
@XmlElement(name = "Properties", required = true)
protected Properties properties;
/**
* Gets the value of the value property.
* Gets the value of the tableId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getValue() {
return value;
public String getTableId() {
return tableId;
}
/**
* Sets the value of the value property.
* Sets the value of the tableId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setValue(String value) {
this.value = value;
public void setTableId(String value) {
this.tableId = value;
}
/**
* Gets the value of the tableId property.
*
* Gets the value of the properties property.
*
* @return
* possible object is
* {@link String }
*
* {@link Properties }
*
*/
public String getTableId() {
return tableId;
public Properties getProperties() {
return properties;
}
/**
* Sets the value of the tableId property.
*
* Sets the value of the properties property.
*
* @param value
* allowed object is
* {@link String }
*
* {@link Properties }
*
*/
public void setTableId(String value) {
this.tableId = value;
public void setProperties(Properties value) {
this.properties = value;
}
}

@ -16,7 +16,7 @@
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@ -40,7 +40,7 @@ import java.util.List;
* &lt;element name="DeviceDetails" type="{}DeviceDetails"/>
* &lt;element name="Features" type="{}Features"/>
* &lt;element name="ProvisioningConfig" type="{}ProvisioningConfig"/>
* &lt;element name="PushNotificationProvider" type="{}PushNotificationProvider"/>
* &lt;element name="PushNotificationProviderConfig" type="{}PushNotificationProviderConfig"/>
* &lt;element name="License" type="{}License"/>
* &lt;element name="DataSource" type="{}DataSource"/>
* &lt;element name="PolicyMonitoring" type="{}PolicyMonitoring"/>
@ -65,8 +65,10 @@ public class DeviceTypeConfiguration {
protected Features features;
@XmlElement(name = "ProvisioningConfig", required = true)
protected ProvisioningConfig provisioningConfig;
@XmlElement(name = "PushNotificationProvider", required = true)
@XmlElement(name = "PushNotificationProviderConfig", required = true)
protected PushNotificationProvider pushNotificationProvider;
@XmlElement(name = "PullNotificationSubscriberConfig", required = true)
protected PullNotificationSubscriberConfig pullNotificationSubscriberConfig;
@XmlElement(name = "License", required = true)
protected License license;
@XmlElement(name = "DataSource", required = true)
@ -198,7 +200,7 @@ public class DeviceTypeConfiguration {
* @param value allowed object is
* {@link DeviceDetails }
*/
public void setDeviceDetails(PolicyMonitoring value) {
public void setPolicyMonitoring(PolicyMonitoring value) {
this.policyMonitoring = value;
}
@ -262,6 +264,26 @@ public class DeviceTypeConfiguration {
this.pushNotificationProvider = value;
}
/**
* Gets the value of the PullNotificationSubscriberConfig property.
*
* @return possible object is
* {@link PullNotificationSubscriberConfig }
*/
public PullNotificationSubscriberConfig getPullNotificationSubscriberConfig() {
return pullNotificationSubscriberConfig;
}
/**
* Sets the value of the PullNotificationSubscriberConfig property.
*
* @param value allowed object is
* {@link PullNotificationSubscriberConfig }
*/
public void setPullNotificationSubscriberConfig(PullNotificationSubscriberConfig value) {
this.pullNotificationSubscriberConfig = value;
}
/**
* Gets the value of the license property.
*
@ -341,4 +363,4 @@ public class DeviceTypeConfiguration {
public void setDeviceAuthorizationConfig(DeviceAuthorizationConfig value) {
this.deviceAuthorizationConfig = value;
}
}
}

@ -16,13 +16,15 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
/**
@ -51,7 +53,7 @@ import javax.xml.bind.annotation.XmlType;
@XmlType(name = "Feature", propOrder = {
"name",
"description",
"operation"
"operation", "metaData"
})
public class Feature {
@ -63,6 +65,9 @@ public class Feature {
protected Operation operation;
@XmlAttribute(name = "code")
protected String code;
@XmlElementWrapper(name = "MetaData")
@XmlElement(name = "Property", required = true)
protected List<String> metaData;
/**
* Gets the value of the name property.
@ -160,4 +165,11 @@ public class Feature {
this.code = value;
}
public List<String> getMetaData() {
return metaData;
}
public void setMetaData(List<String> metaData) {
this.metaData = metaData;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -69,4 +69,8 @@ public class Features {
return this.feature;
}
public void addFeatures(List<Feature> features) {
this.feature = features;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -0,0 +1,80 @@
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for Properties complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Properties">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Property" maxOccurs="unbounded" minOccurs="0">
* &lt;simpleType>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
* &lt;enumeration value="attr1"/>
* &lt;enumeration value="attr2"/>
* &lt;/restriction>
* &lt;/simpleType>
* &lt;/element>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Properties", propOrder = {
"property"
})
public class Properties {
@XmlElement(name = "Property")
protected List<String> property;
/**
* Gets the value of the property property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the property property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getProperty().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getProperty() {
if (property == null) {
property = new ArrayList<String>();
}
return this.property;
}
public void addProperties(List<String> property) {
this.property = property;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -0,0 +1,106 @@
/*
* Copyright (c) 2017, 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for PullNotificationSubscriberConfig complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="PullNotificationSubscriberConfig">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="ConfigProperties" type="{}ConfigProperties"/>
* &lt;/sequence>
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PullNotificationSubscriberConfig", propOrder = {
"configProperties"
})
public class PullNotificationSubscriberConfig {
@XmlElement(name = "ConfigProperties", required = true)
protected ConfigProperties configProperties;
@XmlAttribute(name = "className")
protected String className;
/**
* Gets the value of the configProperties property.
*
* @return
* possible object is
* {@link ConfigProperties }
*
*/
public ConfigProperties getConfigProperties() {
return configProperties;
}
/**
* Sets the value of the configProperties property.
*
* @param value
* allowed object is
* {@link ConfigProperties }
*
*/
public void setConfigProperties(ConfigProperties value) {
this.configProperties = value;
}
/**
* Gets the value of the type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getClassName() {
return className;
}
/**
* Sets the value of the type property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setClassName(String value) {
this.className = value;
}
}

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@ -16,7 +16,7 @@
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.deployer.config;
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save