restructuring iot-plugins

removing mobile/iot base plugins and other restructuring
apim420
Ace 8 years ago
commit 4d0c0d2af9

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2015, 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>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.2.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - IoT Server VirtualFireAlarm API</name>
<description>WSO2 Carbon - Virtual FireAlarm Service Management API Implementation</description>
<url>http://wso2.org</url>
<dependencies>
<!-- CDM -->
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<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.core</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<scope>provided</scope>
</dependency>
<!--MQTT -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<scope>provided</scope>
</dependency>
<!--IOT -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1</version>
<scope>provided</scope>
</dependency>
<!--JAX-RS -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bouncycastle.wso2</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.queuing</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.base</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2</artifactId>
</exclusion>
<exclusion>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smack</artifactId>
</exclusion>
<exclusion>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
</exclusion>
<exclusion>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</exclusion>
<exclusion>
<groupId>commons-fileupload.wso2</groupId>
<artifactId>commons-fileupload</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ant.wso2</groupId>
<artifactId>ant</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ant.wso2</groupId>
<artifactId>ant</artifactId>
</exclusion>
<exclusion>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.equinox</groupId>
<artifactId>javax.servlet</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.registry.api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smack</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.application.extension</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.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>${wso2.maven.compiler.source}</source>
<target>${wso2.maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>virtual_firealarm</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,73 @@
/*
* 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.iot.virtualfirealarm.service.impl;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
/**
* This class consists the functions/APIs specific to the "actions" of the VirtualFirealarm device-type. These APIs
* include the ones that are used by the [Device] to contact the server (i.e: Enrollment & Publishing Data) and the
* ones used by the [Server/Owner] to contact the [Device] (i.e: sending control signals). This class also initializes
* the transport 'Connectors' [XMPP & MQTT] specific to the VirtualFirealarm device-type in order to communicate with
* such devices and to receive messages form it.
*/
@API(name = "virtual_firealarm", version = "1.0.0", context = "/virtual_firealarm", tags = {"virtual_firealarm"})
@DeviceType(value = "virtual_firealarm")
public interface VirtualFireAlarmService {
/**
* This is an API called/used from within the Server(Front-End) or by a device Owner. It sends a control command to
* the VirtualFirealarm device to switch `ON` or `OFF` its buzzer. The method also takes in the protocol to be used
* to connect-to and send the command to the device.
*
* @param deviceId the ID of the VirtualFirealarm device on which the buzzer needs to switched `ON` or `OFF`.
* @param state the state to which the buzzer on the device needs to be changed. Either "ON" or "OFF".
* (Case-Insensitive String)
*/
@POST
@Path("device/{deviceId}/buzz")
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@Feature(code = "buzz", name = "Buzzer On / Off", description = "Switch on/off Virtual Fire Alarm Buzzer. (On / Off)")
Response switchBuzzer(@PathParam("deviceId") String deviceId,
@FormParam("state") String state);
/**
* Retrieve Sensor data for the device type
*/
@Path("device/stats/{deviceId}")
@GET
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@Consumes("application/json")
@Produces("application/json")
Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to);
@Path("device/download")
@GET
@Produces("application/zip")
@Scope(key = "device:firealarm:enroll", name = "", description = "")
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
}

@ -0,0 +1,347 @@
/*
* 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.iot.virtualfirealarm.service.impl;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.dataservice.commons.SortType;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
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.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFirealarmSecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
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.Response;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
private static final String XMPP_PROTOCOL = "XMPP";
private static final String MQTT_PROTOCOL = "MQTT";
private static final String KEY_TYPE = "PRODUCTION";
private static ApiApplicationKey apiApplicationKey;
private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "device-mgt";
private static Log log = LogFactory.getLog(VirtualFireAlarmServiceImpl.class);
@POST
@Path("device/{deviceId}/buzz")
public Response switchBuzzer(@PathParam("deviceId") String deviceId, @FormParam("state") String state) {
if (state == null || state.isEmpty()) {
log.error("State is not defined for the buzzer operation");
return Response.status(Response.Status.BAD_REQUEST).build();
}
String switchToState = state.toUpperCase();
if (!switchToState.equals(VirtualFireAlarmConstants.STATE_ON) && !switchToState.equals(
VirtualFireAlarmConstants.STATE_OFF)) {
log.error("The requested state change shoud be either - 'ON' or 'OFF'");
return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String resource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = resource + ":" + switchToState;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
Operation commandOp = new CommandOperation();
commandOp.setCode("buzz");
commandOp.setType(Operation.Type.COMMAND);
commandOp.setEnabled(true);
commandOp.setPayLoad(encryptedMsg);
Properties props = new Properties();
props.setProperty(VirtualFireAlarmConstants.MQTT_ADAPTER_TOPIC_PROPERTY_NAME, publishTopic);
props.setProperty(VirtualFireAlarmConstants.CLIENT_JID_PROPERTY_KEY, deviceId + "@" + XmppConfig
.getInstance().getServerName());
props.setProperty(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "CONTROL-REQUEST");
props.setProperty(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
commandOp.setProperties(props);
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
deviceIdentifiers.add(new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE));
APIUtil.getDeviceManagementService().addOperation(VirtualFireAlarmConstants.DEVICE_TYPE, commandOp,
deviceIdentifiers);
return Response.ok().build();
} catch (InvalidDeviceException e) {
String msg = "Error occurred while executing command operation to send keywords";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (VirtualFireAlarmException e) {
String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "]";
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (OperationManagementException e) {
String msg = "Error occurred while executing command operation upon ringing the buzzer";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
@PUT
@Path("device/{deviceId}/policy")
public Response updatePolicy(@PathParam("deviceId") String deviceId, @QueryParam("protocol") String protocol,
@FormParam("policy") String policy) {
String protocolString = protocol.toUpperCase();
if (log.isDebugEnabled()) {
log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString);
}
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
Map<String, String> dynamicProperties = new HashMap<>();
switch (protocolString) {
case XMPP_PROTOCOL:
dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY,
deviceId + "@" + XmppConfig.getInstance().getServerName());
dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST");
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break;
default:
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break;
}
return Response.ok().build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (VirtualFireAlarmException e) {
log.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
@Path("device/stats/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "deviceId:" + deviceId + " AND deviceType:" +
VirtualFireAlarmConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = VirtualFireAlarmConstants.TEMPERATURE_EVENT_TABLE;
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("time", SortType.ASC);
sortByFields.add(sortByField);
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).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();
}
}
@Path("device/download")
@GET
@Produces("application/zip")
public Response downloadSketch(@QueryParam("deviceName") String deviceName,
@QueryParam("sketchType") String sketchType) {
try {
ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType);
Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile()));
response.status(Response.Status.OK);
response.type("application/zip");
response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\"");
Response resp = response.build();
zipFile.getZipFile().delete();
return resp;
} catch (IllegalArgumentException ex) {
return Response.status(400).entity(ex.getMessage()).build();//bad request
} catch (DeviceManagementException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (JWTClientException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (VirtualFirealarmDeviceMgtPluginException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
}
}
private boolean register(String deviceId, String name) {
try {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(VirtualFireAlarmConstants.DEVICE_TYPE);
if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) {
return false;
}
Device device = new Device();
device.setDeviceIdentifier(deviceId);
EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
enrolmentInfo.setDateOfEnrolment(new Date().getTime());
enrolmentInfo.setDateOfLastUpdate(new Date().getTime());
enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
device.setName(name);
device.setType(VirtualFireAlarmConstants.DEVICE_TYPE);
enrolmentInfo.setOwner(APIUtil.getAuthenticatedUser());
device.setEnrolmentInfo(enrolmentInfo);
return APIUtil.getDeviceManagementService().enrollDevice(device);
} catch (DeviceManagementException e) {
log.error(e.getMessage(), e);
return false;
}
}
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException,
UserStoreException, VirtualFirealarmDeviceMgtPluginException {
//create new device id
String deviceId = shortUUID();
boolean status = register(deviceId, deviceName);
if (!status) {
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
throw new DeviceManagementException(msg);
}
if (apiApplicationKey == null) {
String applicationUsername =
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
.getAdminUserName();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String device = "{ \"scope\":\"mqtt-publisher mqtt-subscriber\", \"deviceIdentifiers\":[{\"id\":\""+deviceId+"\", " +
"\"type\":\""+VirtualFireAlarmConstants.DEVICE_TYPE+"\"}]}";
Map<String, String> params = new HashMap<String, String>();
params.put("device", Base64.encodeBase64String(device.getBytes()));
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner,
null, params);
String accessToken = accessTokenInfo.getAccessToken();
String refreshToken = accessTokenInfo.getRefreshToken();
XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(deviceId);
newXmppAccount.setUsername(deviceId);
newXmppAccount.setPassword(accessToken);
newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser());
status = XmppServerClient.createAccount(newXmppAccount);
if (!status) {
String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" +
".common.config.server.configs";
throw new DeviceManagementException(msg);
}
ZipUtil ziputil = new ZipUtil();
return ziputil.createZipFile(owner, sketchType, deviceId, deviceName, apiApplicationKey.toString(),
accessToken, refreshToken);
}
private static String shortUUID() {
UUID uuid = UUID.randomUUID();
long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
return Long.toString(l, Character.MAX_RADIX);
}
}

@ -0,0 +1,68 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@XmlRootElement
/**
* This stores sensor event data for android sense.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class SensorRecord {
@XmlElementWrapper(required = true, name = "values")
private Map<String, Object> values;
/** The id. */
@XmlElement(required = false, name = "id")
private String id;
/**
* Gets the values.
* @return the values
*/
public Map<String, Object> getValues() {
return values;
}
/**
* Sets the values.
* @param values the values
*/
public void setValues(Map<String, Object> values) {
this.values = values;
}
/**
* Sets the id.
* @param id the new id
*/
public void setId(String id) {
this.id = id;
}
/**
* Gets the id.
* @return the id
*/
public String getId() {
return id;
}
@Override
public String toString(){
List<String> valueList = new ArrayList<String>();
for (Map.Entry<String, Object> entry : values.entrySet()) {
valueList.add(entry.getKey() + ":" + entry.getValue());
}
return valueList.toString();
}
}

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.exception;
public class VirtualFireAlarmException extends Exception {
private static final long serialVersionUID = 118512086957330189L;
public VirtualFireAlarmException(String errorMessage) {
super(errorMessage);
}
public VirtualFireAlarmException(String errorMessage, Throwable throwable) {
super(errorMessage, throwable);
}
public VirtualFireAlarmException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,198 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
import org.wso2.carbon.analytics.datasource.commons.Record;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class provides utility functions used by REST-API.
*/
public class APIUtil {
private static Log log = LogFactory.getLog(APIUtil.class);
public static String getAuthenticatedUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
String username = threadLocalCarbonContext.getUsername();
String tenantDomain = threadLocalCarbonContext.getTenantDomain();
if (username.endsWith(tenantDomain)) {
return username.substring(0, username.lastIndexOf("@"));
}
return username;
}
public static DeviceManagementProviderService getDeviceManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceManagementProviderService deviceManagementProviderService =
(DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null);
if (deviceManagementProviderService == null) {
String msg = "Device Management service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return deviceManagementProviderService;
}
public 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;
}
public static List<SensorRecord> getAllEventsForDevice(String tableName, String query,
List<SortByField> sortByFields) throws AnalyticsException {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
if (eventCount == 0) {
return null;
}
List<SearchResultEntry> resultEntries = analyticsDataAPI.search(tenantId, tableName, query, 0, eventCount,
sortByFields);
List<String> recordIds = getRecordIds(resultEntries);
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
Map<String, SensorRecord> sensorDatas = createSensorData(AnalyticsDataServiceUtils.listRecords(
analyticsDataAPI, response));
List<SensorRecord> sortedSensorData = getSortedSensorData(sensorDatas, resultEntries);
return sortedSensorData;
}
private static List<String> getRecordIds(List<SearchResultEntry> searchResults) {
List<String> ids = new ArrayList<>();
for (SearchResultEntry searchResult : searchResults) {
ids.add(searchResult.getId());
}
return ids;
}
public static List<SensorRecord> getSortedSensorData(Map<String, SensorRecord> sensorDatas,
List<SearchResultEntry> searchResults) {
List<SensorRecord> sortedRecords = new ArrayList<>();
for (SearchResultEntry searchResultEntry : searchResults) {
sortedRecords.add(sensorDatas.get(searchResultEntry.getId()));
}
return sortedRecords;
}
/**
* Creates the SensorDatas from records.
*
* @param records the records
* @return the Map of SensorRecord <id, SensorRecord>
*/
public static Map<String, SensorRecord> createSensorData(List<Record> records) {
Map<String, SensorRecord> sensorDatas = new HashMap<>();
for (Record record : records) {
SensorRecord sensorData = createSensorData(record);
sensorDatas.put(sensorData.getId(), sensorData);
}
return sensorDatas;
}
/**
* Create a SensorRecord object out of a Record object
*
* @param record the record object
* @return SensorRecord object
*/
public static SensorRecord createSensorData(Record record) {
SensorRecord recordBean = new SensorRecord();
recordBean.setId(record.getId());
recordBean.setValues(record.getValues());
return recordBean;
}
public static APIManagementProviderService getAPIManagementProviderService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
APIManagementProviderService apiManagementProviderService =
(APIManagementProviderService) ctx.getOSGiService(APIManagementProviderService.class, null);
if (apiManagementProviderService == null) {
String msg = "API management provider service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return apiManagementProviderService;
}
public static JWTClientManagerService getJWTClientManagerService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
JWTClientManagerService jwtClientManagerService =
(JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "JWT Client manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
public static String getTenantDomainOftheUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
return threadLocalCarbonContext.getTenantDomain();
}
public static DeviceAccessAuthorizationService getDeviceAccessAuthorizationService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
(DeviceAccessAuthorizationService) ctx.getOSGiService(DeviceAccessAuthorizationService.class, null);
if (deviceAccessAuthorizationService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return deviceAccessAuthorizationService;
}
public static OutputEventAdapterService getOutputEventAdapterService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
OutputEventAdapterService outputEventAdapterService =
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
if (outputEventAdapterService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return outputEventAdapterService;
}
public static PlatformConfigurationManagementService getTenantConfigurationManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
PlatformConfigurationManagementService tenantConfigurationManagementService =
(PlatformConfigurationManagementService) ctx.getOSGiService(PlatformConfigurationManagementService.class, null);
if (tenantConfigurationManagementService == null) {
String msg = "Tenant configuration Management service not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return tenantConfigurationManagementService;
}
}

@ -0,0 +1,51 @@
/*
* 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.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFirealarmSecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import java.lang.*;
import java.security.PrivateKey;
/**
*
*/
public class VirtualFireAlarmServiceUtils {
private static final String JSON_MESSAGE_KEY = "Msg";
private static final String JSON_SIGNATURE_KEY = "Sig";
public static String prepareSecurePayLoad(String message, PrivateKey signatureKey) throws VirtualFireAlarmException {
try {
message = Base64.encodeBase64String(message.getBytes());
String signedPayload = VirtualFirealarmSecurityManager.signMessage(message, signatureKey);
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, message);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
return jsonPayload.toString();
} catch (VirtualFirealarmDeviceMgtPluginException e) {
throw new VirtualFireAlarmException(e);
}
}
}

@ -0,0 +1,26 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
public class VirtualFireAlarmUtilConstants {
public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
public static final String DEVICE_OWNER = "DEVICE_OWNER";
public static final String DEVICE_ID = "DEVICE_ID";
public static final String DEVICE_NAME = "DEVICE_NAME";
public static final String HTTPS_EP = "HTTPS_EP";
public static final String HTTP_EP = "HTTP_EP";
public static final String APIM_EP = "APIM_EP";
public static final String MQTT_EP = "MQTT_EP";
public static final String XMPP_EP = "XMPP_EP";
public static final String VIRTUAL_FIREALARM_HTTPS_EP = "VIRTUAL_FIREALARM_HTTPS_EP";
public static final String VIRTUAL_FIREALARM_HTTP_EP = "VIRTUAL_FIREALARM_HTTP_EP";
public static final String VIRTUAL_FIREALARM_APIM_EP = "VIRTUAL_FIREALARM_APIM_EP";
public static final String VIRTUAL_FIREALARM_MQTT_EP = "VIRTUAL_FIREALARM_MQTT_EP";
public static final String VIRTUAL_FIREALARM_XMPP_EP = "VIRTUAL_FIREALARM_XMPP_EP";
public static final String API_APPLICATION_KEY = "API_APPLICATION_KEY";
public static final String DEVICE_TOKEN = "DEVICE_TOKEN";
public static final String DEVICE_REFRESH_TOKEN = "DEVICE_REFRESH_TOKEN";
public static final String SERVER_NAME = "SERVER_NAME";
public static final String SERVER_JID = "SERVER_JID";
}

@ -0,0 +1,43 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.util;
import java.io.File;
/**
* This is an utility class to hold zip files.
*/
public class ZipArchive {
private File zipFile = null;
private String fileName = null;
public ZipArchive(String fileName, File zipFile) {
this.fileName = fileName;
this.zipFile = zipFile;
}
public File getZipFile() {
return zipFile;
}
public String getFileName() {
return fileName;
}
}

@ -0,0 +1,387 @@
/*
* 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.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* This is used to create a zip file that includes the necessary configuration required for the agent.
*/
public class ZipUtil {
private static final Log log = LogFactory.getLog(ZipUtil.class);
private static final String HTTPS_PORT_PROPERTY = "httpsPort";
private static final String HTTP_PORT_PROPERTY = "httpPort";
private static final String LOCALHOST = "localhost";
private static final String HTTPS_PROTOCOL_APPENDER = "https://";
private static final String HTTP_PROTOCOL_APPENDER = "http://";
private static final String CONFIG_TYPE = "general";
private static final String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1883";
public static final String HOST_NAME = "HostName";
public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName,
String apiApplicationKey, String token, String refreshToken)
throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath =
CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP;
try {
iotServerIP = getServerUrl();
String httpsServerPort = System.getProperty(HTTPS_PORT_PROPERTY);
String httpServerPort = System.getProperty(HTTP_PORT_PROPERTY);
String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort;
String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort;
String mqttEndpoint = DEFAULT_MQTT_ENDPOINT;
if (mqttEndpoint.contains(LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
}
String xmppEndpoint = "";
if (XmppConfig.getInstance().isEnabled()) {
xmppEndpoint = XmppConfig.getInstance().getHost() + ":" + XmppConfig.getInstance().getPort();
if (xmppEndpoint.contains(LOCALHOST)) {
xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP);
}
}
PlatformConfiguration configuration = APIUtil.getTenantConfigurationManagementService().getConfiguration(
CONFIG_TYPE);
if (configuration != null && configuration.getConfiguration() != null && configuration
.getConfiguration().size() > 0) {
List<ConfigurationEntry> configurations = configuration.getConfiguration();
for (ConfigurationEntry configurationEntry : configurations) {
switch (configurationEntry.getName()) {
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_HTTPS_EP:
httpsServerEP = (String)configurationEntry.getValue();
break;
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_HTTP_EP:
httpServerEP = (String)configurationEntry.getValue();
break;
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_MQTT_EP:
mqttEndpoint = (String)configurationEntry.getValue();
break;
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_XMPP_EP:
xmppEndpoint = (String)configurationEntry.getValue();
break;
}
}
}
String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey).trim();
Map<String, String> contextParams = new HashMap<>();
contextParams.put(VirtualFireAlarmUtilConstants.TENANT_DOMAIN, APIUtil.getTenantDomainOftheUser());
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_OWNER, owner);
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_ID, deviceId);
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_NAME, deviceName);
contextParams.put(VirtualFireAlarmUtilConstants.HTTPS_EP, httpsServerEP);
contextParams.put(VirtualFireAlarmUtilConstants.HTTP_EP, httpServerEP);
contextParams.put(VirtualFireAlarmUtilConstants.APIM_EP, httpServerEP);
contextParams.put(VirtualFireAlarmUtilConstants.MQTT_EP, mqttEndpoint);
contextParams.put(VirtualFireAlarmUtilConstants.XMPP_EP, "XMPP:" + xmppEndpoint);
contextParams.put(VirtualFireAlarmUtilConstants.API_APPLICATION_KEY, base64EncodedApplicationKey);
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_TOKEN, token);
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_REFRESH_TOKEN, refreshToken);
contextParams.put(VirtualFireAlarmUtilConstants.SERVER_NAME, XmppConfig.getInstance().getServerName() == null
? "" : XmppConfig.getInstance().getServerName());
contextParams.put(VirtualFireAlarmUtilConstants.SERVER_JID, XmppConfig.getInstance().getJid() == null
? "" : XmppConfig.getInstance().getJid());
ZipArchive zipFile;
zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
return zipFile;
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
} catch (ConfigurationManagementException e) {
throw new DeviceManagementException("Failed to retrieve configuration", e);
}
}
private String getBase64EncodedAPIAppKey(String apiAppCredentialsAsJSONString) {
JSONObject jsonObject = new JSONObject(apiAppCredentialsAsJSONString);
String consumerKey = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_ID).toString();
String consumerSecret = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_SECRET).toString();
String stringToEncode = consumerKey + ":" + consumerSecret;
return Base64.encodeBase64String(stringToEncode.getBytes());
}
public static String getServerUrl() {
String hostName = ServerConfiguration.getInstance().getFirstProperty(HOST_NAME);
try {
if (hostName == null) {
hostName = NetworkUtils.getLocalHostname();
}
} catch (SocketException e) {
hostName = "localhost";
log.warn("Failed retrieving the hostname, therefore set to localhost", e);
}
return hostName;
}
public static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams
, String zipFileName)
throws DeviceManagementException, IOException {
String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath;
FileUtils.deleteDirectory(new File(archivesPath));//clear directory
FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip
if (!new File(archivesPath).mkdirs()) { //new dir
String message = "Could not create directory at path: " + archivesPath;
log.error(message);
throw new DeviceManagementException(message);
}
zipFileName = zipFileName + ".zip";
try {
Map<String, List<String>> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties");
List<String> templateFiles = properties.get("templates");
for (String templateFile : templateFiles) {
parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile,
contextParams);
}
templateFiles.add("sketch.properties"); // ommit copying the props file
copyFolder(new File(sketchPath), new File(archivesPath), templateFiles);
createZipArchive(archivesPath);
FileUtils.deleteDirectory(new File(archivesPath));
File zip = new File(archivesPath + ".zip");
return new org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive(zipFileName, zip);
} catch (IOException ex) {
throw new DeviceManagementException(
"Error occurred when trying to read property " + "file sketch.properties", ex);
}
}
private static Map<String, List<String>> getProperties(String propertyFilePath) throws IOException {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream(propertyFilePath);
// load a properties file
prop.load(input);
Map<String, List<String>> properties = new HashMap<String, List<String>>();
String templates = prop.getProperty("templates");
List<String> list = new ArrayList<String>(Arrays.asList(templates.split(",")));
properties.put("templates", list);
final String filename = prop.getProperty("zipfilename");
list = new ArrayList<String>() {{
add(filename);
}};
properties.put("zipfilename", list);
return properties;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
log.error("Failed closing connection", e);
}
}
}
}
private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException {
//read from file
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(dstFile);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString());
Iterator iterator = contextParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) iterator.next();
content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString());
}
IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString());
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
private static void copyFolder(File src, File dest, List<String> excludeFileNames) throws IOException {
if (src.isDirectory()) {
//if directory not exists, create it
if (!dest.exists() && !dest.mkdirs()) {
String message = "Could not create directory at path: " + dest;
log.error(message);
throw new IOException(message);
}
//list all the directory contents
String files[] = src.list();
if (files == null) {
log.warn("There are no files insides the directory " + src.getAbsolutePath());
return;
}
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile, destFile, excludeFileNames);
}
} else {
for (String fileName : excludeFileNames) {
if (src.getName().equals(fileName)) {
return;
}
}
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
private static boolean createZipArchive(String srcFolder) throws IOException {
BufferedInputStream origin = null;
ZipOutputStream out = null;
try {
final int BUFFER = 2048;
FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip"));
out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
File subDir = new File(srcFolder);
String subdirList[] = subDir.list();
if (subdirList == null) {
log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty");
return false;
}
for (String sd : subdirList) {
// get a list of files from current directory
File f = new File(srcFolder + "/" + sd);
if (f.isDirectory()) {
String files[] = f.list();
if (files == null) {
log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files");
return false;
}
for (int i = 0; i < files.length; i++) {
FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd + "/" + files[i]);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
}
} else //it is just a file
{
FileInputStream fi = new FileInputStream(f);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
}
}
out.flush();
} finally {
if (origin != null) {
origin.close();
}
if (out != null) {
out.close();
}
}
return true;
}
}

@ -0,0 +1,61 @@
/*
* 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.iot.virtualfirealarm.service.impl.util.util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Provides utility methods required by the device type plugins.
*/
public class Utils {
public static final String HOST_NAME = "HostName";
private static final Log log = LogFactory.getLog(Utils.class);
}

@ -0,0 +1,52 @@
<?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.
-->
<!-- This file contains the list of permissions that are associated with URL end points
of the web app. Each permission should contain the name, permission path ,API path
(URL) , HTTP method and OAUTH2 authorization scope (not-required).
When defining dynamic paths for APIs, path variables are denoted by '*' notation.
NOTE: All the endpoints of the web app should be available in this file. Otherwise
it will result 403 error at the runtime.
-->
<PermissionConfiguration>
<APIVersion></APIVersion>
<!-- Device related APIs -->
<Permission>
<name>Download device</name>
<path>/device-mgt/user/devices</path>
<url>/device/download</url>
<method>GET</method>
<scope>virtual_firealarm_user</scope>
</Permission>
<Permission>
<name>Control Buzz</name>
<path>/device-mgt/user/operation</path>
<url>/device/*/buzz</url>
<method>POST</method>
<scope>virtual_firealarm_user</scope>
</Permission>
<Permission>
<name>Get Stats</name>
<path>/device-mgt/user/stats</path>
<url>/device/stats/*</url>
<method>GET</method>
<scope>virtual_firealarm_user</scope>
</Permission>
</PermissionConfiguration>

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright 2005-2013 WSO2, Inc. (http://wso2.com)
~
~ 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.
-->
<!--
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
-->
<Classloading xmlns="http://wso2.org/projects/as/classloading">
<!-- Parent-first or child-first. Default behaviour is child-first.-->
<ParentFirst>false</ParentFirst>
<!--
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
-->
<Environments>CXF,Carbon</Environments>
</Classloading>

@ -0,0 +1,38 @@
<?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.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxrs:server id="VirtualFireAlarm" address="/">
<jaxrs:serviceBeans>
<bean id="VirtualFireAlarmService"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmServiceImpl">
</bean>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
</beans>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
metadata-complete="true">
<display-name>WSO2 IoT Server</display-name>
<description>WSO2 IoT Server</description>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>isAdminService</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>doAuthentication</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>providerTenantDomain</param-name>
<param-value>carbon.super</param-value>
</context-param>
<!--publish to apim-->
<context-param>
<param-name>managed-api-enabled</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>managed-api-owner</param-name>
<param-value>admin</param-value>
</context-param>
</web-app>
Loading…
Cancel
Save