Hasunie 8 years ago
commit a30fbfdbec

@ -1,5 +1,7 @@
#carbon-device-mgt-plugins
<a href='https://wso2.org/jenkins/job/platform-builds/job/carbon-device-mgt-plugins/'><img src='https://wso2.org/jenkins/job/platform-builds/job/carbon-device-mgt-plugins/badge/icon'></a>
WSO2 MOBILE DEVICE MANAGER
WSO2 Mobile Device Manager (WSO2 MDM) is a comprehensive platform that helps solve mobile computing challenges enterprises face today when dealing with both corporate owned, personally enabled (COPE) devices and employee owned devices as part of a bring your own device (BYOD) program.

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

@ -1,72 +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.
-->
<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>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.iot.das.rest.api</artifactId>
<name>WSO2 Carbon - IoT Server REST API</name>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
</Private-Package>
<Export-Package>
</Export-Package>
<Import-Package>
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

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

@ -29,7 +29,7 @@ public interface TokenIssuerService {
@POST
@Produces(MediaType.APPLICATION_JSON)
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
@QueryParam("password") String password, @QueryParam("deviceId") String deviceId, @QueryParam("scope") String scope);
@QueryParam("password") String password, @QueryParam("scope") String scope);
@POST
@Produces(MediaType.APPLICATION_JSON)

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

@ -19,10 +19,8 @@
<eventReceiver name="android_sense_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<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="topic">${tenant-domain}/android_sense/+/data</property>
<property name="contentValidator">iot-mqtt</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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -56,7 +56,7 @@ import javax.ws.rs.core.Response;
}
),
tags = {
@Tag(name = "android_sense", description = "")
@Tag(name = "android_sense,device_management", description = "")
}
)
@Scopes(

@ -21,9 +21,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.constants.AndroidSenseConstants;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import org.wso2.carbon.utils.NetworkUtils;
import java.net.SocketException;
import java.util.ArrayList;
@ -176,18 +174,6 @@ public class APIUtil {
return deviceAccessAuthorizationService;
}
public static OutputEventAdapterService getOutputEventAdapterService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
OutputEventAdapterService outputEventAdapterService =
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
if (outputEventAdapterService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return outputEventAdapterService;
}
public static String getTenantDomainOftheUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
return threadLocalCarbonContext.getTenantDomain();

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

@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
var backendEndBasePath = "/api/device-mgt/v1.0";
/*
* set popup maximum height function.
*/
@ -69,4 +71,32 @@ function attachEvents() {
generateQRCode(modalPopupContent + " .qr-code");
modalDialog.show();
}
}
}
function artifactUpload() {
var contentType = "application/json";
var urix = backendEndBasePath + "/admin/devicetype/deploy/android_sense";
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#androidsense-statistic-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var data = {}
invokerUtil.post(urix, data, function (data) {
title.html("Deploying statistic artifacts. Please wait...");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
$(modalPopupContent).html(content.html());
showPopup();
setTimeout(function () {
hidePopup();
location.reload(true);
}, 5000);
}, function (jqXHR) {
title.html("Failed to deploy artifacts, Please contact administrator.");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
$(modalPopupContent).html(content.html());
showPopup();
}, contentType);
}

@ -41,7 +41,9 @@
<a href="#" class="download-link btn-operations"><i class="fw fw-mobile fw-inverse fw-lg add-margin-1x"></i> Enroll Device</a>
<a href="{{hostName}}{{@unit.publicUri}}/asset/androidsense.apk" class="btn-operations"><i class="fw fw-download fw-inverse fw-lg add-margin-1x"></i> Download APK</a>
<a href="javascript:toggleEmailInvite()" class="btn-operations"><i class="fw fw-mail fw-inverse fw-lg add-margin-1x"></i> Invite by Email</a>
{{#if displayStatus}}
<a href="javascript:artifactUpload()" class="btn-operations"><i class="fw fw-upload fw-inverse fw-lg add-margin-1x"></i> Deploy Analytics Artifacts</a>
{{/if}}
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Android+Sense"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</p>
@ -240,7 +242,26 @@
</div>
{{unit "cdmf.unit.device.type.email.invite-modal" deviceTypeView="androidSense"}}
<div id="androidsense-statistic-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
<!--<div class="content">-->
<!--<div class="row">-->

@ -19,6 +19,20 @@
function onRequest(context){
var viewModel = {};
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/android_sense/status";
serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var responseContent = responsePayload.status;
new Log().error(responseContent);
if ("204" == responsePayload.status) {
viewModel["displayStatus"] = "Display";
}
},
function (responsePayload) {
//do nothing.
}
);
viewModel["hostName"] = devicemgtProps["generalConfig"]["host"];
viewModel["enrollmentURL"] = viewModel["hostName"] + context.unit.publicUri + "/asset/androidsense.apk";
return viewModel;

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

@ -26,7 +26,7 @@
<property name="Arduino_dir" value="Arduino"/>
<target name="clean">
<delete dir="${target-dir}" />
<delete dir="${target-dir}"/>
</target>
<target name="zip" depends="clean">

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

@ -17,8 +17,8 @@
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
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>

@ -18,6 +18,6 @@
-->
<artifact name="arduino_execution" version="1.0.0" type="event/execution-plan" serverRole="DataAnalyticsServer">
<file>arduino_execution.siddhiql</file>
<file>arduino_execution.siddhiql</file>
</artifact>

@ -16,9 +16,10 @@
~ specific language governing permissions and limitations
~ under the License.
-->
<eventReceiver name="arduino_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<eventReceiver name="arduino_receiver" statistics="disable" trace="disable"
xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-http">
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.http.util.HTTPContentValidator</property>
<property name="contentValidator">iot-http</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.arduino" version="1.0.0"/>

@ -17,7 +17,7 @@
~ under the License.
-->
<artifact name= "arduino_stream" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.arduino_1.0.0.json</file>
<artifact name="arduino_stream" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.arduino_1.0.0.json</file>
</artifact>

@ -4,12 +4,19 @@
"nickName": "Arduino",
"description": "Temperature data received from the Arduino",
"metaData": [
{"name":"owner","type":"STRING"},
{"name":"deviceId","type":"STRING"}
{
"name": "owner",
"type": "STRING"
},
{
"name": "deviceId",
"type": "STRING"
}
],
"payloadData": [
{
"name": "temperature","type": "FLOAT"
"name": "temperature",
"type": "FLOAT"
}
]
}

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -144,7 +144,7 @@
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
<scope>provided</scope>
</dependency>
</dependencies>

@ -19,7 +19,6 @@
package org.wso2.carbon.device.mgt.iot.arduino.service.impl;
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;
@ -40,7 +39,7 @@ import javax.ws.rs.core.Response;
}
),
tags = {
@Tag(name = "arduino", description = "")
@Tag(name = "arduino,device_management", description = "")
}
)
@Scopes(
@ -110,7 +109,7 @@ public interface ArduinoService {
}
)
Response getArduinoTemperatureStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to);
@QueryParam("to") long to);
/**
* download device agent

@ -148,7 +148,7 @@ public class ArduinoServiceImpl implements ArduinoService {
@QueryParam("to") long to) {
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String fromDate = String.valueOf(from);
@ -179,13 +179,14 @@ public class ArduinoServiceImpl implements ArduinoService {
@Produces("application/zip")
public Response downloadSketch(@QueryParam("deviceName") String deviceName) {
try {
ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName);
Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile()));
String username = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain();
ZipArchive zipFile = createDownloadFile(username, deviceName);
Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent());
response.status(Response.Status.OK);
response.type("application/zip");
response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\"");
Response resp = response.build();
zipFile.getZipFile().delete();
return resp;
} catch (IllegalArgumentException ex) {
return Response.status(400).entity(ex.getMessage()).build();//bad request
@ -198,9 +199,6 @@ public class ArduinoServiceImpl implements ArduinoService {
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -209,7 +207,7 @@ public class ArduinoServiceImpl implements ArduinoService {
private ZipArchive createDownloadFile(String owner, String deviceName)
throws DeviceManagementException, JWTClientException, APIManagerException,
UserStoreException {
UserStoreException {
if (owner == null) {
throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!");
}
@ -221,7 +219,9 @@ public class ArduinoServiceImpl implements ArduinoService {
throw new DeviceManagementException(msg);
}
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
.getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain();
;
if (apiApplicationKey == null) {
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {ArduinoConstants.DEVICE_TYPE};
@ -232,14 +232,14 @@ public class ArduinoServiceImpl implements ArduinoService {
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = " device_" + deviceId + " perm:arduino:enroll";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
apiApplicationKey.getConsumerSecret(), owner, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
String refreshToken = accessTokenInfo.getRefreshToken();
//Register the device with CDMF
ZipUtil ziputil = new ZipUtil();
return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(),
ArduinoConstants.DEVICE_TYPE, deviceId, deviceName, accessToken, refreshToken);
ArduinoConstants.DEVICE_TYPE, deviceId, deviceName, accessToken, refreshToken);
}
private static String shortUUID() {

@ -25,16 +25,16 @@ import java.io.File;
*/
public class ZipArchive {
private File zipFile = null;
private byte[] zipFileContent = null;
private String fileName = null;
public ZipArchive(String fileName, File zipFile) {
public ZipArchive(String fileName, byte[] zipFile) {
this.fileName = fileName;
this.zipFile = zipFile;
this.zipFileContent = zipFile;
}
public File getZipFile() {
return zipFile;
public byte[] getZipFileContent() {
return zipFileContent;
}
public String getFileName() {

@ -34,6 +34,7 @@ import org.wso2.carbon.utils.NetworkUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -57,7 +58,6 @@ import java.util.zip.ZipOutputStream;
*/
public class ZipUtil {
private static final String HTTP_PORT_PROPERTY = "httpPort";
private static final String CONFIG_TYPE = "general";
private static final Log log = LogFactory.getLog(ZipUtil.class);
private static final String LOCALHOST = "localhost";
@ -69,8 +69,6 @@ public class ZipUtil {
String refreshToken) throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP;
@ -113,7 +111,7 @@ public class ZipUtil {
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);
ZipArchive zipFile;
zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName);
return zipFile;
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
@ -122,7 +120,7 @@ public class ZipUtil {
}
}
public static String getServerUrl() {
private static String getServerUrl() {
try {
return org.apache.axis2.util.Utils.getIpAddress();
} catch (SocketException e) {
@ -131,32 +129,26 @@ public class ZipUtil {
}
}
private static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams
private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams
, String zipFileName)
throws DeviceManagementException, IOException {
String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath;
FileUtils.deleteDirectory(new File(archivesPath));//clear directory
FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip
if (!new File(archivesPath).mkdirs()) { //new dir
String message = "Could not create directory at path: " + archivesPath;
log.error(message);
throw new DeviceManagementException(message);
}
zipFileName = zipFileName + ".zip";
try {
Map<String, List<String>> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties");
List<String> templateFiles = properties.get("templates");
List<TemplateFile> processTemplateFiles = new ArrayList<>();
for (String templateFile : templateFiles) {
parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile,
contextParams);
TemplateFile tFile = new TemplateFile();
tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams));
tFile.setFileName(templateFile);
processTemplateFiles.add(tFile);
}
templateFiles.add("sketch.properties"); // ommit copying the props file
copyFolder(new File(sketchPath), new File(archivesPath), templateFiles);
createZipArchive(archivesPath);
FileUtils.deleteDirectory(new File(archivesPath));
File zip = new File(archivesPath + ".zip");
byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles);
return new ZipArchive(zipFileName, zip);
} catch (IOException ex) {
throw new DeviceManagementException(
@ -196,148 +188,124 @@ public class ZipUtil {
}
}
private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException {
private static String parseTemplate(String srcFile, Map contextParams) throws IOException {
//read from file
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(dstFile);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString());
Iterator iterator = contextParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) iterator.next();
content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString());
}
IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString());
return content;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
private static void copyFolder(File src, File dest, List<String> excludeFileNames) throws IOException {
if (src.isDirectory()) {
//if directory not exists, create it
if (!dest.exists() && !dest.mkdirs()) {
String message = "Could not create directory at path: " + dest;
log.error(message);
throw new IOException(message);
}
//list all the directory contents
String files[] = src.list();
if (files == null) {
log.warn("There are no files insides the directory " + src.getAbsolutePath());
return;
}
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile, destFile, excludeFileNames);
}
} else {
for (String fileName : excludeFileNames) {
if (src.getName().equals(fileName)) {
return;
}
}
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
private static boolean createZipArchive(String srcFolder) throws IOException {
BufferedInputStream origin = null;
private static byte[] createZipArchive(String srcFolder, List<TemplateFile> processTemplateFiles) throws IOException {
ZipOutputStream out = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
final int BUFFER = 2048;
FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip"));
out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
out = new ZipOutputStream(new BufferedOutputStream(baos));
File subDir = new File(srcFolder);
String subdirList[] = subDir.list();
if (subdirList == null) {
log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty");
return false;
return null;
}
for (String sd : subdirList) {
// get a list of files from current directory
File f = new File(srcFolder + "/" + sd);
File f = new File(srcFolder + File.separator + sd);
if (f.isDirectory()) {
String files[] = f.list();
if (files == null) {
log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files");
return false;
return null;
}
for (int i = 0; i < files.length; i++) {
FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd + "/" + files[i]);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (files[i].equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd + File.separator + files[i]);
out.putNextEntry(entry);
out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd
+ File.separator + files[i])));
out.closeEntry();
}
} else //it is just a file
{
FileInputStream fi = new FileInputStream(f);
origin = new BufferedInputStream(fi, BUFFER);
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (f.getName().equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
out.write(IOUtils.toByteArray(new FileInputStream(f)));
out.closeEntry();
}
}
out.flush();
out.finish();
} finally {
if (origin != null) {
origin.close();
}
if (out != null) {
out.close();
}
}
return true;
return baos.toByteArray();
}
public class TemplateFile {
private String content;
private String fileName;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
}

@ -26,16 +26,16 @@
it will result 403 error at the runtime.
-->
<PermissionConfiguration>
<APIVersion></APIVersion>
<!-- Device related APIs -->
<APIVersion></APIVersion>
<!-- Device related APIs -->
<Permission>
<name>control bulb</name>
<path>/device-mgt/user/operations</path>
<url>/device/*/bulb</url>
<method>POST</method>
<scope>arduino_user</scope>
</Permission>
<Permission>
<name>control bulb</name>
<path>/device-mgt/user/operations</path>
<url>/device/*/bulb</url>
<method>POST</method>
<scope>arduino_user</scope>
</Permission>
<Permission>
<name>get controls</name>
<path>/device-mgt/user/operations</path>

@ -16,9 +16,9 @@
~ limitations under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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">
@ -30,7 +30,7 @@
</bean>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<web-app version="2.5"
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>Arduino</display-name>
<description>Arduino</description>
<display-name>Arduino</display-name>
<description>Arduino</description>
<servlet>
<servlet-name>CXFServlet</servlet-name>
@ -20,10 +20,6 @@
<param-name>doAuthentication</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>isSharedWithAllTenants</param-name>
<param-value>true</param-value>
</context-param>
<!--publish to apim-->
<context-param>
@ -32,7 +28,8 @@
</context-param>
<listener>
<listener-class>org.wso2.carbon.device.mgt.iot.arduino.service.impl.listener.ArduinoPermissionUpdateListener</listener-class>
<listener-class>org.wso2.carbon.device.mgt.iot.arduino.service.impl.listener.ArduinoPermissionUpdateListener
</listener-class>
</listener>
</web-app>

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

@ -17,8 +17,8 @@
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
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>

@ -18,7 +18,7 @@
function onRequest(context) {
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("deviceId");
@ -26,7 +26,7 @@ function onRequest(context) {
if (devices) {
return {
"devices": stringify(devices),
"backendApiUri": "/arduino/device/stats/"
"backendApiUri": "/arduino/device/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];

@ -48,25 +48,25 @@ function drawGraph_arduino(from, to) {
if (devices) {
for (var i = 0; i < devices.length; i++) {
graphConfig['series'].push(
{
'color': palette.color(),
'data': [{
x: parseInt(new Date().getTime() / 1000),
y: 0
}],
'name': devices[i].name
});
}
} else {
graphConfig['series'].push(
{
'color': palette.color(),
'data': [{
x: parseInt(new Date().getTime() / 1000),
y: 0
}],
'name': $("#arduino-details").data("devicename")
'name': devices[i].name
});
}
} else {
graphConfig['series'].push(
{
'color': palette.color(),
'data': [{
x: parseInt(new Date().getTime() / 1000),
y: 0
}],
'name': $("#arduino-details").data("devicename")
});
}
var graph = new Rickshaw.Graph(graphConfig);
@ -103,9 +103,9 @@ function drawGraph_arduino(from, to) {
graph: graph,
formatter: function (series, x, y) {
var date = '<span class="date">' +
moment((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
moment((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
var swatch = '<span class="detail_swatch" style="background-color: ' +
series.color + '"></span>';
series.color + '"></span>';
return swatch + series.name + ": " + parseInt(y) + '<br>' + date;
}
});
@ -145,7 +145,7 @@ function drawGraph_arduino(from, to) {
return;
}
var backendApiUrl = $("#arduino-div-chart").data("backend-api-url") + devices[deviceIndex].deviceIdentifier
+ "?from=" + from + "&to=" + to;
+ "?from=" + from + "&to=" + to;
var successCallback = function (data) {
if (data) {
drawLineGraph(JSON.parse(data));
@ -167,10 +167,10 @@ function drawGraph_arduino(from, to) {
var chartData = [];
for (var i = 0; i < data.length; i++) {
chartData.push(
{
x: parseInt(data[i].values.time) - tzOffset,
y: parseInt(data[i].values.temperature)
}
{
x: parseInt(data[i].values.time) - tzOffset,
y: parseInt(data[i].values.temperature)
}
);
}

@ -33,14 +33,14 @@
</div>
<div class="add-margin-top-4x">
{{unit "cdmf.unit.device.operation-bar" device=device autoCompleteParams=autoCompleteParams
encodedFeaturePayloads=encodedFeaturePayloads}}
encodedFeaturePayloads=encodedFeaturePayloads}}
</div>
{{/zone}}
{{#zone "device-view-tabs"}}
<li class="active"><a class="list-group-item" href="#device_statistics" role="tab"
data-toggle="tab" aria-controls="device_statistics">Device
Statistics</a>
Statistics</a>
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>

@ -22,20 +22,20 @@ function onRequest(context) {
var deviceId = request.getParameter("id");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var autoCompleteParams = [
{"name" : "deviceId", "value" : deviceId}
{"name": "deviceId", "value": deviceId}
];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
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}};
var anchor = {"device": {"id": device.content.deviceIdentifier, "type": device.content.type}};
return {
"device": device.content,
"autoCompleteParams" : autoCompleteParams,
"autoCompleteParams": autoCompleteParams,
"encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor)
"portalUrl": devicemgtProps['portalURL'],
"anchor": JSON.stringify(anchor)
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");

@ -30,7 +30,7 @@
<div class="wr-input-control">
<label class="wr-input-label" for="email-config-host">
Http Server IP
<span class="helper" title="SMTP Server Host">
<span class="helper" title="SMTP Server Host">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
@ -41,7 +41,7 @@
<label class="wr-input-label" for="email-config-host">
Http Server Port
<span class="helper" title="SMTP Server Host">
<span class="helper" title="SMTP Server Host">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
@ -52,7 +52,7 @@
</div>
<div class="wr-input-control wr-btn-grp">
<button id="save-general-btn" class="wr-btn" onclick="addConfiguration();">
Save
Save
</button>
</div>
</div>

@ -31,7 +31,7 @@ function onRequest(context) {
if (encodedClientKeys) {
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
var resp = tokenUtil.decode(encodedClientKeys).split(":");
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {});
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username, "default", {});
if (tokenPair) {
token = tokenPair.accessToken;
}

@ -25,9 +25,9 @@ $(window).load(function () {
var tNow = new Date().getTime() / 1000;
for (var i = 0; i < 30; i++) {
chartData.push({
x: tNow - (30 - i) * 15,
y: parseFloat(0)
});
x: tNow - (30 - i) * 15,
y: parseFloat(0)
});
}
graph = new Rickshaw.Graph({
@ -90,9 +90,9 @@ function connect(target) {
ws.onmessage = function (event) {
var dataPoint = JSON.parse(event.data);
chartData.push({
x: parseInt(dataPoint[0]) / 1000,
y: parseFloat(dataPoint[5])
});
x: parseInt(dataPoint[0]) / 1000,
y: parseFloat(dataPoint[5])
});
chartData.shift();
graph.update();
};

@ -4,7 +4,7 @@
"category": "iot",
"downloadAgentUri": "arduino/device/download",
"category": "iot",
"scopes" : [
"scopes": [
"perm:arduino:enroll"
]
}

@ -21,15 +21,19 @@
width: 50px;
color: #fff;
}
.padding-top-double {
padding-top: 20px;
}
.padding-double {
padding: 20px;
}
.grey {
color: #333;
}
hr {
display: block;
height: 1px;
@ -39,20 +43,25 @@ hr {
padding: 0;
opacity: 0.2;
}
.light-grey {
color: #7c7c7c;
}
.uppercase {
text-transform: uppercase;
}
.grey-bg {
background-color: #f6f4f4;
}
.doc-link{
.doc-link {
background: none;
color: #000;
padding: 10px 0px;
}
.doc-link a {
color: #006eff;
}

@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
var backendEndBasePath = "/api/device-mgt/v1.0";
/*
* set popup maximum height function.
*/
@ -108,15 +110,15 @@ function attachEvents() {
doAction(data);
}
);
}else if(deviceName){
} else if (deviceName) {
$('.controls').append('<label for="deviceName" generated="true" class="error" ' +
'style="display: inline-block;">Please enter at least 4 ' +
'characters.</label>');
'style="display: inline-block;">Please enter at least 4 ' +
'characters.</label>');
$('.control-group').removeClass('success').addClass('error');
} else {
$('.controls').append('<label for="deviceName" generated="true" class="error" ' +
'style="display: inline-block;">This field is required.' +
'</label>');
'style="display: inline-block;">This field is required.' +
'</label>');
$('.control-group').removeClass('success').addClass('error');
}
});
@ -144,7 +146,7 @@ function downloadAgent() {
setTimeout(function () {
hidePopup();
}, 1000);
}else {
} else {
$("#invalid-username-error-msg span").text("Invalid device name");
$("#invalid-username-error-msg").removeClass("hidden");
}
@ -181,4 +183,31 @@ function doAction(data) {
hidePopup();
});
}
}
function artifactUpload() {
var contentType = "application/json";
var urix = backendEndBasePath + "/admin/devicetype/deploy/arduino";
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#arduino-statistic-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var data = {}
invokerUtil.post(urix, data, function (data) {
title.html("Deploying statistic artifacts. Please wait...");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
$(modalPopupContent).html(content.html());
showPopup();
setTimeout(function () {
hidePopup();
location.reload(true);
}, 5000);
}, function (jqXHR) {
title.html("Failed to deploy artifacts, Please contact administrator.");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
$(modalPopupContent).html(content.html());
showPopup();
}, contentType);
}

@ -32,31 +32,31 @@
<h3 class="uppercase">What it Does</h3>
<hr>
<p class="grey margin-top">Connect Arduino UNO board to WSO2 IoT Server and visualize sensor
data.</p>
data.</p>
<br>
<h3 class="uppercase">What You Need</h3>
<hr>
<ul class="list-unstyled">
<li class="padding-top-double">
<span class="badge">ITEM 01</span>
Arduino UNO Board.
Arduino UNO Board.
</li>
<li>
<span class="badge">ITEM 02</span>
Adafruit Wifi Shield for Arduino.
Adafruit Wifi Shield for Arduino.
</li>
<li>
<span class="badge">ITEM 03</span>
LED bulb connected to Pin 13.
LED bulb connected to Pin 13.
<i>(If not available, will use the one on the board.)</i>
</li>
<li>
<span class="badge">ITEM 04</span>
Resister( e.g 330 ohms )
Resister( e.g 330 ohms )
</li>
<li>
<span class="badge">STEP 05</span>
Proceed to [Prepare] section.
Proceed to [Prepare] section.
</ul>
<br>
<a href="/api-store/apis/info?name={{@uriParams.deviceType}}&version=1.0.0&provider=admin"
@ -66,6 +66,11 @@
<a href="#" class="download-link btn-operations">
<i class="fw fw-download add-margin-1x"></i>Download Sketch
</a>
{{#if displayStatus}}
<a href="javascript:artifactUpload()" class="btn-operations"><i
class="fw fw-upload fw-inverse fw-lg add-margin-1x"></i> Deploy Analytics Artifacts</a>
{{/if}}
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Arduino"
target="_blank">here</a> for latest instructions and
troubleshooting.</p>
@ -197,11 +202,11 @@
<ul class="list-unstyled">
<li class="padding-top-double">
<span class="badge">01</span>
Wifi-Shield mounted onto the Arduino-UNO board
Wifi-Shield mounted onto the Arduino-UNO board
</li>
<li class="padding-top-double">
<span class="badge">02</span>
Connect LED bulb to arduino as follows
Connect LED bulb to arduino as follows
<br/><br/>
<a href="{{@unit.publicUri}}/images/schematicsGuide.png" target="_blank">
<img src="{{@unit.publicUri}}/images/schematicsGuide.png" class="img-responsive">
@ -211,20 +216,20 @@
<li class="padding-top-double">
<span class="badge">03</span>
Download Arduino-Sketch from [Download Sketch] link above.
Download Arduino-Sketch from [Download Sketch] link above.
</li>
<li class="padding-top-double">
<span class="badge">04</span>
Unzip the downloaded Arduino Agent
Unzip the downloaded Arduino Agent
</li>
<li class="padding-top-double">
<span class="badge">05</span>
Create a folder called "ArduinoBoardSketch" and move all source files
Create a folder called "ArduinoBoardSketch" and move all source files
inside
</li>
<li class="padding-top-double">
<span class="badge">06</span>
Open ArduinoBoardSketch.h and provide appropriate values for
Open ArduinoBoardSketch.h and provide appropriate values for
<i>[WLAN_SSID]</i>,
<i>[WLAN_PASS]</i>,
<i>[SERVICE_PORT]</i>,
@ -234,7 +239,7 @@
</li>
<li class="padding-top-double">
<span class="badge">07</span>
Burn the sketch onto your Arduino board and let the program run.
Burn the sketch onto your Arduino board and let the program run.
</li>
<li class="padding-top-double">
@ -242,14 +247,14 @@
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i>
</span>
Arduino will publish it's internal temperature to WSO2-IoT-Server
Arduino will publish it's internal temperature to WSO2-IoT-Server
<br/><br/>
<span class="fw-stack margin-right">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i>
</span>
LED on <i>PIN 13</i> can be controlled from Device Management page.
LED on <i>PIN 13</i> can be controlled from Device Management page.
</li>
</ul>
<br>
@ -263,17 +268,17 @@
<ul class="list-unstyled">
<li class="padding-top-double">
<span class="badge">01</span>
You can view all your connected devices at
You can view all your connected devices at
<a href="{{@app.context}}/devices">[Device Management]</a> page.
</li>
<li class="padding-top-double">
<span class="badge">02</span>
Select one of connected devices and check for available control
Select one of connected devices and check for available control
operations and monitor Real-Time data.
</li>
<li class="padding-top-double">
<span class="badge">03</span>
You can also view analytics of the data published to IoT-Server by
You can also view analytics of the data published to IoT-Server by
navigating to Device Analytics page.
</li>
</ul>
@ -291,6 +296,27 @@
</div>
</div>
<div id="arduino-statistic-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
{{#zone "topCss"}}
{{css "css/styles.css"}}
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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.
*/
function onRequest(context) {
var viewModel = {};
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/arduino/status";
serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var responseContent = responsePayload.status;
new Log().error(responseContent);
if ("204" == responsePayload.status) {
viewModel["displayStatus"] = "Display";
}
},
function (responsePayload) {
//do nothing.
}
);
return viewModel;
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,10 +18,8 @@
-->
<eventReceiver name="raspberrypi_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<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="topic">${tenant-domain}/raspberrypi/+/temperature</property>
<property name="contentValidator">iot-mqtt</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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -39,7 +39,7 @@ import javax.ws.rs.core.Response;
}
),
tags = {
@Tag(name = "raspberrypi", description = "")
@Tag(name = "raspberrypi,device_management", description = "")
}
)
@Scopes(

@ -141,13 +141,14 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
@Produces("application/zip")
public Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType) {
try {
ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType);
Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile()));
String username = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain();
ZipArchive zipFile = createDownloadFile(username, deviceName, sketchType);
Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent());
response.status(Response.Status.OK);
response.type("application/zip");
response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\"");
Response resp = response.build();
zipFile.getZipFile().delete();
return resp;
} catch (IllegalArgumentException ex) {
return Response.status(400).entity(ex.getMessage()).build();//bad request
@ -160,9 +161,6 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -206,7 +204,8 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
}
if (apiApplicationKey == null) {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
.getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantDomain();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {RaspberrypiConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(

@ -17,7 +17,6 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.util.ArrayList;
@ -170,18 +169,6 @@ public class APIUtil {
return deviceAccessAuthorizationService;
}
public static OutputEventAdapterService getOutputEventAdapterService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
OutputEventAdapterService outputEventAdapterService =
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
if (outputEventAdapterService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return outputEventAdapterService;
}
public static PlatformConfigurationManagementService getTenantConfigurationManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
PlatformConfigurationManagementService tenantConfigurationManagementService =

@ -18,23 +18,21 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util;
import java.io.File;
/**
* This is an utility class to hold zip files.
*/
public class ZipArchive {
private File zipFile = null;
private byte[] zipFileContent = null;
private String fileName = null;
public ZipArchive(String fileName, File zipFile) {
public ZipArchive(String fileName, byte[] zipFile) {
this.fileName = fileName;
this.zipFile = zipFile;
this.zipFileContent = zipFile;
}
public File getZipFile() {
return zipFile;
public byte[] getZipFileContent() {
return zipFileContent;
}
public String getFileName() {

@ -18,27 +18,22 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.core.util.Utils;
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.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -69,8 +64,6 @@ public class ZipUtil {
String refreshToken) throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP;
@ -117,7 +110,7 @@ public class ZipUtil {
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);
ZipArchive zipFile;
zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName);
return zipFile;
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
@ -126,7 +119,7 @@ public class ZipUtil {
}
}
public static String getServerUrl() {
private static String getServerUrl() {
try {
return org.apache.axis2.util.Utils.getIpAddress();
} catch (SocketException e) {
@ -135,32 +128,26 @@ public class ZipUtil {
}
}
private static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams
private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams
, String zipFileName)
throws DeviceManagementException, IOException {
String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath;
FileUtils.deleteDirectory(new File(archivesPath));//clear directory
FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip
if (!new File(archivesPath).mkdirs()) { //new dir
String message = "Could not create directory at path: " + archivesPath;
log.error(message);
throw new DeviceManagementException(message);
}
zipFileName = zipFileName + ".zip";
try {
Map<String, List<String>> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties");
List<String> templateFiles = properties.get("templates");
List<TemplateFile> processTemplateFiles = new ArrayList<>();
for (String templateFile : templateFiles) {
parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile,
contextParams);
TemplateFile tFile = new TemplateFile();
tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams));
tFile.setFileName(templateFile);
processTemplateFiles.add(tFile);
}
templateFiles.add("sketch.properties"); // ommit copying the props file
copyFolder(new File(sketchPath), new File(archivesPath), templateFiles);
createZipArchive(archivesPath);
FileUtils.deleteDirectory(new File(archivesPath));
File zip = new File(archivesPath + ".zip");
byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles);
return new ZipArchive(zipFileName, zip);
} catch (IOException ex) {
throw new DeviceManagementException(
@ -200,148 +187,124 @@ public class ZipUtil {
}
}
private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException {
private static String parseTemplate(String srcFile, Map contextParams) throws IOException {
//read from file
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(dstFile);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString());
Iterator iterator = contextParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) iterator.next();
content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString());
}
IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString());
return content;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
private static void copyFolder(File src, File dest, List<String> excludeFileNames) throws IOException {
if (src.isDirectory()) {
//if directory not exists, create it
if (!dest.exists() && !dest.mkdirs()) {
String message = "Could not create directory at path: " + dest;
log.error(message);
throw new IOException(message);
}
//list all the directory contents
String files[] = src.list();
if (files == null) {
log.warn("There are no files insides the directory " + src.getAbsolutePath());
return;
}
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile, destFile, excludeFileNames);
}
} else {
for (String fileName : excludeFileNames) {
if (src.getName().equals(fileName)) {
return;
}
}
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
private static boolean createZipArchive(String srcFolder) throws IOException {
BufferedInputStream origin = null;
private static byte[] createZipArchive(String srcFolder, List<TemplateFile> processTemplateFiles) throws IOException {
ZipOutputStream out = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
final int BUFFER = 2048;
FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip"));
out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
out = new ZipOutputStream(new BufferedOutputStream(baos));
File subDir = new File(srcFolder);
String subdirList[] = subDir.list();
if (subdirList == null) {
log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty");
return false;
return null;
}
for (String sd : subdirList) {
// get a list of files from current directory
File f = new File(srcFolder + "/" + sd);
File f = new File(srcFolder + File.separator + sd);
if (f.isDirectory()) {
String files[] = f.list();
if (files == null) {
log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files");
return false;
return null;
}
for (int i = 0; i < files.length; i++) {
FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd + "/" + files[i]);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (files[i].equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd + File.separator + files[i]);
out.putNextEntry(entry);
out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd
+ File.separator + files[i])));
out.closeEntry();
}
} else //it is just a file
{
FileInputStream fi = new FileInputStream(f);
origin = new BufferedInputStream(fi, BUFFER);
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (f.getName().equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
out.write(IOUtils.toByteArray(new FileInputStream(f)));
out.closeEntry();
}
}
out.flush();
out.finish();
} finally {
if (origin != null) {
origin.close();
}
if (out != null) {
out.close();
}
}
return true;
return baos.toByteArray();
}
public class TemplateFile {
private String content;
private String fileName;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
}

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

@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
var backendEndBasePath = "/api/device-mgt/v1.0";
/*
* set popup maximum height function.
*/
@ -180,4 +182,31 @@ function doAction(data) {
hidePopup();
});
}
}
function artifactUpload() {
var contentType = "application/json";
var urix = backendEndBasePath + "/admin/devicetype/deploy/raspberrypi";
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#raspberrypi-statistic-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var data = {}
invokerUtil.post(urix, data, function (data) {
title.html("Deploying statistic artifacts. Please wait...");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
$(modalPopupContent).html(content.html());
showPopup();
setTimeout(function () {
hidePopup();
location.reload(true);
}, 5000);
}, function (jqXHR) {
title.html("Failed to deploy artifacts, Please contact administrator.");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
$(modalPopupContent).html(content.html());
showPopup();
}, contentType);
}

@ -61,6 +61,10 @@
<a href="#" class="download-link btn-operations">
<i class="fw fw-download add-margin-1x"></i>Download Agent
</a>
{{#if displayStatus}}
<a href="javascript:artifactUpload()" class="btn-operations"><i class="fw fw-upload fw-inverse fw-lg add-margin-1x"></i> Deploy Analytics Artifacts</a>
{{/if}}
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Raspberry+Pi"
target="_blank">here</a> for latest instructions and
troubleshooting.</p>
@ -275,6 +279,27 @@
</center>
</div>
<div id="raspberrypi-statistic-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
{{#zone "topCss"}}
{{css "css/styles.css"}}
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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.
*/
function onRequest(context){
var viewModel = {};
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/raspberrypi/status";
serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var responseContent = responsePayload.status;
new Log().error(responseContent);
if ("204" == responsePayload.status) {
viewModel["displayStatus"] = "Display";
}
},
function (responsePayload) {
//do nothing.
}
);
return viewModel;
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

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

@ -18,10 +18,8 @@
-->
<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="topic">${tenant-domain}/virtual_firealarm/+/temperature</property>
<property name="contentValidator">iot-mqtt</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -51,18 +51,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>

@ -45,7 +45,7 @@ import javax.ws.rs.core.Response;
}
),
tags = {
@Tag(name = "virtual_firealarm", description = "")
@Tag(name = "virtual_firealarm,device_management", description = "")
}
)
@Scopes(

@ -58,15 +58,11 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
@ -134,40 +130,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
}
}
@PUT
@Path("device/{deviceId}/policy")
public Response updatePolicy(@PathParam("deviceId") String deviceId, @QueryParam("protocol") String protocol,
@FormParam("policy") String policy) {
String protocolString = protocol.toUpperCase();
if (log.isDebugEnabled()) {
log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString);
}
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy;
Map<String, String> dynamicProperties = new HashMap<>();
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();
}
}
@Path("device/stats/{deviceId}")
@GET
@Consumes("application/json")
@ -206,13 +168,14 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
public Response downloadSketch(@QueryParam("deviceName") String deviceName,
@QueryParam("sketchType") String sketchType) {
try {
ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType);
Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile()));
String user = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantDomain();
ZipArchive zipFile = createDownloadFile(user, deviceName, sketchType);
Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent());
response.status(Response.Status.OK);
response.type("application/zip");
response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\"");
Response resp = response.build();
zipFile.getZipFile().delete();
return resp;
} catch (IllegalArgumentException ex) {
return Response.status(400).entity(ex.getMessage()).build();//bad request
@ -225,9 +188,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -276,7 +236,8 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
if (apiApplicationKey == null) {
String applicationUsername =
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
.getAdminUserName();
.getAdminUserName() + "@" + PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantDomain();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(

@ -16,7 +16,6 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.util.ArrayList;
@ -169,18 +168,6 @@ public class APIUtil {
return deviceAccessAuthorizationService;
}
public static OutputEventAdapterService getOutputEventAdapterService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
OutputEventAdapterService outputEventAdapterService =
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
if (outputEventAdapterService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return outputEventAdapterService;
}
public static PlatformConfigurationManagementService getTenantConfigurationManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
PlatformConfigurationManagementService tenantConfigurationManagementService =

@ -18,23 +18,23 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import java.io.File;
import java.util.zip.ZipOutputStream;
/**
* This is an utility class to hold zip files.
*/
public class ZipArchive {
private File zipFile = null;
private byte[] zipFileContent = null;
private String fileName = null;
public ZipArchive(String fileName, File zipFile) {
public ZipArchive(String fileName, byte[] zipFile) {
this.fileName = fileName;
this.zipFile = zipFile;
this.zipFileContent = zipFile;
}
public File getZipFile() {
return zipFile;
public byte[] getZipFileContent() {
return zipFileContent;
}
public String getFileName() {

@ -19,7 +19,6 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -33,14 +32,12 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -59,24 +56,18 @@ import java.util.zip.ZipOutputStream;
public class ZipUtil {
private static final Log log = LogFactory.getLog(ZipUtil.class);
private static final String HTTPS_PORT_PROPERTY = "httpsPort";
private static final String HTTP_PORT_PROPERTY = "httpPort";
private static final String LOCALHOST = "localhost";
private static final String HTTPS_PROTOCOL_URL = "https://${iot.gateway.host}:${iot.gateway.https.port}";
private static final String HTTP_PROTOCOL_URL = "http://${iot.gateway.host}:${iot.gateway.http.port}";
private static final String CONFIG_TYPE = "general";
private static final String DEFAULT_MQTT_ENDPOINT = "tcp://${mqtt.broker.host}:${mqtt.broker.port}";
public static final String HOST_NAME = "HostName";
public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName,
String apiApplicationKey, String token, String refreshToken)
throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath =
CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP;
@ -141,7 +132,7 @@ public class ZipUtil {
? "" : XmppConfig.getInstance().getJid());
ZipArchive zipFile;
zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName);
return zipFile;
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
@ -159,7 +150,7 @@ public class ZipUtil {
return Base64.encodeBase64String(stringToEncode.getBytes());
}
public static String getServerUrl() {
private static String getServerUrl() {
try {
return org.apache.axis2.util.Utils.getIpAddress();
} catch (SocketException e) {
@ -168,33 +159,27 @@ public class ZipUtil {
}
}
public static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams
private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams
, String zipFileName)
throws DeviceManagementException, IOException {
String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath;
FileUtils.deleteDirectory(new File(archivesPath));//clear directory
FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip
if (!new File(archivesPath).mkdirs()) { //new dir
String message = "Could not create directory at path: " + archivesPath;
log.error(message);
throw new DeviceManagementException(message);
}
zipFileName = zipFileName + ".zip";
try {
Map<String, List<String>> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties");
List<String> templateFiles = properties.get("templates");
List<TemplateFile> processTemplateFiles = new ArrayList<>();
for (String templateFile : templateFiles) {
parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile,
contextParams);
TemplateFile tFile = new TemplateFile();
tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams));
tFile.setFileName(templateFile);
processTemplateFiles.add(tFile);
}
templateFiles.add("sketch.properties"); // ommit copying the props file
copyFolder(new File(sketchPath), new File(archivesPath), templateFiles);
createZipArchive(archivesPath);
FileUtils.deleteDirectory(new File(archivesPath));
File zip = new File(archivesPath + ".zip");
return new org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive(zipFileName, zip);
byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles);
return new ZipArchive(zipFileName, zip);
} catch (IOException ex) {
throw new DeviceManagementException(
"Error occurred when trying to read property " + "file sketch.properties", ex);
@ -206,9 +191,7 @@ public class ZipUtil {
InputStream input = null;
try {
input = new FileInputStream(propertyFilePath);
// load a properties file
prop.load(input);
Map<String, List<String>> properties = new HashMap<String, List<String>>();
@ -235,148 +218,124 @@ public class ZipUtil {
}
}
private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException {
private static String parseTemplate(String srcFile, Map contextParams) throws IOException {
//read from file
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(dstFile);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString());
Iterator iterator = contextParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) iterator.next();
content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString());
}
IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString());
return content;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
private static void copyFolder(File src, File dest, List<String> excludeFileNames) throws IOException {
if (src.isDirectory()) {
//if directory not exists, create it
if (!dest.exists() && !dest.mkdirs()) {
String message = "Could not create directory at path: " + dest;
log.error(message);
throw new IOException(message);
}
//list all the directory contents
String files[] = src.list();
if (files == null) {
log.warn("There are no files insides the directory " + src.getAbsolutePath());
return;
}
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile, destFile, excludeFileNames);
}
} else {
for (String fileName : excludeFileNames) {
if (src.getName().equals(fileName)) {
return;
}
}
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
private static boolean createZipArchive(String srcFolder) throws IOException {
BufferedInputStream origin = null;
private static byte[] createZipArchive(String srcFolder, List<TemplateFile> processTemplateFiles) throws IOException {
ZipOutputStream out = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
final int BUFFER = 2048;
FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip"));
out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
out = new ZipOutputStream(new BufferedOutputStream(baos));
File subDir = new File(srcFolder);
String subdirList[] = subDir.list();
if (subdirList == null) {
log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty");
return false;
return null;
}
for (String sd : subdirList) {
// get a list of files from current directory
File f = new File(srcFolder + "/" + sd);
File f = new File(srcFolder + File.separator + sd);
if (f.isDirectory()) {
String files[] = f.list();
if (files == null) {
log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files");
return false;
return null;
}
for (int i = 0; i < files.length; i++) {
FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd + "/" + files[i]);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (files[i].equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd + File.separator + files[i]);
out.putNextEntry(entry);
out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd
+ File.separator + files[i])));
out.closeEntry();
}
} else //it is just a file
{
FileInputStream fi = new FileInputStream(f);
origin = new BufferedInputStream(fi, BUFFER);
boolean fileAdded = false;
for (TemplateFile templateFile : processTemplateFiles) {
if (f.getName().equals(templateFile.getFileName())) {
ZipEntry entry = new ZipEntry(templateFile.getFileName());
out.putNextEntry(entry);
out.write(templateFile.getContent().getBytes());
out.closeEntry();
fileAdded = true;
break;
} else if (f.getName().equals("sketch.properties")) {
fileAdded = true;
break;
}
}
if (fileAdded) {
continue;
}
ZipEntry entry = new ZipEntry(sd);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
out.write(IOUtils.toByteArray(new FileInputStream(f)));
out.closeEntry();
}
}
out.flush();
out.finish();
} finally {
if (origin != null) {
origin.close();
}
if (out != null) {
out.close();
}
}
return true;
return baos.toByteArray();
}
public class TemplateFile {
private String content;
private String fileName;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
}

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

@ -1,199 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - IoT Server SCEP Server API</name>
<description>WSO2 Carbon - Virtual FireAlarm SCEP Server API Implementation</description>
<url>http://wso2.org</url>
<dependencies>
<!-- CDM -->
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<scope>provided</scope>
</dependency>
<!--JAX-RS -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bouncycastle.wso2</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.queuing</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.base</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2</artifactId>
</exclusion>
<exclusion>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smack</artifactId>
</exclusion>
<exclusion>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
</exclusion>
<exclusion>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</exclusion>
<exclusion>
<groupId>commons-fileupload.wso2</groupId>
<artifactId>commons-fileupload</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ant.wso2</groupId>
<artifactId>ant</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ant.wso2</groupId>
<artifactId>ant</artifactId>
</exclusion>
<exclusion>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.equinox</groupId>
<artifactId>javax.servlet</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.registry.api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>${wso2.maven.compiler.source}</source>
<target>${wso2.maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>virtual_firealarm_scep</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>

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

@ -39,4 +39,4 @@ function onRequest(context) {
+ "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token;
}
return {"device": device, "websocketEndpoint": websocketEndpoint};
}
}

@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
var backendEndBasePath = "/api/device-mgt/v1.0";
/*
* Set popup maximum height function.
*/
@ -132,4 +134,31 @@ function doAction(data) {
hideAgentDownloadPopup();
});
}
}
function artifactUpload() {
var contentType = "application/json";
var urix = backendEndBasePath + "/admin/devicetype/deploy/virtual_firealarm";
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#virtualfirealarm-statistic-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var data = {}
invokerUtil.post(urix, data, function (data) {
title.html("Deploying statistic artifacts. Please wait...");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
$(modalPopupContent).html(content.html());
showPopup();
setTimeout(function () {
hidePopup();
location.reload(true);
}, 5000);
}, function (jqXHR) {
title.html("Failed to deploy artifacts, Please contact administrator.");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
$(modalPopupContent).html(content.html());
showPopup();
}, contentType);
}

@ -54,6 +54,10 @@
</a>
<a href="#" class="download-link btn-operations">
<i class="fw fw-download"></i>Download Agent</a>
{{#if displayStatus}}
<a href="javascript:artifactUpload()" class="btn-operations"><i class="fw fw-upload fw-inverse fw-lg add-margin-1x"></i> Deploy Analytics Artifacts</a>
{{/if}}
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Virtual+Firealarm"
target="_blank">[ here ]</a> for latest instructions and
troubleshooting.</p>
@ -260,6 +264,27 @@
</center>
</div>
<div id="virtualfirealarm-statistic-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
{{#zone "topCss"}}
{{css "css/styles.css"}}
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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.
*/
function onRequest(context){
var viewModel = {};
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/virtual_firealarm/status";
serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var responseContent = responsePayload.status;
new Log().error(responseContent);
if ("204" == responsePayload.status) {
viewModel["displayStatus"] = "Display";
}
},
function (responsePayload) {
//do nothing.
}
);
return viewModel;
}

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

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

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -27,6 +27,7 @@
<packaging>bundle</packaging>
<name>WSO2 Carbon - App Manager WSO2 MDM REST Connector Component</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
@ -51,6 +52,8 @@
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>org.wso2.carbon.appmgt.mdm.restconnector.internal</Private-Package>
<Import-Package>
org.osgi.framework,
org.osgi.service.component,
org.wso2.carbon.appmgt.mobile.utils.*,
org.wso2.carbon.appmgt.mobile.mdm.*,
org.wso2.carbon.appmgt.mobile.interfaces.*,
@ -62,7 +65,11 @@
feign.auth,
feign.codec,
feign.gson,
*;resolution:=optional
org.json.simple.*,
org.wso2.carbon.appmgt.mobile.beans,
org.wso2.carbon.context,
javax.net.ssl,
feign.slf4j
</Import-Package>
<Export-Package>
!org.wso2.carbon.appmgt.mdm.restconnector.internal,
@ -70,8 +77,7 @@
</Export-Package>
<Embed-Dependency>
jsr311-api,
feign-jaxrs,
org.wso2.carbon.device.mgt.common
feign-jaxrs
</Embed-Dependency>
</instructions>
</configuration>
@ -80,38 +86,14 @@
</build>
<dependencies>
<dependency>
<groupId>commons-io.wso2</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.governance</groupId>
<artifactId>org.wso2.carbon.governance.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.appmgt</groupId>
<artifactId>org.wso2.carbon.appmgt.mobile</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
@ -136,21 +118,14 @@
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.appmgt</groupId>
<artifactId>org.wso2.carbon.appmgt.mobile</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
</dependency>
</dependencies>
</project>

@ -17,16 +17,22 @@
*/
package org.wso2.carbon.appmgt.mdm.restconnector;
import feign.Client;
import feign.Feign;
import feign.Logger;
import feign.Request;
import feign.Response;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.jaxrs.JAXRSContract;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.OAuthRequestInterceptor;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.Activity;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApplicationManagementAdminService;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApplicationWrapper;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.DeviceManagementAdminService;
@ -42,8 +48,16 @@ import org.wso2.carbon.appmgt.mobile.mdm.Device;
import org.wso2.carbon.appmgt.mobile.utils.MobileApplicationException;
import org.wso2.carbon.appmgt.mobile.utils.MobileConfigurations;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -62,13 +76,13 @@ public class ApplicationOperationsImpl implements ApplicationOperations {
public ApplicationOperationsImpl() {
String authorizationConfigManagerServerURL = AuthorizationConfigurationManager.getInstance().getServerURL();
OAuthRequestInterceptor oAuthRequestInterceptor = new OAuthRequestInterceptor();
deviceManagementAdminService = Feign.builder()
.requestInterceptor(oAuthRequestInterceptor)
deviceManagementAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(
Logger.Level.FULL).requestInterceptor(oAuthRequestInterceptor)
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceManagementAdminService.class,
authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT);
applicationManagementAdminService = Feign.builder()
.requestInterceptor(oAuthRequestInterceptor)
applicationManagementAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(
Logger.Level.FULL).requestInterceptor(oAuthRequestInterceptor)
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApplicationManagementAdminService.class,
authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT);
@ -271,4 +285,37 @@ public class ApplicationOperationsImpl implements ApplicationOperations {
log.error(errorMessage);
}
}
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
}

@ -17,13 +17,20 @@
*/
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client;
import feign.Client;
import feign.Feign;
import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.auth.BasicAuthRequestInterceptor;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.jaxrs.JAXRSContract;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.appmgt.mdm.restconnector.Constants;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.AccessTokenInfo;
import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApiApplicationKey;
@ -33,6 +40,16 @@ import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.TokenIs
import org.wso2.carbon.appmgt.mdm.restconnector.config.AuthorizationConfigurationManager;
import org.wso2.carbon.appmgt.mdm.restconnector.internal.AuthorizationDataHolder;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
/**
* This is a request interceptor to add oauth token header.
*/
@ -46,6 +63,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
private static final String REFRESH_GRANT_TYPE = "refresh_token";
private ApiApplicationRegistrationService apiApplicationRegistrationService;
private TokenIssuerService tokenIssuerService;
private static Log log = LogFactory.getLog(OAuthRequestInterceptor.class);
/**
* Creates an interceptor that authenticates all requests.
@ -54,8 +73,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset();
String username = AuthorizationConfigurationManager.getInstance().getUserName();
String password = AuthorizationConfigurationManager.getInstance().getPassword();
apiApplicationRegistrationService = Feign.builder().requestInterceptor(
new BasicAuthRequestInterceptor(username, password))
apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(
Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class,
AuthorizationConfigurationManager.getInstance().getServerURL() +
@ -82,8 +101,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String consumerSecret = apiApplicationKey.getConsumerSecret();
String username = AuthorizationConfigurationManager.getInstance().getUserName();
String password = AuthorizationConfigurationManager.getInstance().getPassword();
tokenIssuerService = Feign.builder().requestInterceptor(
new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
tokenIssuerService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(Logger.Level.FULL)
.requestInterceptor(new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenApiURL());
tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password);
@ -98,4 +117,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String headerValue = Constants.RestConstants.BEARER + tokenInfo.getAccess_token();
template.header(Constants.RestConstants.AUTHORIZATION, headerValue);
}
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
}

@ -0,0 +1,63 @@
/*
* 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.appmgt.mdm.restconnector.authorization.client.dto;
public class Activity {
public enum Type {
CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY
}
private String activityId;
private String code;
private Type type;
private String createdTimeStamp;
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getCreatedTimeStamp() {
return createdTimeStamp;
}
public void setCreatedTimeStamp(String createdTimeStamp) {
this.createdTimeStamp = createdTimeStamp;
}
}

@ -17,7 +17,6 @@
*/
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;

@ -1,39 +0,0 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
/**
* Number of Resources.
*/
public class BasePaginatedResult {
@ApiModelProperty(value = "Number of total resources.", example = "2")
@JsonProperty("count")
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

@ -17,10 +17,7 @@
*/
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto;
import org.wso2.carbon.device.mgt.common.Feature;
import java.io.Serializable;
import java.util.List;
/**
* The DTO class of device.
@ -37,15 +34,6 @@ public class Device implements Serializable {
public Device() {
}
public Device(String name, String type, String description, String deviceId, EnrolmentInfo enrolmentInfo,
List<Feature> features, List<Property> properties) {
this.name = name;
this.type = type;
this.description = description;
this.deviceIdentifier = deviceId;
this.enrolmentInfo = enrolmentInfo;
}
public int getId() {
return id;
}
@ -130,22 +118,4 @@ public class Device implements Serializable {
"]" +
"]";
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof org.wso2.carbon.device.mgt.common.Device))
return false;
org.wso2.carbon.device.mgt.common.Device device = (org.wso2.carbon.device.mgt.common.Device) o;
return getDeviceIdentifier().equals(device.getDeviceIdentifier());
}
@Override
public int hashCode() {
return getDeviceIdentifier().hashCode();
}
}

@ -17,17 +17,21 @@
*/
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.List;
public class DeviceList extends BasePaginatedResult {
public class DeviceList {
private List<Device> devices = new ArrayList<>();
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@ApiModelProperty(value = "List of devices returned")
@JsonProperty("devices")
public List<Device> getList() {
return devices;
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.12-SNAPSHOT</version>
<version>3.0.15-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.12-SNAPSHOT</version>
<version>3.0.15-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -33,6 +33,18 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
@ -45,12 +57,48 @@
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
org.wso2.carbon.device.mgt.input.adapter.extension.internal,
org.wso2.carbon.device.mgt.input.adapter.extension.internal.*
</Private-Package>
<Export-Package>
org.wso2.carbon.device.mgt.input.adapter.extension.*
org.wso2.carbon.device.mgt.input.adapter.extension.*,
!org.wso2.carbon.device.mgt.input.adapter.extension.internal,
</Export-Package>
<Import-Package>
org.osgi.framework,
org.osgi.service.component,
com.jayway.jsonpath,
org.apache.commons.logging,
org.json.simple,
org.json.simple.parser
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
</dependency>
</dependencies>
</project>

@ -25,6 +25,11 @@ import java.util.Map;
*/
public interface ContentTransformer {
/**
* This returns the type of ContentTransformer.
*/
String getType();
/**
* This is used to transform the receiver content
* @param message message to be format

@ -24,6 +24,13 @@ import java.util.Map;
* This interface will be triggered to validate the stream content before publishing.
*/
public interface ContentValidator {
/**
* this returns the unique name of ContentValidatorType.
* @return
*/
String getType();
/**
* @param dynamicParameter that message.
* @return ContentInfo.

@ -0,0 +1,34 @@
package org.wso2.carbon.device.mgt.input.adapter.extension;
/**
* This hold the input adapter extension service.
*/
public interface InputAdapterExtensionService {
/**
* return content validator for the given type.
* @param type type of the content validator
* @return content validator for the given type.
*/
ContentValidator getContentValidator(String type);
/**
* return default content validator for the given type.
* @return default content validator for the given type.
*/
ContentValidator getDefaultContentValidator();
/**
* return content transformer for the given type.
* @param type of the content transfomer
* @return content transformer for the given type.
*/
ContentTransformer getContentTransformer(String type);
/**
* return default content transformer for the given type.
* @return default content transformer for the given type.
*/
ContentTransformer getDefaultContentTransformer();
}

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

Loading…
Cancel
Save