Merge branch 'release-3.0.x' of https://github.com/wso2/carbon-device-mgt-plugins into release-3.0.x

revert-dabc3590
Menaka Jayawardena 8 years ago
commit 672f153551

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -69,6 +69,12 @@
<!--TODO: use http://requirejs.org/ for better performance, now we have too many imports -->
<!-- C3 chart library styles-->
<link rel="stylesheet" href="css/d3/c3.css" type="text/css"/>
<link rel="stylesheet" href="css/bootstrap-datepicker.min.css" type="text/css"/>
<style>
.datepicker-inline {
margin:0 auto;
}
</style>
<!-- JAVASCRIPT -->
@ -85,7 +91,17 @@
<script src="js/jquery/jquery-2.1.1.min.js"></script>
<script src="js/jquery/jquery-ui.min.js"></script>
<script src="js/bootstrap/bootstrap.min.js"></script>
<script src="js/bootstrap-datepicker.min.js"></script>
<script>
$(function() {
$("#timeFrom").datepicker({
orientation: 'top'
});
$("#timeTo").datepicker({
orientation: 'top'
});
});
</script>
<!--bootstrap-application-wizard-->
<script src="js/bootstrap-wizard-lib/bootstrap-wizard.js"></script>

@ -327,25 +327,31 @@ function notifyError(message) {
function enableRealTime() {
document.getElementById('realTimeShow').style.display = 'none';
spatialObject = currentSpatialObjects[selectedSpatialObject];
spatialObject.removePath();
spatialObject.marker.closePopup();
if (spatialObject) {
spatialObject.removePath();
spatialObject.marker.closePopup();
}
selectedSpatialObject = null;
clearFocus();
clearMap();
document.getElementById('objectInfo').style.display = 'none';
isBatchModeOn = false;
}
function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) {
if (!timeFrom) {
notifyError('No start time provided to show history. Please provide a suitable value' + timeFrom);
} else if (!timeTo) {
notifyError('No end time provided to show history. Please provide a suitable value' + timeTo);
} else {
$('#dateRangePopup').dialog('close');
document.getElementById('realTimeShow').style.display = 'block';
isBatchModeOn = true;
clearFocus(); // Clear current focus if any
clearMap();
var tableData = getProviderData(timeFrom, timeTo);
var fromDate = new Date(timeFrom);
var toDate = new Date(timeTo);
var tableData = getProviderData(fromDate.valueOf() / 1000, toDate.valueOf() / 1000);
for (var i = 0; i < tableData.length; i++) {
var data = tableData[i];
var geoMessage = {
@ -401,7 +407,6 @@ function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) {
createChart();
chart.load({columns: [spatialObject.speedHistory.getArray()]});
}, 100);
$('#dateRangePopup').dialog('close');
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -116,7 +116,7 @@ public class SenseClientAsyncExecutor extends AsyncTask<String, Void, Map<String
TokenIssuerService tokenIssuerService = Feign.builder().client(disableHostnameVerification).requestInterceptor(
new BasicAuthRequestInterceptor(apiApplicationKey.getConsumerKey(), apiApplicationKey.getConsumerSecret()))
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
.target(TokenIssuerService.class, endpoint + SenseConstants.TOKEN_ISSUER_CONTEXT);
.target(TokenIssuerService.class, endpoint);
accessTokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, "device_" + deviceId);
//DeviceRegister

@ -39,7 +39,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" android:hint="@string/hostname"
android:id="@+id/hostname"
android:text="https://localhost:9443"
android:text="https://localhost:8243"
android:inputType="text"
android:maxLines="1" android:singleLine="true"/>

@ -1,7 +1,7 @@
<resources>
<string name="app_name">WSO2-SenseAgent</string>
<string name="title_activity_sense_settings">Sense Settings</string>
<string name="hostname">Server URL https://host:9443</string>
<string name="hostname">Server URL https://host:8243</string>
<string name="speakup">Speakup to capture the words</string>
<string name="action_settings">DeEnroll</string>
<string name="title_activity_activity_select_sensor">ActivitySelectSensor</string>

@ -21,7 +21,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,10 +21,8 @@
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/android_sense/+/data</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="contentTransformer">default</property>
<property name="dcrUrl">https://${iot.core.host}:${iot.core.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>

@ -3,7 +3,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -153,6 +153,11 @@
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

@ -19,14 +19,29 @@
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.constants.AndroidSenseConstants;
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 javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
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;
@SwaggerDefinition(
@ -44,6 +59,16 @@ import javax.ws.rs.core.Response;
@Tag(name = "android_sense", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Enroll device",
description = "",
key = "perm:android-sense:enroll",
permissions = {"/device-mgt/devices/enroll/android-sense"}
)
}
)
public interface AndroidSenseService {
/**
@ -52,10 +77,57 @@ public interface AndroidSenseService {
* @param deviceId The registered device Id.
* @param keywords The key words to be sent. (Comma separated values)
*/
@Path("device/{deviceId}/words")
@POST
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response sendKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("keywords") String keywords);
@Path("device/{deviceId}/words")
@ApiOperation(
httpMethod = "POST",
value = "End point to send the key words to the device",
notes = "",
tags = "android_sense",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = AndroidSenseConstants.SCOPE, value = "perm:android-sense:enroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@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 Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while executing command operation to"
+ " send keywords",
response = Response.class)
})
Response sendKeyWords(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "keywords",
value = "The key words to be sent. (Comma separated values)",
required = true)
@QueryParam("keywords") String keywords);
/**
* End point to send the key words to the device
@ -63,34 +135,222 @@ public interface AndroidSenseService {
* @param deviceId The registered device Id.
* @param threshold The key words to be sent. (Comma separated values)
*/
@Path("device/{deviceId}/words/threshold")
@POST
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response sendThreshold(@PathParam("deviceId") String deviceId, @QueryParam("threshold") String threshold);
@Path("device/{deviceId}/words/threshold")
@ApiOperation(
httpMethod = "POST",
value = "End point to send threshold value to the device",
notes = "",
tags = "android_sense",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = AndroidSenseConstants.SCOPE, value = "perm:android-sense:enroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@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 Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while executing command operation to"
+ " send threashold",
response = Response.class)
})
Response sendThreshold(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "threshold",
value = "Threshold to be sent.",
required = true)
@QueryParam("threshold") String threshold);
@Path("device/{deviceId}/words")
/**
* End point to remove key words from the device
*/
@DELETE
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response removeKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("words") String words);
@Path("device/{deviceId}/words")
@ApiOperation(
httpMethod = "DELETE",
value = "Remove key words from the device",
notes = "",
response = Response.class,
tags = "android_sense",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = AndroidSenseConstants.SCOPE, value = "perm:android-sense:enroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@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 Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while executing command operation to"
+ " send threashold",
response = Response.class)
})
Response removeKeyWords(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "words",
value = "The key words to be sent. (Comma separated values)",
required = true)
@QueryParam("words") String words);
/**
* Retrieve Sensor data for the device type
*/
@Path("stats/{deviceId}/sensors/{sensorName}")
@GET
@Consumes("application/json")
@Scope(key = "device:android-sense:enroll", name = "", description = "")
@Produces("application/json")
Response getAndroidSenseDeviceStats(@PathParam("deviceId") String deviceId, @PathParam("sensorName") String sensor,
@QueryParam("from") long from, @QueryParam("to") long to);
@Path("stats/{deviceId}/sensors/{sensorName}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Sensor data for the device type",
notes = "",
response = Response.class,
tags = "android_sense",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = AndroidSenseConstants.SCOPE, value = "perm:android-sense:enroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@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 Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getAndroidSenseDeviceStats(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "sensorName",
value = "Name of the sensor",
required = true)
@PathParam("sensorName") String sensor,
@ApiParam(
name = "from",
value = "Get stats from what time",
required = true)
@QueryParam("from") long from,
@ApiParam(
name = "to",
value = "Get stats up to what time",
required = true)
@QueryParam("to") long to);
/**
* Enroll devices.
*/
@Path("device/{device_id}/register")
@POST
@Scope(key = "device:android-sense:enroll", name = "", description = "")
Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
@Path("device/{device_id}/register")
@ApiOperation(
httpMethod = "POST",
value = "Enroll device",
notes = "",
response = Response.class,
tags = "android_sense",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = AndroidSenseConstants.SCOPE, value = "perm:android-sense:enroll")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 202,
message = "Accepted.",
response = Response.class),
@ApiResponse(
code = 406,
message = "Not Acceptable"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response register(
@ApiParam(
name = "deviceId",
value = "Device identifier id of the device to be added",
required = true)
@PathParam("device_id") String deviceId,
@ApiParam(
name = "deviceName",
value = "Device name of the device to be added",
required = true)
@QueryParam("deviceName") String deviceName);
}

@ -42,4 +42,6 @@ public class AndroidSenseConstants {
public static final String CONFIG_TYPE = "general";
public static final String DEFAULT_ENDPOINT = "tcp://localhost:1886";
public static final String SCOPE = "scope";
}

@ -28,18 +28,10 @@
<param-name>isSharedWithAllTenants</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>

@ -22,7 +22,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -43,6 +43,8 @@
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
<li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Map</a></li>
{{/zone}}
{{#zone "device-view-tab-contents"}}
@ -73,4 +75,20 @@
</div>
</div>
</div>
<div class="panel panel-default tab-pane"
id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard">
<div class="panel-heading">Map</div>
<div id="chartWrapper">
</div>
<a class="padding-left"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Location
</a>
</div>
{{/zone}}

@ -20,6 +20,7 @@ function onRequest(context) {
var log = new Log("device-view.js");
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var autoCompleteParams = [
{"name" : "deviceId", "value" : deviceId}
];
@ -28,10 +29,13 @@ function onRequest(context) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
var anchor = { "device" : { "id" : device.content.deviceIdentifier, "type" : device.content.type}};
return {
"device": device.content,
"autoCompleteParams": autoCompleteParams,
"encodedFeaturePayloads": ""
"encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor)
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,14 +18,7 @@
-->
<eventReceiver name="arduino_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-http">
<property name="maximumHttpConnectionPerHost">2</property>
<property name="username">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.http.util.HTTPContentValidator</property>
<property name="contentTransformer">default</property>
<property name="transports">all</property>
<property name="maximumTotalHttpConnection">100</property>
<property name="tokenValidationEndpointUrl">https://localhost:${dcr.endpoint.port}/services/OAuth2TokenValidationService</property>
<property name="password">admin</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.arduino" version="1.0.0"/>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -141,6 +141,11 @@
<artifactId>org.wso2.carbon.analytics.api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

@ -18,15 +18,14 @@
package org.wso2.carbon.device.mgt.iot.arduino.service.impl;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.constants.ArduinoConstants;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@SwaggerDefinition(
@ -44,26 +43,72 @@ import javax.ws.rs.core.Response;
@Tag(name = "arduino", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Enroll device",
description = "",
key = "perm:arduino:enroll",
permissions = {"/device-mgt/devices/enroll/arduino"}
)
}
)
public interface ArduinoService {
@Path("device/{deviceId}/bulb")
@POST
@Scope(key = "device:arduino:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Switch bulb",
notes = "",
response = Response.class,
tags = "arduino",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = ArduinoConstants.SCOPE, value = "perm:arduino:enroll")
})
}
)
Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state);
@Path("device/{deviceId}/controls")
@GET
@Scope(key = "device:arduino:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Read controls",
notes = "",
response = Response.class,
tags = "arduino",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = ArduinoConstants.SCOPE, value = "perm:arduino:enroll")
})
}
)
Response readControls(@PathParam("deviceId") String deviceId);
/**
* Retreive Sensor data for the device type
* Retrieve Sensor data for the device type
*/
@Path("device/stats/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
@Scope(key = "device:arduino:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Retrieve Sensor data for the device type",
notes = "",
response = Response.class,
tags = "arduino",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = ArduinoConstants.SCOPE, value = "perm:arduino:enroll")
})
}
)
Response getArduinoTemperatureStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to);
@ -73,7 +118,19 @@ public interface ArduinoService {
@Path("device/download")
@GET
@Produces("application/octet-stream")
@Scope(key = "device:arduino:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Download device agent",
notes = "",
response = Response.class,
tags = "arduino",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = ArduinoConstants.SCOPE, value = "perm:arduino:enroll")
})
}
)
Response downloadSketch(@QueryParam("deviceName") String customDeviceName);
}

@ -27,4 +27,6 @@ public class ArduinoConstants {
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
public static final String SCOPE = "scope";
}

@ -28,19 +28,11 @@
<param-name>isSharedWithAllTenants</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>

@ -23,7 +23,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -44,6 +44,8 @@
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
<li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Map</a></li>
{{/zone}}
{{#zone "device-view-tab-contents"}}
@ -75,4 +77,20 @@
</div>
</div>
</div>
<div class="panel panel-default tab-pane"
id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard">
<div class="panel-heading">Map</div>
<div id="chartWrapper">
</div>
<a class="padding-left"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Location
</a>
</div>
{{/zone}}

@ -20,6 +20,7 @@ function onRequest(context) {
var log = new Log("device-view.js");
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var autoCompleteParams = [
{"name" : "deviceId", "value" : deviceId}
];
@ -28,7 +29,14 @@ function onRequest(context) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device.content, "autoCompleteParams" : autoCompleteParams, "encodedFeaturePayloads": ""};
var anchor = { "device" : { "id" : device.content.deviceIdentifier, "type" : device.content.type}};
return {
"device": device.content,
"autoCompleteParams" : autoCompleteParams,
"encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor)
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,10 +20,8 @@
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/raspberrypi/+/temperature</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="contentTransformer">default</property>
<property name="dcrUrl">https://${iot.core.host}:${iot.core.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -121,7 +121,11 @@
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
</dependency>
</dependencies>
<build>

@ -18,12 +18,10 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.constants.RaspberrypiConstants;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
@ -44,11 +42,33 @@ import javax.ws.rs.core.Response;
@Tag(name = "raspberrypi", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Enroll device",
description = "",
key = "perm:raspberrypi:enroll",
permissions = {"/device-mgt/devices/enroll/raspberrypi"}
)
}
)
public interface RaspberryPiService {
@Path("device/{deviceId}/bulb")
@POST
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Switch bulb",
notes = "",
response = Response.class,
tags = "raspberrypi",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = RaspberrypiConstants.SCOPE, value = "perm:raspberrypi:enroll")
})
}
)
Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state);
/**
@ -58,7 +78,19 @@ public interface RaspberryPiService {
@GET
@Consumes("application/json")
@Produces("application/json")
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Retreive Sensor data for the device type",
notes = "",
response = Response.class,
tags = "raspberrypi",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = RaspberrypiConstants.SCOPE, value = "perm:raspberrypi:enroll")
})
}
)
Response getRaspberryPiTemperatureStats(@PathParam("deviceId") String deviceId,
@QueryParam("from") long from, @QueryParam("to") long to);
@ -68,7 +100,19 @@ public interface RaspberryPiService {
@Path("device/download")
@GET
@Produces(MediaType.APPLICATION_JSON)
@Scope(key = "device:raspberrypi:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Download the agent.",
notes = "",
response = Response.class,
tags = "raspberrypi",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = RaspberrypiConstants.SCOPE, value = "perm:raspberrypi:enroll")
})
}
)
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketch_type") String sketchType);
}

@ -33,4 +33,6 @@ public class RaspberrypiConstants {
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
public static final String SCOPE = "scope";
}

@ -28,19 +28,11 @@
<param-name>isSharedWithAllTenants</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>

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -44,6 +44,8 @@
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
<li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Map</a></li>
{{/zone}}
{{#zone "device-view-tab-contents"}}
@ -75,4 +77,20 @@
</div>
</div>
</div>
<div class="panel panel-default tab-pane"
id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard">
<div class="panel-heading">Map</div>
<div id="chartWrapper">
</div>
<a class="padding-left"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Location
</a>
</div>
{{/zone}}

@ -20,6 +20,7 @@ function onRequest(context) {
var log = new Log("device-view.js");
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var autoCompleteParams = [
{"name" : "deviceId", "value" : deviceId}
];
@ -28,7 +29,14 @@ function onRequest(context) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device.content, "autoCompleteParams" : autoCompleteParams, "encodedFeaturePayloads": ""};
var anchor = { "device" : { "id" : device.content.deviceIdentifier, "type" : device.content.type}};
return {
"device": device.content,
"autoCompleteParams" : autoCompleteParams,
"encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor)
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -191,7 +191,10 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
@Override
public void run() {
int currentTemperature = agentManager.getTemperature();
String message = "PUBLISHER:" + AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
try {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);

@ -189,7 +189,10 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
try {
int currentTemperature = agentManager.getTemperature();
String message = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID);

@ -58,7 +58,7 @@ public class AgentConstants {
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
/* ---------------------------------------------------------------------------------------
XMPP Connection specific information
--------------------------------------------------------------------------------------- */

@ -168,13 +168,13 @@ public class AgentManager {
}
}
try {
EnrollmentManager.getInstance().beginEnrollmentFlow();
} catch (AgentCoreOperationException e) {
log.error("Device Enrollment Failed:\n");
e.printStackTrace();
System.exit(0);
}
// try {
// EnrollmentManager.getInstance().beginEnrollmentFlow();
// } catch (AgentCoreOperationException e) {
// log.error("Device Enrollment Failed:\n");
// e.printStackTrace();
// System.exit(0);
// }
//Start agent communication
agentCommunicator.get(protocol).connect();

@ -241,59 +241,67 @@ public class AgentUtilOperations {
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
try {
signedPayload = CommunicationUtils.signMessage(encodedMessage, devicePrivateKey);
} catch (TransportHandlerException e) {
String errorMsg = "Error occurred whilst trying to sign encrypted message of: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
if (EnrollmentManager.getInstance().isEnrolled()) {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
try {
signedPayload = CommunicationUtils.signMessage(encodedMessage, devicePrivateKey);
} catch (TransportHandlerException e) {
String errorMsg = "Error occurred whilst trying to sign encrypted message of: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, encodedMessage);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
//below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, encodedMessage);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
//below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString();
return jsonPayload.toString();
} else {
return message;
}
}
public static String extractMessageFromPayload(String message) throws AgentCoreOperationException {
String actualMessage;
if (EnrollmentManager.getInstance().isEnrolled()) {
String actualMessage;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
boolean verification;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
boolean verification;
if (encodedMessage != null && signedPayload != null) {
try {
verification = CommunicationUtils.verifySignature(
encodedMessage.toString(), signedPayload.toString(), serverPublicKey);
} catch (TransportHandlerException e) {
String errorMsg =
"Error occurred whilst trying to verify signature on received message: [" + message + "]";
if (encodedMessage != null && signedPayload != null) {
try {
verification = CommunicationUtils.verifySignature(
encodedMessage.toString(), signedPayload.toString(), serverPublicKey);
} catch (TransportHandlerException e) {
String errorMsg =
"Error occurred whilst trying to verify signature on received message: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new AgentCoreOperationException(errorMsg);
}
if (verification) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()), StandardCharsets.UTF_8);
} else {
String errorMsg = "Could not verify payload signature. The message was not signed by a valid client";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
throw new AgentCoreOperationException(errorMsg);
}
return actualMessage;
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new AgentCoreOperationException(errorMsg);
}
if (verification) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()), StandardCharsets.UTF_8);
} else {
String errorMsg = "Could not verify payload signature. The message was not signed by a valid client";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg);
return message;
}
return actualMessage;
}
public static String formatMessage(String message) {

@ -96,6 +96,7 @@ public class EnrollmentManager {
private PublicKey publicKey;
private PublicKey serverPublicKey;
private X509Certificate SCEPCertificate;
private boolean isEnrolled = false;
/**
@ -443,4 +444,13 @@ public class EnrollmentManager {
public PublicKey getServerPublicKey() {
return serverPublicKey;
}
/**
* Checks whether the device has already been enrolled with the SCEP Server.
*
* @return the enrollment status; 'TRUE' if already enrolled else 'FALSE'.
*/
public boolean isEnrolled() {
return isEnrolled;
}
}

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -111,7 +111,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
AgentManager agentManager = AgentManager.getInstance();
String pathContext = request.getPathInfo();
String separator = File.separator;
String separator = File.separatorChar=='\\' ? "\\\\" : File.separator ;
if (pathContext.toUpperCase().contains(
separator + AgentConstants.TEMPERATURE_CONTROL)) {

@ -208,7 +208,10 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
@Override
public void run() {
int currentTemperature = agentManager.getTemperature();
String message = "PUBLISHER:" + AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
try {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);

@ -189,8 +189,10 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
try {
int currentTemperature = agentManager.getTemperature();
String message = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID);

@ -62,7 +62,7 @@ public class AgentConstants {
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
/* ---------------------------------------------------------------------------------------
Device/Agent specific properties to be read from the 'deviceConfig.properties' file

@ -153,15 +153,15 @@ public class AgentManager {
}
}
try {
if (!EnrollmentManager.getInstance().isEnrolled()) {
EnrollmentManager.getInstance().beginEnrollmentFlow();
}
} catch (AgentCoreOperationException e) {
log.error("Device Enrollment Failed:\n");
log.error(e);
System.exit(0);
}
// try {
// if (!EnrollmentManager.getInstance().isEnrolled()) {
// EnrollmentManager.getInstance().beginEnrollmentFlow();
// }
// } catch (AgentCoreOperationException e) {
// log.error("Device Enrollment Failed:\n");
// log.error(e);
// System.exit(0);
// }
//Start agent communication
agentCommunicator.get(protocol).connect();

@ -250,57 +250,65 @@ public class AgentUtilOperations {
}
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
try {
signedPayload = CommunicationUtils.signMessage(encodedMessage, devicePrivateKey);
} catch (TransportHandlerException e) {
String errorMsg = "Error occurred whilst trying to sign encrypted message of: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
if (EnrollmentManager.getInstance().isEnrolled()) {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
try {
signedPayload = CommunicationUtils.signMessage(encodedMessage, devicePrivateKey);
} catch (TransportHandlerException e) {
String errorMsg = "Error occurred whilst trying to sign encrypted message of: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, encodedMessage);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
//below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString();
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, encodedMessage);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
//below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString();
} else {
return message;
}
}
public static String extractMessageFromPayload(String message) throws AgentCoreOperationException {
String actualMessage;
if (EnrollmentManager.getInstance().isEnrolled()) {
String actualMessage;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
boolean verification;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
boolean verification;
if (encodedMessage != null && signedPayload != null) {
try {
verification = CommunicationUtils.verifySignature(
encodedMessage.toString(), signedPayload.toString(), serverPublicKey);
} catch (TransportHandlerException e) {
String errorMsg =
"Error occurred whilst trying to verify signature on received message: [" + message + "]";
if (encodedMessage != null && signedPayload != null) {
try {
verification = CommunicationUtils.verifySignature(
encodedMessage.toString(), signedPayload.toString(), serverPublicKey);
} catch (TransportHandlerException e) {
String errorMsg =
"Error occurred whilst trying to verify signature on received message: [" + message + "]";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
}
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new AgentCoreOperationException(errorMsg);
}
if (verification) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()), StandardCharsets.UTF_8);
} else {
String errorMsg = "Could not verify payload signature. The message was not signed by a valid client";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
throw new AgentCoreOperationException(errorMsg);
}
return actualMessage;
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new AgentCoreOperationException(errorMsg);
}
if (verification) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()), StandardCharsets.UTF_8);
} else {
String errorMsg = "Could not verify payload signature. The message was not signed by a valid client";
log.error(errorMsg);
throw new AgentCoreOperationException(errorMsg);
return message;
}
return actualMessage;
}
public static String getAuthenticationMethod() {

@ -111,7 +111,7 @@ public class EnrollmentManager {
*/
private EnrollmentManager() {
this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP();
setEnrollmentStatus();
//setEnrollmentStatus();
}
/**

@ -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.
-->
<project name="create-virtual-firealarm-capps" default="zip" basedir=".">
<property name="project-name" value="${ant.project.name}"/>
<property name="target-dir" value="target/carbonapps"/>
<property name="src-dir" value="src/main/resources/carbonapps"/>
<property name="Virtual_firealarm_dir" value="virtualfirealarm"/>
<target name="clean">
<delete dir="${target-dir}" />
</target>
<target name="zip" depends="clean">
<mkdir dir="${target-dir}"/>
<zip destfile="${target-dir}/${Virtual_firealarm_dir}.car">
<zipfileset dir="${src-dir}/${Virtual_firealarm_dir}"/>
</zip>
</target>
</project>

@ -0,0 +1,75 @@
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics</artifactId>
<name>WSO2 Carbon - IoT Server Virtual Firealarm Analytics capp</name>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="build.xml" target="zip" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<finalName>${project.artifactId}-${carbon.devicemgt.plugins.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/src.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,36 @@
<!--
~ 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.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>src</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>${basedir}/src</baseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/target/carbonapps</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

@ -0,0 +1,26 @@
<?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.
-->
<artifacts>
<artifact name="virtualfirealarm" version="1.0.0" type="carbon/application">
<dependency artifact="virtualfirealarm_stream" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="virtualfirealarm_receiver" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="virtualfirealarm_execution" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
</artifact>
</artifacts>

@ -0,0 +1,23 @@
<?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.
-->
<artifact name="virtualfirealarm_execution" version="1.0.0" type="event/execution-plan" serverRole="DataAnalyticsServer">
<file>virtualfirealarm_execution.siddhiql</file>
</artifact>

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('virtualfirealarm_execution')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('virtualfirealarm_execution')
/* define streams/tables and write queries here ... */
@Import('org.wso2.iot.virtualfirealarm:1.0.0')
define stream virtualfirealarm (meta_owner string, meta_deviceId string, meta_time long, temperature float);
@Export('org.wso2.iot.devices.temperature:1.0.0')
define stream temperature (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, temperature float);
from virtualfirealarm
select meta_owner, 'virtual_firealarm' as meta_deviceType, meta_deviceId, time:timestampInMilliseconds() as meta_time, temperature
insert into temperature;

@ -0,0 +1,22 @@
<?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.
-->
<artifact name="virtualfirealarm_receiver" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
<file>virtualfirealarm_receiver.xml</file>
</artifact>

@ -0,0 +1,29 @@
<?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.
-->
<eventReceiver name="virtualfirealarm_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/virtual_firealarm/+/temperature</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.virtualfirealarm" version="1.0.0"/>
</eventReceiver>

@ -0,0 +1,23 @@
<?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.
-->
<artifact name= "virtualfirealarm_stream" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.virtualfirealarm_1.0.0.json</file>
</artifact>

@ -0,0 +1,16 @@
{
"name": "org.wso2.iot.virtualfirealarm",
"version": "1.0.0",
"nickName": "virtual_firealarm",
"description": "Temperature data received from the virtual_firealarm",
"metaData": [
{"name":"owner","type":"STRING"},
{"name":"deviceId","type":"STRING"},
{"name":"time","type":"LONG"}
],
"payloadData": [
{
"name": "temperature","type": "FLOAT"
}
]
}

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -235,12 +235,12 @@
<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>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>

@ -18,14 +18,12 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
@ -50,8 +48,20 @@ import javax.ws.rs.core.Response;
@Tag(name = "virtual_firealarm", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Enroll device",
description = "",
key = "perm:firealarm:enroll",
permissions = {"/device-mgt/devices/enroll/firealarm"}
)
}
)
public interface VirtualFireAlarmService {
String SCOPE = "scope";
/**
* 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
@ -63,7 +73,19 @@ public interface VirtualFireAlarmService {
*/
@POST
@Path("device/{deviceId}/buzz")
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Switch Buzzer",
notes = "",
response = Response.class,
tags = "virtual_firealarm",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
})
}
)
Response switchBuzzer(@PathParam("deviceId") String deviceId,
@FormParam("state") String state);
@ -72,7 +94,19 @@ public interface VirtualFireAlarmService {
*/
@Path("device/stats/{deviceId}")
@GET
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Retrieve Sensor data for the device type",
notes = "",
response = Response.class,
tags = "virtual_firealarm",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
})
}
)
@Consumes("application/json")
@Produces("application/json")
Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@ -81,7 +115,19 @@ public interface VirtualFireAlarmService {
@Path("device/download")
@GET
@Produces("application/zip")
@Scope(key = "device:firealarm:enroll", name = "", description = "")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Download agent",
notes = "",
response = Response.class,
tags = "virtual_firealarm",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
})
}
)
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
}

@ -18,7 +18,6 @@
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;
@ -35,18 +34,15 @@ 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.constants.VirtualFireAlarmConstants;
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.device.mgt.iot.virtualfirealarm.service.impl.xmpp.VirtualFirealarmXMPPException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppServerClient;
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;
@ -76,11 +72,8 @@ 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
@ -103,10 +96,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
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;
@ -114,7 +104,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
commandOp.setCode("buzz");
commandOp.setType(Operation.Type.COMMAND);
commandOp.setEnabled(true);
commandOp.setPayLoad(encryptedMsg);
commandOp.setPayLoad(actualMessage);
Properties props = new Properties();
props.setProperty(VirtualFireAlarmConstants.MQTT_ADAPTER_TOPIC_PROPERTY_NAME, publishTopic);
@ -137,10 +127,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
} 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);
@ -162,37 +148,22 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
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;
}
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
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, actualMessage);
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();
}
}
@ -260,7 +231,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (VirtualFirealarmDeviceMgtPluginException ex) {
} catch (VirtualFirealarmXMPPException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
}
@ -294,7 +265,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException,
UserStoreException, VirtualFirealarmDeviceMgtPluginException {
UserStoreException, VirtualFirealarmXMPPException {
//create new device id
String deviceId = shortUUID();
boolean status = register(deviceId, deviceName);

@ -0,0 +1,84 @@
/*
* 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.constants;
public class VirtualFireAlarmConstants {
public final static String DEVICE_TYPE = "virtual_firealarm";
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
public final static String DEVICE_PLUGIN_DEVICE_ID = "VIRTUAL_FIREALARM_DEVICE_ID";
public final static String STATE_ON = "ON";
public final static String STATE_OFF = "OFF";
public static final String URL_PREFIX = "http://";
public static final String BULB_CONTEXT = "BULB";
public static final String POLICY_CONTEXT = "POLICY";
//sensor events sumerized table name for temperature
public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
//mqtt tranport related constants
public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt";
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
public static final int DEFAULT_MQTT_PORT = 1886;
//xmpp transport related constants
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
public static final String XMPP_ADAPTER_TYPE = "xmpp";
public static final String PASSWORD_PROPERTY_KEY = "password";
public static final String JID_PROPERTY_KEY = "jid";
public static final String CLIENT_JID_PROPERTY_KEY = "xmpp.client.jid";
public static final String SUBJECT_PROPERTY_KEY = "xmpp.client.subject";
public static final String MESSAGE_TYPE_PROPERTY_KEY = "xmpp.client.messageType";
public static final String CHAT_PROPERTY_KEY = "chat";
public static final String USERNAME_PROPERTY_KEY = "username";
public static final String DCR_PROPERTY_KEY = "dcrUrl";
public static final String BROKER_URL_PROPERTY_KEY = "url";
public static final String SCOPES_PROPERTY_KEY = "scopes";
public static final String QOS_PROPERTY_KEY = "qos";
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher";
public static final String CONTENT_VALIDATION = "contentValidator";
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
public static final String RESOURCE = "resource";
public static final String JSON_SERIAL_KEY = "SerialNumber";
public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
public static final String JSON_MESSAGE_KEY = "Msg";
public static final String JSON_SIGNATURE_KEY = "Sig";
public static final String HOST_KEY = "host";
public static final String PORT_KEY = "port";
public static final String SERVER_NAME = "serverName";
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
}

@ -1,51 +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.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);
}
}
}

@ -1,6 +1,5 @@
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 {

@ -30,7 +30,7 @@ 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.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;

@ -0,0 +1,56 @@
/*
* 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.xmpp;
public class VirtualFirealarmXMPPException extends Exception{
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public VirtualFirealarmXMPPException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public VirtualFirealarmXMPPException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public VirtualFirealarmXMPPException(String msg) {
super(msg);
setErrorMessage(msg);
}
public VirtualFirealarmXMPPException() {
super();
}
public VirtualFirealarmXMPPException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,63 @@
/*
* 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.xmpp;
/**
* holds the information related to account that needs to be created on xmpp server.
*/
public class XmppAccount {
private String username;
private String password;
private String accountName;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

@ -0,0 +1,124 @@
/*
* 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.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class XmppConfig {
private String host;
private int port;
private String username;
private String password;
private String serverName;
private boolean enabled;
private String jid;
private static XmppConfig xmppConfig = new XmppConfig();
private static final Log log = LogFactory.getLog(XmppConfig.class);
private static final String ENABLED = "enabled";
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String HOST = "host";
private static final String PORT = "port";
private static final String SERVERNAME = "serverName";
private static final String JID = "jid";
private XmppConfig() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("../xmpp.properties");
Properties properties = new Properties();
try {
properties.load(input);
enabled = Boolean.parseBoolean(properties.getProperty(ENABLED, "false"));
host = properties.getProperty(HOST);
port = Integer.parseInt(properties.getProperty(PORT));
username = properties.getProperty(USERNAME);
password = properties.getProperty(PASSWORD);
serverName = properties.getProperty(SERVERNAME);
jid = properties.getProperty(JID);
} catch (IOException e) {
log.error("Failed to load xmpp config properties.");
}
}
public static XmppConfig getInstance() {
return xmppConfig;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getJid() {
return jid;
}
public void setJid(String jid) {
this.jid = jid;
}
}

@ -0,0 +1,66 @@
/*
* 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.xmpp;
import org.jivesoftware.smack.AccountManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import java.util.HashMap;
import java.util.Map;
public class XmppServerClient {
public static boolean createAccount(XmppAccount xmppAccount) throws VirtualFirealarmXMPPException {
if (XmppConfig.getInstance().isEnabled()) {
if (xmppAccount != null) {
try {
ConnectionConfiguration config = new ConnectionConfiguration(XmppConfig.getInstance().getHost(),
XmppConfig.getInstance().getPort(),
"Accounts");
XMPPConnection xmppConnection = new XMPPConnection(config);
xmppConnection.connect();
xmppConnection.login(XmppConfig.getInstance().getUsername(), XmppConfig.getInstance().getPassword());
AccountManager accountManager = xmppConnection.getAccountManager();
Map<String, String> attributes = new HashMap<>();
attributes.put("username", xmppAccount.getUsername());
attributes.put("password", xmppAccount.getPassword());
attributes.put("email", xmppAccount.getEmail());
attributes.put("name", xmppAccount.getAccountName());
accountManager.createAccount(xmppAccount.getUsername(), xmppAccount.getPassword(), attributes);
xmppConnection.disconnect();
return true;
} catch (XMPPException e) {
if (e.getXMPPError().getCode() == 409) {
//AccountAlreadyExist
return true;
} else {
throw new VirtualFirealarmXMPPException(
"XMPP account creation failed. Error: " + e.getLocalizedMessage(), e);
}
}
} else {
throw new VirtualFirealarmXMPPException("Invalid XMPP attributes");
}
} else {
return true;
}
}
}

@ -34,9 +34,7 @@
<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>

@ -0,0 +1,25 @@
#
# Copyright (c) 2016, 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.
#
#
#[XMPP-Configurations]
enabled=false
username=admin
password=admin
host=localhost
port=5222
serverName=localhost
jid=admin@localhost

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -77,12 +77,12 @@
org.apache.commons.codec.binary,
org.json.*;version="${commons-json.version.range}",
org.wso2.carbon.certificate.mgt.core.*,
org.wso2.carbon.certificate.mgt.core.util,
org.wso2.carbon.device.mgt.analytics.data.publisher.exception,
org.wso2.carbon.device.mgt.analytics.data.publisher.service,
org.wso2.carbon.event.input.adapter.core,
org.wso2.carbon.event.input.adapter.core.exception,
org.jivesoftware.smack.*,
javax.xml,
javax.xml.bind,
javax.xml.bind.annotation,
javax.xml.parsers; version="${javax.xml.parsers.import.pkg.version}",

@ -6,6 +6,7 @@ import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.config.exception.VirtualFirealarmConfigurationException;
import org.wso2.carbon.utils.CarbonUtils;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
@ -50,6 +51,7 @@ public class VirtualFirealarmConfig {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -1,65 +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.iot.virtualfirealarm.scep.service.impl;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.InputStream;
public interface VirtualFireAlarmScepServer {
/**
* This is an API called/used by the SCEP Client of the VirtualFirealarm device in its SCEP enrollment process.
* This acts as the endpoint exposed as part of the SCEP-Server for use by a SCEP Client. This is one of the two
* method-signatures that takes different parameters according to the SCEP-Operation executed by the SCEP-Client
* of the enrolling device. The API supports 2 SCEP Operations [GetCACert] and [GetCACaps].
* <p/>
* Operation [GetCACert] returns the CA cert of the SCEP-Server for the device to verify its authenticity.
* Operation [GetCACaps] returns the CA Capabilities of the SCEP-Server.
*
* @param operation the SCEP operation requested by the client. [GetCACert] or [GetCACaps]
* @param message any messages pertaining to the requested SCEP Operation.
* @return an HTTP Response object with either the CA-Cert or the CA-Capabilities according to the operation.
*/
@GET
@Path("scep")
Response scepRequest(@QueryParam("operation") String operation, @QueryParam("message") String message);
/**
* This is an API called/used by the SCEP Client of the VirtualFirealarm device in its SCEP enrollment process.
* This acts as the endpoint exposed as part of the SCEP-Server for use by a SCEP Client. This is one of the two
* method-signatures that takes different parameters according to the SCEP-Operation executed by the SCEP-Client
* of the enrolling device. This API supports the SCEP Operation [PKIOperation].
* <p/>
* Operation [PKIOperation] returns a certificate generated by the SCEP-Server for the enrolling device.
*
* @param operation the final SCEP operation executed in the enrollment process - which is [PKIOperation]
* @param inputStream an input stream consisting of the Certificate-Signing-Request (CSR) from the device.
* @return an HTTP Response object with the signed certificate for the device by the CA of the SCEP Server.
*/
@POST
@Path("scep")
Response scepRequestPost(@QueryParam("operation") String operation, InputStream inputStream);
}

@ -1,136 +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.iot.virtualfirealarm.scep.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.dto.SCEPResponse;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.scep.ContentType;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.scep.SCEPOperation;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.VirtualFireAlarmServiceUtils;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
@SuppressWarnings("Non-Annoted WebService")
public class VirtualFireAlarmScepServerImpl implements VirtualFireAlarmScepServer {
private static Log log = LogFactory.getLog(VirtualFireAlarmScepServerImpl.class);
@GET
@Path("scep")
public Response scepRequest(@QueryParam("operation") String operation, @QueryParam("message") String message) {
if (log.isDebugEnabled()) {
log.debug("Invoking SCEP operation " + operation);
}
if (SCEPOperation.GET_CA_CERT.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking GetCACert");
}
try {
CertificateManagementService certificateManagementService =
VirtualFireAlarmServiceUtils.getCertificateManagementService();
SCEPResponse scepResponse = certificateManagementService.getCACertSCEP();
Response.ResponseBuilder responseBuilder;
switch (scepResponse.getResultCriteria()) {
case CA_CERT_FAILED:
log.error("CA cert failed");
responseBuilder = Response.serverError();
break;
case CA_CERT_RECEIVED:
if (log.isDebugEnabled()) {
log.debug("CA certificate received in GetCACert");
}
responseBuilder = Response.ok(scepResponse.getEncodedResponse(),
ContentType.X_X509_CA_CERT);
break;
case CA_RA_CERT_RECEIVED:
if (log.isDebugEnabled()) {
log.debug("CA and RA certificates received in GetCACert");
}
responseBuilder = Response.ok(scepResponse.getEncodedResponse(),
ContentType.X_X509_CA_RA_CERT);
break;
default:
log.error("Invalid SCEP request");
responseBuilder = Response.serverError();
break;
}
return responseBuilder.build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the VirtualFireAlarm device", e);
} catch (KeystoreException e) {
log.error("Keystore error occurred while enrolling the VirtualFireAlarm device", e);
}
} else if (SCEPOperation.GET_CA_CAPS.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking GetCACaps");
}
try {
CertificateManagementService certificateManagementService = VirtualFireAlarmServiceUtils.
getCertificateManagementService();
byte caCaps[] = certificateManagementService.getCACapsSCEP();
return Response.ok(caCaps, MediaType.TEXT_PLAIN).build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the device", e);
}
} else {
log.error("Invalid SCEP operation " + operation);
}
return Response.serverError().build();
}
@POST
@Path("scep")
public Response scepRequestPost(@QueryParam("operation") String operation, InputStream inputStream) {
if (log.isDebugEnabled()) {
log.debug("Invoking SCEP operation " + operation);
}
if (SCEPOperation.PKI_OPERATION.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking PKIOperation");
}
try {
CertificateManagementService certificateManagementService = VirtualFireAlarmServiceUtils.
getCertificateManagementService();
byte pkiMessage[] = certificateManagementService.getPKIMessageSCEP(inputStream);
return Response.ok(pkiMessage, ContentType.X_PKI_MESSAGE).build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the device", e);
} catch (KeystoreException e) {
log.error("Keystore error occurred while enrolling the device", e);
}
}
return Response.serverError().build();
}
}

@ -1,31 +0,0 @@
/*
* 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.scep.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);
}
}

@ -1,103 +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.iot.virtualfirealarm.scep.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.exception.VirtualFireAlarmException;
import java.lang.*;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
/**
*
*/
public class VirtualFireAlarmServiceUtils {
private static final Log log = LogFactory.getLog(VirtualFireAlarmServiceUtils.class);
/**
*
* @return
* @throws VirtualFireAlarmException
*/
public static CertificateManagementService getCertificateManagementService() throws VirtualFireAlarmException {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
CertificateManagementService certificateManagementService = (CertificateManagementService)
ctx.getOSGiService(CertificateManagementService.class, null);
if (certificateManagementService == null) {
String msg = "EnrollmentService is not initialized";
log.error(msg);
throw new VirtualFireAlarmException(msg);
}
return certificateManagementService;
}
/**
*
* @param deviceId
* @return
* @throws VirtualFireAlarmException
*/
public static PublicKey getDevicePublicKey(String deviceId) throws VirtualFireAlarmException {
PublicKey clientPublicKey;
String alias = "";
try {
alias += deviceId.hashCode();
CertificateManagementService certificateManagementService =
VirtualFireAlarmServiceUtils.getCertificateManagementService();
X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias(
alias);
clientPublicKey = clientCertificate.getPublicKey();
} catch (VirtualFireAlarmException e) {
String errorMsg = "Could not retrieve CertificateManagementService from the runtime.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} catch (KeystoreException e) {
String errorMsg;
if (e.getMessage().contains("NULL_CERT")) {
errorMsg = "The Device-View page might have been accessed prior to the device being started.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} else {
errorMsg = "An error occurred whilst trying to retrieve certificate for deviceId [" + deviceId +
"] with alias: [" + alias + "]";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
}
}
return clientPublicKey;
}
}

@ -1,26 +0,0 @@
/*
* 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.scep.service.impl.util.scep;
public class ContentType {
public static final String X_PKI_MESSAGE = "application/x-pki-message";
public static final String X_X509_CA_CERT = "application/x-x509-ca-cert";
public static final String X_X509_CA_RA_CERT = "application/x-x509-ca-ra-cert";
}

@ -1,39 +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.iot.virtualfirealarm.scep.service.impl.util.scep;
public enum SCEPOperation {
GET_CA_CERT("GetCACert"),
GET_CA_CAPS("GetCACaps"),
PKI_OPERATION("PKIOperation");
private String value;
private SCEPOperation(String value) {
this.setValue(value);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

@ -1,33 +0,0 @@
<?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>

@ -1,38 +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.
-->
<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="VirtualFireAlarmScepServer" address="/">
<jaxrs:serviceBeans>
<bean id="VirtualFireAlarmScepServerService"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.VirtualFireAlarmScepServerImpl">
</bean>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
</beans>

@ -1,46 +0,0 @@
<?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>false</param-value>
</context-param>
<context-param>
<param-name>isSharedWithAllTenants</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>false</param-value>
</context-param>
<context-param>
<param-name>managed-api-owner</param-name>
<param-value>admin</param-value>
</context-param>
</web-app>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -38,7 +38,7 @@
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics</module>
</modules>
<build>

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.5-SNAPSHOT</version>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -186,7 +186,7 @@ public final class HTTPEventAdapter implements InputEventAdapter {
"HttpService not available, Error in registering endpoint " + endpoint);
}
httpService.registerServlet(endpoint, new HTTPMessageServlet(eventAdaptorListener, tenantId,
eventAdapterConfiguration),
eventAdapterConfiguration, globalProperties),
new Hashtable(), httpService.createDefaultHttpContext());
} catch (ServletException | NamespaceException e) {
throw new InputEventAdapterRuntimeException("Error in registering endpoint " + endpoint, e);

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

Loading…
Cancel
Save