forked from community/device-mgt-plugins
Merge pull request 'virtual fire alarm sample fixing' (#15) from amalka.subasinghe/device-mgt-plugins:master into master
Reviewed-on: community/device-mgt-plugins#15apim420
commit
e0f95e9d4f
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2014, 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>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>device-types</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>WSO2 Carbon - IoT Plugins</name>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<modules>
|
||||
<module>virtual-fire-alarm-plugin</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-scr-plugin</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-scr-scrdescriptor</id>
|
||||
<goals>
|
||||
<goal>scr</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,236 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>virtual-fire-alarm-plugin</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl</artifactId>
|
||||
<name>WSO2 Carbon - IoT Server VirtualFireAlarm Agent</name>
|
||||
<description>WSO2 Carbon - VirtualFireAlarm Device Agent Implementation</description>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>${wso2.maven.compiler.source}</source>
|
||||
<target>${wso2.maven.compiler.target}</target>
|
||||
</configuration>
|
||||
<version>2.3.2</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>
|
||||
org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.Bootstrap
|
||||
</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<finalName>wso2-firealarm-virtual-agent</finalName>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- this is used for inheritance merges -->
|
||||
<phase>package</phase>
|
||||
<!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--Dependency on Log4J - required by IoT Common Component-->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--Dependency on Jetty-Server Library-->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Dependency on MQTT Client Library-->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>${paho.mqtt.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Dependencies on XMPP Client Library-->
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smack</artifactId>
|
||||
<version>${smack.wso2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smackx</artifactId>
|
||||
<version>${smackx.wso2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Dependency on BouncyCastle Library for SCEP-->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle.wso2</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bcprov.wso2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle.wso2</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>${bcpkix.wso2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Dependency on WSO2 JSCEP Orbit-->
|
||||
<dependency>
|
||||
<groupId>com.google.code.jscep.wso2</groupId>
|
||||
<artifactId>jscep</artifactId>
|
||||
<version>${jscep.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons-lang.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>${common-logging.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Dependency on SLF4J - required by BouncyCastle-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json.wso2</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>1.10</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>wso2-nexus</id>
|
||||
<name>WSO2 internal Repository</name>
|
||||
<url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>daily</updatePolicy>
|
||||
<checksumPolicy>ignore</checksumPolicy>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>wso2-maven2-repository</id>
|
||||
<url>http://dist.wso2.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
|
||||
<!-- Java Version Compatibility -->
|
||||
<wso2.maven.compiler.source>1.7</wso2.maven.compiler.source>
|
||||
<wso2.maven.compiler.target>1.7</wso2.maven.compiler.target>
|
||||
|
||||
<!-- Jetty Server Version -->
|
||||
<jetty.version>8.1.3.v20120416</jetty.version>
|
||||
|
||||
<!-- MQTT Paho Version -->
|
||||
<paho.mqtt.version>1.0.2</paho.mqtt.version>
|
||||
|
||||
<!-- Jivesoftware XMPP Version -->
|
||||
<smack.wso2.version>3.0.4.wso2v1</smack.wso2.version>
|
||||
<smackx.wso2.version>3.0.4.wso2v1</smackx.wso2.version>
|
||||
|
||||
<!-- BouncyCastle Version -->
|
||||
<bcprov.wso2.version>1.49.wso2v1</bcprov.wso2.version>
|
||||
<bcpkix.wso2.version>1.49.wso2v1</bcpkix.wso2.version>
|
||||
|
||||
<!-- WSO2 JSCEP Orbit Version -->
|
||||
<jscep.version>2.0.2.wso2v2</jscep.version>
|
||||
|
||||
<!-- Commons Libraries -->
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<common-logging.version>1.2</common-logging.version>
|
||||
<commons.io>2.4</commons.io>
|
||||
<commons-codec.version>1.7</commons-codec.version>
|
||||
<commons-lang.version>2.6</commons-lang.version>
|
||||
|
||||
<!-- SLF4J Version -->
|
||||
<slf4j.version>1.7.13</slf4j.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent;
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
|
||||
public class Bootstrap {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
|
||||
System.setProperty("org.apache.commons.logging.simplelog.defaultlog", "info");
|
||||
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
|
||||
System.setProperty("org.apache.commons.logging.simplelog.dateTimeFormat", "HH:mm:ss");
|
||||
AgentManager.getInstance().init();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.http;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.http.HTTPTransportHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
|
||||
private static final Log log = LogFactory.getLog(FireAlarmHTTPCommunicator.class);
|
||||
|
||||
private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
|
||||
private ScheduledFuture<?> dataPushServiceHandler;
|
||||
private ScheduledFuture<?> connectorServiceHandler;
|
||||
|
||||
public FireAlarmHTTPCommunicator() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FireAlarmHTTPCommunicator(int port) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
public FireAlarmHTTPCommunicator(int port, int reconnectionInterval) {
|
||||
super(port, reconnectionInterval);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getDataPushServiceHandler() {
|
||||
return dataPushServiceHandler;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
Runnable connect = new Runnable() {
|
||||
public void run() {
|
||||
if (!isConnected()) {
|
||||
try {
|
||||
processIncomingMessage();
|
||||
server.start();
|
||||
registerThisDevice();
|
||||
publishDeviceData();
|
||||
log.info("HTTP Server started at port: " + port);
|
||||
|
||||
} catch (Exception e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.warn("Unable to 'START' HTTP server. Will retry after " +
|
||||
timeoutInterval / 1000 + " seconds.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connectorServiceHandler = service.scheduleAtFixedRate(connect, 0, timeoutInterval,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processIncomingMessage() {
|
||||
server.setHandler(new AbstractHandler() {
|
||||
public void handle(String s, Request request, HttpServletRequest
|
||||
httpServletRequest,
|
||||
HttpServletResponse httpServletResponse)
|
||||
throws IOException, ServletException {
|
||||
httpServletResponse.setContentType("text/html;charset=utf-8");
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
request.setHandled(true);
|
||||
|
||||
AgentManager agentManager = AgentManager.getInstance();
|
||||
String pathContext = request.getPathInfo();
|
||||
String separator = File.separatorChar=='\\' ? "\\\\" : File.separator ;
|
||||
|
||||
if (pathContext.toUpperCase().contains(
|
||||
separator + AgentConstants.TEMPERATURE_CONTROL)) {
|
||||
httpServletResponse.getWriter().println(
|
||||
agentManager.getTemperature());
|
||||
|
||||
} else if (pathContext.toUpperCase().contains(
|
||||
separator + AgentConstants.HUMIDITY_CONTROL)) {
|
||||
httpServletResponse.getWriter().println(
|
||||
agentManager.getHumidity());
|
||||
|
||||
} else if (pathContext.toUpperCase().contains(
|
||||
separator + AgentConstants.BULB_CONTROL)) {
|
||||
String[] pathVariables = pathContext.split(separator);
|
||||
|
||||
if (pathVariables.length != 3) {
|
||||
httpServletResponse.getWriter().println(
|
||||
"Invalid BULB-control received by the device. Need to be in " +
|
||||
"'{host}:{port}/BULB/{ON|OFF}' format.");
|
||||
return;
|
||||
}
|
||||
|
||||
String switchState = pathVariables[2];
|
||||
|
||||
if (switchState == null) {
|
||||
httpServletResponse.getWriter().println(
|
||||
"Please specify switch-status of the BULB.");
|
||||
} else {
|
||||
boolean status = switchState.toUpperCase().equals(
|
||||
AgentConstants.CONTROL_ON);
|
||||
agentManager.changeAlarmStatus(status);
|
||||
httpServletResponse.getWriter().println("Bulb is " + (status ?
|
||||
AgentConstants.CONTROL_ON : AgentConstants.CONTROL_OFF));
|
||||
}
|
||||
} else {
|
||||
httpServletResponse.getWriter().println(
|
||||
"Invalid control command received by the device.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDeviceData() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
int publishInterval = agentManager.getPushInterval();
|
||||
final String deviceOwner = agentManager.getAgentConfigs().getDeviceOwner();
|
||||
final String deviceID = agentManager.getAgentConfigs().getDeviceId();
|
||||
boolean simulationMode = false;
|
||||
int duration = 2 * 60;
|
||||
int frequency = 5;
|
||||
|
||||
Runnable pushDataRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
String pushDataPayload = String.format(AgentConstants.PUSH_DATA_PAYLOAD, deviceOwner,
|
||||
deviceID, (agentManager.getDeviceIP() + ":" + port),
|
||||
agentManager.getTemperature());
|
||||
executeDataPush(pushDataPayload);
|
||||
}
|
||||
};
|
||||
|
||||
if (!simulationMode) {
|
||||
dataPushServiceHandler = service.scheduleAtFixedRate(pushDataRunnable, publishInterval,
|
||||
publishInterval,
|
||||
TimeUnit.SECONDS);
|
||||
} else {
|
||||
String pushDataPayload = String.format(AgentConstants.PUSH_SIMULATION_DATA_PAYLOAD, deviceOwner,
|
||||
deviceID, (agentManager.getDeviceIP() + ":" + port),
|
||||
agentManager.getTemperature(), true, duration, frequency);
|
||||
executeDataPush(pushDataPayload);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void executeDataPush(String pushDataPayload) {
|
||||
AgentManager agentManager = AgentManager.getInstance();
|
||||
String pushDataEndPointURL = agentManager.getPushDataAPIEP();
|
||||
HttpURLConnection httpConnection;
|
||||
int responseCode = -1;
|
||||
|
||||
try {
|
||||
httpConnection = TransportUtils.getHttpConnection(agentManager.getPushDataAPIEP());
|
||||
httpConnection.setRequestMethod(AgentConstants.HTTP_POST);
|
||||
httpConnection.setRequestProperty("Authorization",
|
||||
"Bearer " + agentManager.getAgentConfigs().getAuthToken());
|
||||
httpConnection.setRequestProperty("Content-Type", AgentConstants.APPLICATION_JSON);
|
||||
|
||||
httpConnection.setDoOutput(true);
|
||||
DataOutputStream dataOutPutWriter = new DataOutputStream(httpConnection.getOutputStream());
|
||||
dataOutPutWriter.writeBytes(pushDataPayload);
|
||||
dataOutPutWriter.flush();
|
||||
dataOutPutWriter.close();
|
||||
|
||||
responseCode = httpConnection.getResponseCode();
|
||||
httpConnection.disconnect();
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER + "Message - '" + pushDataPayload +
|
||||
"' was published to server at: " + httpConnection.getURL());
|
||||
|
||||
} catch (ProtocolException exception) {
|
||||
String errorMsg =
|
||||
"Protocol specific error occurred when trying to set method to " +
|
||||
AgentConstants.HTTP_POST + " for:" + pushDataEndPointURL;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
|
||||
} catch (IOException exception) {
|
||||
String errorMsg =
|
||||
"An IO error occurred whilst trying to get the response code from: " +
|
||||
pushDataEndPointURL + " for a " + AgentConstants.HTTP_POST + " method.";
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
|
||||
} catch (TransportHandlerException exception) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Error encountered whilst trying to create HTTP-Connection to IoT-Server EP at: " +
|
||||
pushDataEndPointURL);
|
||||
}
|
||||
|
||||
if (responseCode == HttpStatus.CONFLICT_409 ||
|
||||
responseCode == HttpStatus.PRECONDITION_FAILED_412) {
|
||||
log.warn(AgentConstants.LOG_APPENDER +
|
||||
"DeviceIP is being Re-Registered due to Push-Data failure with response code: " +
|
||||
responseCode);
|
||||
registerThisDevice();
|
||||
|
||||
} else if (responseCode != HttpStatus.NO_CONTENT_204) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "Status Code: " + responseCode +
|
||||
" encountered whilst trying to Push-Device-Data to IoT Server at: " +
|
||||
agentManager.getPushDataAPIEP());
|
||||
}
|
||||
agentManager.updateAgentStatus(AgentConstants.SERVER_NOT_RESPONDING);
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(AgentConstants.LOG_APPENDER + "Push-Data call with payload - " + pushDataPayload +
|
||||
", to IoT Server returned status " + responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
Runnable stopConnection = new Runnable() {
|
||||
public void run() {
|
||||
while (isConnected()) {
|
||||
try {
|
||||
dataPushServiceHandler.cancel(true);
|
||||
connectorServiceHandler.cancel(true);
|
||||
closeConnection();
|
||||
} catch (Exception e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Unable to 'STOP' HTTP server at port: " + port);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(timeoutInterval);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error(
|
||||
AgentConstants.LOG_APPENDER + "HTTP-Termination: Thread Sleep Interrupt Exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread terminatorThread = new Thread(stopConnection);
|
||||
terminatorThread.setDaemon(true);
|
||||
terminatorThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIncomingMessage(Object message, String... messageParams) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDeviceData(String... publishData) {
|
||||
|
||||
}
|
||||
|
||||
public void registerThisDevice() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
agentManager.updateAgentStatus("Registering...");
|
||||
|
||||
final Runnable ipRegistration = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (isConnected()) {
|
||||
try {
|
||||
int responseCode = registerDeviceIP(
|
||||
agentManager.getAgentConfigs().getDeviceOwner(),
|
||||
agentManager.getAgentConfigs().getDeviceId());
|
||||
|
||||
if (responseCode == HttpStatus.OK_200) {
|
||||
agentManager.updateAgentStatus(AgentConstants.REGISTERED);
|
||||
break;
|
||||
} else {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Device Registration with IoT Server at:" + " " +
|
||||
agentManager.getIpRegistrationEP() +
|
||||
" failed with response - '" + responseCode + ":" +
|
||||
HttpStatus.getMessage(responseCode) + "'");
|
||||
agentManager.updateAgentStatus(AgentConstants.RETRYING_TO_REGISTER);
|
||||
}
|
||||
} catch (AgentCoreOperationException exception) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Error encountered whilst trying to register the " +
|
||||
"Device's IP at: " +
|
||||
agentManager.getIpRegistrationEP() +
|
||||
".\nCheck whether the network-interface provided is " +
|
||||
"accurate");
|
||||
agentManager.updateAgentStatus(AgentConstants.REGISTRATION_FAILED);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(timeoutInterval);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Device Registration: Thread Sleep Interrupt Exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread ipRegisterThread = new Thread(ipRegistration);
|
||||
ipRegisterThread.setDaemon(true);
|
||||
ipRegisterThread.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method calls the "Register-API" of the IoT Server in order to register the device's IP
|
||||
* against its ID.
|
||||
*
|
||||
* @param deviceOwner the owner of the device by whose name the agent was downloaded.
|
||||
* (Read from configuration file)
|
||||
* @param deviceID the deviceId that is auto-generated whilst downloading the agent.
|
||||
* (Read from configuration file)
|
||||
* @return the status code of the HTTP-Post call to the Register-API of the IoT-Server
|
||||
* @throws AgentCoreOperationException if any errors occur when an HTTPConnection session is
|
||||
* created
|
||||
*/
|
||||
private int registerDeviceIP(String deviceOwner, String deviceID)
|
||||
throws AgentCoreOperationException {
|
||||
int responseCode = -1;
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
|
||||
String networkInterface = agentManager.getNetworkInterface();
|
||||
String deviceIPAddress = getDeviceIP(networkInterface);
|
||||
|
||||
if (deviceIPAddress == null) {
|
||||
throw new AgentCoreOperationException(
|
||||
"An IP address could not be retrieved for the selected network interface - '" +
|
||||
networkInterface + ".");
|
||||
}
|
||||
|
||||
agentManager.setDeviceIP(deviceIPAddress);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Device IP Address: " + deviceIPAddress);
|
||||
|
||||
String deviceIPRegistrationEP = agentManager.getIpRegistrationEP();
|
||||
String registerEndpointURLString =
|
||||
deviceIPRegistrationEP + File.separator + deviceOwner + File.separator + deviceID +
|
||||
File.separator + deviceIPAddress + File.separator + port;
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(AgentConstants.LOG_APPENDER + "DeviceIP Registration EndPoint: " +
|
||||
registerEndpointURLString);
|
||||
}
|
||||
|
||||
HttpURLConnection httpConnection;
|
||||
try {
|
||||
httpConnection = TransportUtils.getHttpConnection(registerEndpointURLString);
|
||||
} catch (TransportHandlerException e) {
|
||||
String errorMsg =
|
||||
"Protocol specific error occurred when trying to fetch an HTTPConnection to:" +
|
||||
" " + registerEndpointURLString;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException();
|
||||
}
|
||||
|
||||
try {
|
||||
httpConnection.setRequestMethod(AgentConstants.HTTP_POST);
|
||||
httpConnection.setRequestProperty("Authorization", "Bearer " +
|
||||
agentManager.getAgentConfigs().getAuthToken());
|
||||
httpConnection.setDoOutput(true);
|
||||
responseCode = httpConnection.getResponseCode();
|
||||
|
||||
} catch (ProtocolException exception) {
|
||||
String errorMsg = "Protocol specific error occurred when trying to set method to " +
|
||||
AgentConstants.HTTP_POST + " for:" + registerEndpointURLString;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, exception);
|
||||
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = "An IO error occurred whilst trying to get the response code from:" +
|
||||
" " + registerEndpointURLString + " for a " + AgentConstants.HTTP_POST + " method.";
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, exception);
|
||||
}
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER + "DeviceIP - " + deviceIPAddress +
|
||||
", registration with IoT Server at : " +
|
||||
agentManager.getAgentConfigs().getHTTPS_ServerEndpoint() +
|
||||
" returned status " +
|
||||
responseCode);
|
||||
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
/* Utility methods relevant to creating and sending HTTP requests to the Iot-Server */
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* This method is used to get the IP of the device in which the agent is run on.
|
||||
*
|
||||
* @return the IP Address of the device
|
||||
* @throws AgentCoreOperationException if any errors occur whilst trying to get the IP address
|
||||
*/
|
||||
private String getDeviceIP() throws AgentCoreOperationException {
|
||||
try {
|
||||
return Inet4Address.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
String errorMsg = "Error encountered whilst trying to get the device IP address.";
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an overloaded method that fetches the public IPv4 address of the given network
|
||||
* interface
|
||||
*
|
||||
* @param networkInterfaceName the network-interface of whose IPv4 address is to be retrieved
|
||||
* @return the IP Address iof the device
|
||||
* @throws AgentCoreOperationException if any errors occur whilst trying to get details of the
|
||||
* given network interface
|
||||
*/
|
||||
private String getDeviceIP(String networkInterfaceName) throws
|
||||
AgentCoreOperationException {
|
||||
String ipAddress = null;
|
||||
try {
|
||||
Enumeration<InetAddress> interfaceIPAddresses = NetworkInterface.getByName(
|
||||
networkInterfaceName).getInetAddresses();
|
||||
for (; interfaceIPAddresses.hasMoreElements(); ) {
|
||||
InetAddress ip = interfaceIPAddresses.nextElement();
|
||||
ipAddress = ip.getHostAddress();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(AgentConstants.LOG_APPENDER + "IP Address: " + ipAddress);
|
||||
}
|
||||
|
||||
if (TransportUtils.validateIPv4(ipAddress)) {
|
||||
return ipAddress;
|
||||
}
|
||||
}
|
||||
} catch (SocketException | NullPointerException exception) {
|
||||
String errorMsg =
|
||||
"Error encountered whilst trying to get IP Addresses of the network interface: " +
|
||||
networkInterfaceName +
|
||||
".\nPlease check whether the name of the network interface used is correct";
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, exception);
|
||||
}
|
||||
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.mqtt;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.mqtt.MQTTTransportHandler;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
//TODO:: Lincence header, comments and SPECIFIC class name since its not generic
|
||||
public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
|
||||
|
||||
private static final Log log = LogFactory.getLog(FireAlarmMQTTCommunicator.class);
|
||||
|
||||
private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
|
||||
private ScheduledFuture<?> dataPushServiceHandler;
|
||||
private static final String DEFAULT_PASSWORD = "";
|
||||
|
||||
public FireAlarmMQTTCommunicator(String deviceOwner, String deviceType,
|
||||
String mqttBrokerEndPoint, String subscribeTopic) {
|
||||
super(deviceOwner, deviceType, mqttBrokerEndPoint, subscribeTopic);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public FireAlarmMQTTCommunicator(String deviceOwner, String deviceType,
|
||||
String mqttBrokerEndPoint, String subscribeTopic,
|
||||
int intervalInMillis) {
|
||||
super(deviceOwner, deviceType, mqttBrokerEndPoint, subscribeTopic, intervalInMillis);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getDataPushServiceHandler() {
|
||||
return dataPushServiceHandler;
|
||||
}
|
||||
|
||||
//TODO:: Terminate logs with a period
|
||||
//TODO: Need to print exceptions
|
||||
@Override
|
||||
public void connect() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
Runnable connector = new Runnable() {
|
||||
public void run() {
|
||||
while (!isConnected()) {
|
||||
try { // uudi formay 8-4-4-4-12
|
||||
connectToQueue(agentManager.getAgentConfigs().getAuthToken().substring(0, 18),
|
||||
agentManager.getAgentConfigs().getAuthToken().substring(19));
|
||||
agentManager.updateAgentStatus("Connected to MQTT Queue");
|
||||
} catch (TransportHandlerException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Connection to MQTT Broker at: " + mqttBrokerEndPoint +
|
||||
" failed.\n Will retry in " + timeoutInterval + " milli-seconds.");
|
||||
|
||||
if (e.getCause() != null && e.getCause() instanceof MqttSecurityException) {
|
||||
refreshOAuthToken((MqttSecurityException) e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (isConnected()) {
|
||||
subscribeToQueue();
|
||||
agentManager.updateAgentStatus("Subscribed to MQTT Queue");
|
||||
publishDeviceData();
|
||||
}
|
||||
} catch (TransportHandlerException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Subscription to MQTT Broker at: " +
|
||||
mqttBrokerEndPoint + " failed");
|
||||
agentManager.updateAgentStatus("Subscription to broker failed.");
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(timeoutInterval);
|
||||
} catch (InterruptedException ex) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "MQTT: Connect-Thread Sleep Interrupt Exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread connectorThread = new Thread(connector);
|
||||
connectorThread.setDaemon(true);
|
||||
connectorThread.start();
|
||||
}
|
||||
|
||||
private void refreshOAuthToken(final MqttSecurityException exception) {
|
||||
Runnable tokenRefresher = new Runnable() {
|
||||
public void run() {
|
||||
String authenticationMethod = AgentUtilOperations.getAuthenticationMethod();
|
||||
|
||||
try {
|
||||
if (exception.getReasonCode() == MqttSecurityException.REASON_CODE_FAILED_AUTHENTICATION &&
|
||||
authenticationMethod.equals(AgentConstants.TOKEN_AUTHENTICATION_METHOD)) {
|
||||
AgentUtilOperations.refreshOAuthToken();
|
||||
}
|
||||
} catch (AgentCoreOperationException e1) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "Token Refresh Attempt Failed. " + e1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread connectorThread = new Thread(tokenRefresher);
|
||||
connectorThread.setDaemon(true);
|
||||
connectorThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIncomingMessage(MqttMessage message, String... messageParams) {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
String tenantDomain = agentManager.getAgentConfigs().getTenantDomain();
|
||||
String deviceOwner = agentManager.getAgentConfigs().getDeviceOwner();
|
||||
String deviceID = agentManager.getAgentConfigs().getDeviceId();
|
||||
String receivedMessage;
|
||||
String replyMessage;
|
||||
String securePayLoad;
|
||||
|
||||
if (message.toString().contains("BULB:ON")) {
|
||||
boolean stateToSwitch = true;
|
||||
agentManager.changeAlarmStatus(stateToSwitch);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Bulb was switched to state: 'ON'");
|
||||
return;
|
||||
} else if (message.toString().contains("BULB:OFF")) {
|
||||
boolean stateToSwitch = false;
|
||||
agentManager.changeAlarmStatus(stateToSwitch);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Bulb was switched to state: 'OFF'");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
receivedMessage = AgentUtilOperations.extractMessageFromPayload(message.toString());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Message [" + receivedMessage + "] was received");
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Could not extract message from payload.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String[] controlSignal = receivedMessage.split(":");
|
||||
// message- "<SIGNAL_TYPE>:<SIGNAL_MODE>" format.(ex: "BULB:ON", "TEMPERATURE", "HUMIDITY")
|
||||
|
||||
try {
|
||||
switch (controlSignal[0].toUpperCase()) {
|
||||
case AgentConstants.BULB_CONTROL:
|
||||
boolean stateToSwitch = controlSignal[1].equals(AgentConstants.CONTROL_ON);
|
||||
agentManager.changeAlarmStatus(stateToSwitch);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Bulb was switched to state: '" + controlSignal[1] + "'");
|
||||
break;
|
||||
|
||||
case AgentConstants.TEMPERATURE_CONTROL:
|
||||
int currentTemperature = agentManager.getTemperature();
|
||||
|
||||
String replyTemperature = "Current temperature was read as: '" + currentTemperature + "C'";
|
||||
log.info(AgentConstants.LOG_APPENDER + replyTemperature);
|
||||
|
||||
String tempPublishTopic = String.format(AgentConstants.MQTT_PUBLISH_TOPIC, tenantDomain, deviceID);
|
||||
|
||||
replyMessage = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
publishToQueue(tempPublishTopic, securePayLoad);
|
||||
break;
|
||||
|
||||
case AgentConstants.HUMIDITY_CONTROL:
|
||||
int currentHumidity = agentManager.getHumidity();
|
||||
|
||||
String replyHumidity = "Current humidity was read as: '" + currentHumidity + "%'";
|
||||
log.info(AgentConstants.LOG_APPENDER + replyHumidity);
|
||||
|
||||
String humidPublishTopic = String.format(
|
||||
AgentConstants.MQTT_PUBLISH_TOPIC, tenantDomain, deviceID);
|
||||
|
||||
replyMessage = AgentConstants.HUMIDITY_CONTROL + ":" + currentHumidity;
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
publishToQueue(humidPublishTopic, securePayLoad);
|
||||
break;
|
||||
|
||||
default:
|
||||
log.warn(AgentConstants.LOG_APPENDER + "'" + controlSignal[0] +
|
||||
"' is invalid and not-supported for this device-type");
|
||||
break;
|
||||
}
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Preparing Secure payload failed", e);
|
||||
} catch (TransportHandlerException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"MQTT - Publishing, reply message to the MQTT Queue at: " +
|
||||
agentManager.getAgentConfigs().getMqttBrokerEndpoint() + " failed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDeviceData() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
int publishInterval = agentManager.getPushInterval();
|
||||
Runnable pushDataRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int currentTemperature = agentManager.getTemperature();
|
||||
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
|
||||
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
|
||||
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": \"" +
|
||||
System.currentTimeMillis() + "\"},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
|
||||
|
||||
try {
|
||||
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
|
||||
|
||||
MqttMessage pushMessage = new MqttMessage();
|
||||
pushMessage.setPayload(payLoad.getBytes(StandardCharsets.UTF_8));
|
||||
pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
|
||||
pushMessage.setRetained(false);
|
||||
|
||||
String topic = String.format(AgentConstants.MQTT_PUBLISH_TOPIC,
|
||||
agentManager.getAgentConfigs().getTenantDomain(),
|
||||
agentManager.getAgentConfigs().getDeviceId());
|
||||
|
||||
publishToQueue(topic, pushMessage);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Message: '" + message + "' published to MQTT Queue at [" +
|
||||
agentManager.getAgentConfigs().getMqttBrokerEndpoint() + "] under topic [" +
|
||||
topic + "]");
|
||||
|
||||
} catch (TransportHandlerException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Data Publish attempt to topic - [" +
|
||||
AgentConstants.MQTT_PUBLISH_TOPIC + "] failed for payload [" + message + "]");
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Preparing Secure payload failed", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dataPushServiceHandler = service.scheduleAtFixedRate(pushDataRunnable, publishInterval, publishInterval,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
Runnable stopConnection = new Runnable() {
|
||||
public void run() {
|
||||
while (isConnected()) {
|
||||
|
||||
if (dataPushServiceHandler != null) {
|
||||
dataPushServiceHandler.cancel(true);
|
||||
}
|
||||
|
||||
try {
|
||||
closeConnection();
|
||||
|
||||
} catch (MqttException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.warn(AgentConstants.LOG_APPENDER +
|
||||
"Unable to 'STOP' MQTT connection at broker at: " +
|
||||
mqttBrokerEndPoint);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(timeoutInterval);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"MQTT-Terminator: Thread Sleep Interrupt Exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread terminatorThread = new Thread(stopConnection);
|
||||
terminatorThread.setDaemon(true);
|
||||
terminatorThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIncomingMessage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDeviceData(String... publishData) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.xmpp;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConfiguration;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.xmpp.XMPPTransportHandler;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
|
||||
|
||||
private static final Log log = LogFactory.getLog(FireAlarmXMPPCommunicator.class);
|
||||
|
||||
private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
|
||||
private ScheduledFuture<?> dataPushServiceHandler;
|
||||
private ScheduledFuture<?> connectorServiceHandler;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String resource;
|
||||
private String xmppAdminJID;
|
||||
private String xmppDeviceJID;
|
||||
|
||||
public FireAlarmXMPPCommunicator(String server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
public FireAlarmXMPPCommunicator(String server, int port) {
|
||||
super(server, port);
|
||||
}
|
||||
|
||||
public FireAlarmXMPPCommunicator(String server, int port, int timeout) {
|
||||
super(server, port, timeout);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getDataPushServiceHandler() {
|
||||
return dataPushServiceHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
username = agentManager.getAgentConfigs().getDeviceId();
|
||||
password = agentManager.getAgentConfigs().getAuthToken();
|
||||
xmppDeviceJID = username + "@" + agentManager.getAgentConfigs().getXmppServerName();
|
||||
xmppAdminJID = agentManager.getAgentConfigs().getServerJID();
|
||||
|
||||
Runnable connect = new Runnable() {
|
||||
public void run() {
|
||||
if (!isConnected()) {
|
||||
try {
|
||||
connectToServer();
|
||||
} catch (TransportHandlerException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Connection to XMPP server at: " + server + " failed");
|
||||
}
|
||||
|
||||
try {
|
||||
loginToServer(username, password, resource);
|
||||
agentManager.updateAgentStatus("Connected to XMPP Server");
|
||||
setMessageFilterAndListener(xmppAdminJID, xmppDeviceJID, true);
|
||||
publishDeviceData();
|
||||
} catch (TransportHandlerException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Login to XMPP server at: " + server + " failed");
|
||||
agentManager.updateAgentStatus("No XMPP Account for Device");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connectorServiceHandler = service.scheduleAtFixedRate(connect, 0, timeoutInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an abstract method used for post processing the received XMPP-message. This
|
||||
* method will be implemented as per requirement at the time of creating an object of this
|
||||
* class.
|
||||
*
|
||||
* @param xmppMessage the xmpp message received by the listener.
|
||||
*/
|
||||
@Override
|
||||
public void processIncomingMessage(Message xmppMessage, String... messageParams) {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
String from = xmppMessage.getFrom();
|
||||
String message = xmppMessage.getBody();
|
||||
String receivedMessage;
|
||||
String replyMessage;
|
||||
String securePayLoad;
|
||||
|
||||
try {
|
||||
receivedMessage = AgentUtilOperations.extractMessageFromPayload(message);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Message [" + receivedMessage + "] was received");
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Could not extract message from payload.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] controlSignal = receivedMessage.split(":");
|
||||
//message- "<SIGNAL_TYPE>:<SIGNAL_MODE>" format. (ex: "BULB:ON", "TEMPERATURE", "HUMIDITY")
|
||||
|
||||
try {
|
||||
switch (controlSignal[0].toUpperCase()) {
|
||||
case AgentConstants.BULB_CONTROL:
|
||||
if (controlSignal.length != 2) {
|
||||
replyMessage = "BULB controls need to be in the form - 'BULB:{ON|OFF}'";
|
||||
log.warn(replyMessage);
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
sendXMPPMessage(xmppAdminJID, securePayLoad, "CONTROL-REPLY");
|
||||
break;
|
||||
}
|
||||
|
||||
agentManager.changeAlarmStatus(controlSignal[1].equals(AgentConstants.CONTROL_ON));
|
||||
log.info(AgentConstants.LOG_APPENDER + "Bulb was switched to state: '" + controlSignal[1] + "'");
|
||||
break;
|
||||
|
||||
case AgentConstants.TEMPERATURE_CONTROL:
|
||||
int currentTemperature = agentManager.getTemperature();
|
||||
|
||||
String replyTemperature =
|
||||
"The current temperature was read to be: '" + currentTemperature +
|
||||
"C'";
|
||||
log.info(AgentConstants.LOG_APPENDER + replyTemperature);
|
||||
|
||||
replyMessage = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
sendXMPPMessage(xmppAdminJID, securePayLoad, "CONTROL-REPLY");
|
||||
break;
|
||||
|
||||
case AgentConstants.HUMIDITY_CONTROL:
|
||||
int currentHumidity = agentManager.getHumidity();
|
||||
|
||||
String replyHumidity = "The current humidity was read to be: '" + currentHumidity + "%'";
|
||||
log.info(AgentConstants.LOG_APPENDER + replyHumidity);
|
||||
|
||||
replyMessage = AgentConstants.HUMIDITY_CONTROL + ":" + currentHumidity;
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
sendXMPPMessage(xmppAdminJID, securePayLoad, "CONTROL-REPLY");
|
||||
break;
|
||||
|
||||
default:
|
||||
replyMessage = "'" + controlSignal[0] + "' is invalid and not-supported for this device-type";
|
||||
log.warn(replyMessage);
|
||||
securePayLoad = AgentUtilOperations.prepareSecurePayLoad(replyMessage);
|
||||
sendXMPPMessage(xmppAdminJID, securePayLoad, "CONTROL-ERROR");
|
||||
break;
|
||||
}
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Preparing Secure payload failed", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void publishDeviceData() {
|
||||
final AgentManager agentManager = AgentManager.getInstance();
|
||||
int publishInterval = agentManager.getPushInterval();
|
||||
|
||||
Runnable pushDataRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Message xmppMessage = new Message();
|
||||
|
||||
try {
|
||||
int currentTemperature = agentManager.getTemperature();
|
||||
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
|
||||
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
|
||||
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
|
||||
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
|
||||
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
|
||||
|
||||
xmppMessage.setTo(xmppAdminJID);
|
||||
xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain());
|
||||
xmppMessage.setBody(payLoad);
|
||||
xmppMessage.setType(Message.Type.chat);
|
||||
|
||||
sendXMPPMessage(xmppAdminJID, xmppMessage);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Message: '" + message + "' sent to XMPP JID - " +
|
||||
"[" + xmppAdminJID + "] under subject [" + xmppMessage.getSubject() + "].");
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Preparing Secure payload failed for XMPP JID - " +
|
||||
"[" + xmppAdminJID + "] with subject - [" + xmppMessage.getSubject() + "].");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dataPushServiceHandler = service.scheduleAtFixedRate(pushDataRunnable, publishInterval,
|
||||
publishInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
Runnable stopConnection = new Runnable() {
|
||||
public void run() {
|
||||
|
||||
if (dataPushServiceHandler != null) {
|
||||
dataPushServiceHandler.cancel(true);
|
||||
}
|
||||
|
||||
if (connectorServiceHandler != null) {
|
||||
connectorServiceHandler.cancel(true);
|
||||
}
|
||||
|
||||
while (isConnected()) {
|
||||
closeConnection();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.warn(AgentConstants.LOG_APPENDER +
|
||||
"Unable to 'STOP' connection to XMPP server at: " + server);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(timeoutInterval);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "XMPP-Terminator: Thread Sleep Interrupt Exception");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread terminatorThread = new Thread(stopConnection);
|
||||
terminatorThread.setDaemon(true);
|
||||
terminatorThread.start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processIncomingMessage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDeviceData(String... publishData) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
|
||||
|
||||
/**
|
||||
* A Configuration class that holds all the Agent specific details that are read from the
|
||||
* 'deviceConfig.properties' file. This file is generated by the IoT-Server at the time of
|
||||
* downloading the device agent from the IoT-Server.
|
||||
*/
|
||||
public class AgentConfiguration {
|
||||
private String tenantDomain;
|
||||
private String deviceOwner;
|
||||
private String deviceId;
|
||||
private String deviceName;
|
||||
private String HTTPS_ServerEndpoint;
|
||||
private String HTTP_ServerEndpoint;
|
||||
private String apimGatewayEndpoint;
|
||||
private String mqttBrokerEndpoint;
|
||||
private String xmppServerEndpoint;
|
||||
private String apiApplicationKey;
|
||||
private String authToken;
|
||||
private String refreshToken;
|
||||
private int dataPushInterval;
|
||||
private String xmppServerName;
|
||||
private String serverJID;
|
||||
|
||||
public String getTenantDomain() {
|
||||
return tenantDomain;
|
||||
}
|
||||
|
||||
public void setTenantDomain(String tenantDomain) {
|
||||
this.tenantDomain = tenantDomain;
|
||||
}
|
||||
|
||||
public String getDeviceOwner() {
|
||||
return deviceOwner;
|
||||
}
|
||||
|
||||
public void setDeviceOwner(String deviceOwner) {
|
||||
this.deviceOwner = deviceOwner;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public String getServerJID() {
|
||||
return serverJID;
|
||||
}
|
||||
|
||||
public void setServerJID(String serverJID) {
|
||||
this.serverJID = serverJID;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public String getHTTPS_ServerEndpoint() {
|
||||
return HTTPS_ServerEndpoint;
|
||||
}
|
||||
|
||||
public void setHTTPS_ServerEndpoint(String HTTPS_ServerEndpoint) {
|
||||
this.HTTPS_ServerEndpoint = HTTPS_ServerEndpoint;
|
||||
}
|
||||
|
||||
public String getHTTP_ServerEndpoint() {
|
||||
return HTTP_ServerEndpoint;
|
||||
}
|
||||
|
||||
public void setHTTP_ServerEndpoint(String HTTP_ServerEndpoint) {
|
||||
this.HTTP_ServerEndpoint = HTTP_ServerEndpoint;
|
||||
}
|
||||
|
||||
public String getApimGatewayEndpoint() {
|
||||
return apimGatewayEndpoint;
|
||||
}
|
||||
|
||||
public void setApimGatewayEndpoint(String apimGatewayEndpoint) {
|
||||
this.apimGatewayEndpoint = apimGatewayEndpoint;
|
||||
}
|
||||
|
||||
public String getMqttBrokerEndpoint() {
|
||||
return mqttBrokerEndpoint;
|
||||
}
|
||||
|
||||
public void setMqttBrokerEndpoint(String mqttBrokerEndpoint) {
|
||||
this.mqttBrokerEndpoint = mqttBrokerEndpoint;
|
||||
}
|
||||
|
||||
public String getXmppServerEndpoint() {
|
||||
return xmppServerEndpoint;
|
||||
}
|
||||
|
||||
public void setXmppServerEndpoint(String xmppServerEndpoint) {
|
||||
this.xmppServerEndpoint = xmppServerEndpoint;
|
||||
}
|
||||
|
||||
public String getApiApplicationKey() {
|
||||
return apiApplicationKey;
|
||||
}
|
||||
|
||||
public void setApiApplicationKey(String apiApplicationKey) {
|
||||
this.apiApplicationKey = apiApplicationKey;
|
||||
}
|
||||
|
||||
public String getAuthToken() {
|
||||
return authToken;
|
||||
}
|
||||
|
||||
public void setAuthToken(String authToken) {
|
||||
this.authToken = authToken;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public int getDataPushInterval() {
|
||||
return dataPushInterval;
|
||||
}
|
||||
|
||||
public void setDataPushInterval(int dataPushInterval) {
|
||||
this.dataPushInterval = dataPushInterval;
|
||||
}
|
||||
|
||||
public String getXmppServerName() {
|
||||
return xmppServerName;
|
||||
}
|
||||
|
||||
public void setXmppServerName(String xmppServerName) {
|
||||
this.xmppServerName = xmppServerName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
|
||||
|
||||
public class AgentConstants {
|
||||
public static final String DEVICE_TYPE = "virtual_firealarm";
|
||||
public static final String LOG_APPENDER = "AGENT_LOG:: ";
|
||||
public static final String PROPERTIES_FILE_PATH = "";
|
||||
public static final int DEFAULT_RETRY_THREAD_INTERVAL = 5000; // time in millis
|
||||
public static final String TOKEN_AUTHENTICATION_METHOD = "token";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
IoT-Server specific information
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String DEVICE_CONTROLLER_API_EP = "/virtual_firealarm/device";
|
||||
public static final String DEVICE_SCEP_API_EP = "/virtual_firealarm_scep";
|
||||
public static final String DEVICE_ENROLLMENT_API_EP = "/scep";
|
||||
public static final String DEVICE_REGISTER_API_EP = "/register";
|
||||
public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature";
|
||||
public static final String PUSH_DATA_PAYLOAD =
|
||||
"{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\"}";
|
||||
|
||||
public static final String PUSH_SIMULATION_DATA_PAYLOAD =
|
||||
"{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\",\"isSimulated\":\"%s\"," +
|
||||
"\"duration\":\"%s\",\"frequency\":\"%s\"}";
|
||||
|
||||
public static final String DEVICE_DETAILS_PAGE_EP = "/devicemgt/device/%s?id=%s";
|
||||
public static final String DEVICE_ANALYTICS_PAGE_URL =
|
||||
"/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%s";
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
HTTP Connection specific information for communicating with IoT-Server
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String HTTP_POST = "POST";
|
||||
public static final String HTTP_GET = "GET";
|
||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
public static final String CONTENT_TYPE_HEADER = "Content-Type";
|
||||
public static final String APPLICATION_JSON = "application/json";
|
||||
public static final String X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
|
||||
public static final String REGISTERED = "Registered";
|
||||
public static final String NOT_REGISTERED = "Not-Registered";
|
||||
public static final String REGISTRATION_FAILED = "Registration Failed";
|
||||
public static final String RETRYING_TO_REGISTER = "Registration Failed. Re-trying..";
|
||||
public static final String SERVER_NOT_RESPONDING = "Server not responding..";
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
MQTT Connection specific information
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
|
||||
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
|
||||
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s/operation/#";
|
||||
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Device/Agent specific properties to be read from the 'deviceConfig.properties' file
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String AGENT_PROPERTIES_FILE_NAME = "deviceConfig.properties";
|
||||
public static final String TENANT_DOMAIN = "tenantDomain";
|
||||
public static final String DEVICE_OWNER_PROPERTY = "owner";
|
||||
public static final String DEVICE_ID_PROPERTY = "deviceId";
|
||||
public static final String SERVER_JID_PROPERTY = "server-jid";
|
||||
public static final String DEVICE_NAME_PROPERTY = "device-name";
|
||||
public static final String SERVER_HTTPS_EP_PROPERTY = "https-ep";
|
||||
public static final String SERVER_HTTP_EP_PROPERTY = "http-ep";
|
||||
public static final String APIM_GATEWAY_EP_PROPERTY = "apim-ep";
|
||||
public static final String MQTT_BROKER_EP_PROPERTY = "mqtt-ep";
|
||||
public static final String XMPP_SERVER_EP_PROPERTY = "xmpp-ep";
|
||||
public static final String XMPP_SERVER_NAME_PROPERTY = "xmpp-server-name";
|
||||
public static final String API_APPLICATION_KEY = "application-key";
|
||||
public static final String AUTH_TOKEN_PROPERTY = "auth-token";
|
||||
public static final String REFRESH_TOKEN_PROPERTY = "refresh-token";
|
||||
public static final String NETWORK_INTERFACE_PROPERTY = "network-interface";
|
||||
public static final String PUSH_INTERVAL_PROPERTY = "push-interval";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Default values for the Device/Agent specific configurations listed above
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String DEFAULT_NETWORK_INTERFACE = "en0";
|
||||
public static final int DEFAULT_DATA_PUBLISH_INTERVAL = 15; // seconds
|
||||
public static final String DEFAULT_PROTOCOL = "MQTT";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Control Signal specific constants to match the request context
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String BULB_CONTROL = "BULB";
|
||||
public static final String TEMPERATURE_CONTROL = "TEMPERATURE";
|
||||
public static final String POLICY_SIGNAL = "POLICY";
|
||||
public static final String HUMIDITY_CONTROL = "HUMIDITY";
|
||||
public static final String CONTROL_ON = "ON";
|
||||
public static final String CONTROL_OFF = "OFF";
|
||||
public static final String AUDIO_FILE_NAME = "fireAlarmSound.mid";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Communication protocol specific Strings
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String TCP_PREFIX = "tcp://";
|
||||
public static final String HTTP_PREFIX = "http://";
|
||||
public static final String HTTPS_PREFIX = "https://";
|
||||
public static final String HTTP_PROTOCOL = "HTTP";
|
||||
public static final String MQTT_PROTOCOL = "MQTT";
|
||||
public static final String XMPP_PROTOCOL = "XMPP";
|
||||
public static final String PROTOCOL_PROPERTY = "Protocol";
|
||||
public static final String HOST_PROPERTY = "Host";
|
||||
public static final String PORT_PROPERTY = "Port";
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Keystore specific strings for the device trustStore
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final String DEVICE_KEYSTORE_TYPE = "JKS";
|
||||
public static final String DEVICE_KEYSTORE = "virtual_firealarm.jks";
|
||||
public static final String DEVICE_KEYSTORE_PASSWORD = "wso2@virtual_firealarm";
|
||||
public static final String DEVICE_PRIVATE_KEY_ALIAS = "virtual_firealarm_key";
|
||||
public static final String DEVICE_CERT_ALIAS = "virtual_firealarm_cert";
|
||||
public static final String SERVER_CA_CERT_ALIAS = "ca_iotServer";
|
||||
}
|
@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.http.FireAlarmHTTPCommunicator;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.mqtt.FireAlarmMQTTCommunicator;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.xmpp.FireAlarmXMPPCommunicator;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.VirtualHardwareManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AgentManager {
|
||||
|
||||
private static final Log log = LogFactory.getLog(AgentManager.class);
|
||||
private static AgentManager agentManager;
|
||||
private String rootPath = "";
|
||||
|
||||
private boolean deviceReady = false;
|
||||
private boolean isAlarmOn = false;
|
||||
|
||||
private String deviceName, agentStatus;
|
||||
|
||||
private int pushInterval; // seconds
|
||||
private String prevProtocol, protocol;
|
||||
|
||||
private String networkInterface;
|
||||
private List<String> interfaceList, protocolList;
|
||||
private Map<String, TransportHandler> agentCommunicator;
|
||||
|
||||
private AgentConfiguration agentConfigs;
|
||||
|
||||
private String deviceIP;
|
||||
private String enrollmentEP;
|
||||
private String ipRegistrationEP;
|
||||
private String pushDataAPIEP;
|
||||
|
||||
private AgentManager() {
|
||||
}
|
||||
|
||||
public static AgentManager getInstance() {
|
||||
if (agentManager == null) {
|
||||
agentManager = new AgentManager();
|
||||
}
|
||||
return agentManager;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
agentCommunicator = new HashMap<>();
|
||||
// Read IoT-Server specific configurations from the 'deviceConfig.properties' file
|
||||
try {
|
||||
this.agentConfigs = AgentUtilOperations.readIoTServerConfigs();
|
||||
} catch (AgentCoreOperationException e) {
|
||||
log.error("Reading device configuration from configuration file failed:\n");
|
||||
log.error(e);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
// Initialise IoT-Server URL endpoints from the configuration read from file
|
||||
AgentUtilOperations.initializeServerEndPoints();
|
||||
// Set the hostNameVerifier to the APIM-Server IPAddress to enable HTTPS handshake
|
||||
AgentUtilOperations.setHTTPSConfigurations();
|
||||
|
||||
String analyticsPageContext = String.format(AgentConstants.DEVICE_ANALYTICS_PAGE_URL,
|
||||
agentConfigs.getDeviceId(),
|
||||
agentConfigs.getDeviceName());
|
||||
|
||||
String controlPageContext = String.format(AgentConstants.DEVICE_DETAILS_PAGE_EP,
|
||||
AgentConstants.DEVICE_TYPE,
|
||||
agentConfigs.getDeviceId());
|
||||
|
||||
this.agentStatus = AgentConstants.NOT_REGISTERED;
|
||||
this.deviceName = this.agentConfigs.getDeviceName();
|
||||
|
||||
this.pushInterval = this.agentConfigs.getDataPushInterval();
|
||||
this.networkInterface = AgentConstants.DEFAULT_NETWORK_INTERFACE;
|
||||
|
||||
this.protocol = AgentConstants.DEFAULT_PROTOCOL;
|
||||
this.prevProtocol = protocol;
|
||||
|
||||
Map<String, String> xmppIPPortMap;
|
||||
try {
|
||||
xmppIPPortMap = TransportUtils.getHostAndPort(agentConfigs.getXmppServerEndpoint());
|
||||
String xmppServer = xmppIPPortMap.get("Host");
|
||||
int xmppPort = Integer.parseInt(xmppIPPortMap.get("Port"));
|
||||
|
||||
TransportHandler xmppCommunicator = new FireAlarmXMPPCommunicator(xmppServer, xmppPort);
|
||||
agentCommunicator.put(AgentConstants.XMPP_PROTOCOL, xmppCommunicator);
|
||||
|
||||
} catch (TransportHandlerException e) {
|
||||
log.info("XMPP Endpoint String - " + agentConfigs.getXmppServerEndpoint() +
|
||||
", provided in the configuration file is invalid. XMPP is not configured.");
|
||||
}
|
||||
String mqttTopic = String.format(AgentConstants.MQTT_SUBSCRIBE_TOPIC, agentConfigs.getTenantDomain(),
|
||||
agentConfigs.getDeviceId());
|
||||
|
||||
// TransportHandler httpCommunicator = new FireAlarmHTTPCommunicator();
|
||||
TransportHandler mqttCommunicator = new FireAlarmMQTTCommunicator(agentConfigs.getDeviceOwner(),
|
||||
agentConfigs.getDeviceId(),
|
||||
agentConfigs.getMqttBrokerEndpoint(),
|
||||
mqttTopic);
|
||||
|
||||
// agentCommunicator.put(AgentConstants.HTTP_PROTOCOL, httpCommunicator);
|
||||
agentCommunicator.put(AgentConstants.MQTT_PROTOCOL, mqttCommunicator);
|
||||
|
||||
try {
|
||||
interfaceList = new ArrayList<>(TransportUtils.getInterfaceIPMap().keySet());
|
||||
protocolList = new ArrayList<>(agentCommunicator.keySet());
|
||||
} catch (TransportHandlerException e) {
|
||||
log.error("An error occurred whilst retrieving all NetworkInterface-IP mappings");
|
||||
}
|
||||
|
||||
//Initializing hardware at that point
|
||||
//AgentManger.setDeviceReady() method should invoked from hardware after initialization
|
||||
VirtualHardwareManager.getInstance().init();
|
||||
|
||||
//Wait till hardware get ready
|
||||
while (!deviceReady) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
log.info(AgentConstants.LOG_APPENDER + "Sleep error in 'device ready-flag' checking thread");
|
||||
}
|
||||
}
|
||||
|
||||
// try {
|
||||
// if (!EnrollmentManager.getInstance().isEnrolled()) {
|
||||
// EnrollmentManager.getInstance().beginEnrollmentFlow();
|
||||
// }
|
||||
// } catch (AgentCoreOperationException e) {
|
||||
// log.error("Device Enrollment Failed:\n");
|
||||
// log.error(e);
|
||||
// System.exit(0);
|
||||
// }
|
||||
|
||||
//Start agent communication
|
||||
agentCommunicator.get(protocol).connect();
|
||||
}
|
||||
|
||||
private void switchCommunicator(String stopProtocol, String startProtocol) {
|
||||
agentCommunicator.get(stopProtocol).disconnect();
|
||||
|
||||
while (agentCommunicator.get(stopProtocol).isConnected()) {
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException e) {
|
||||
log.info(AgentConstants.LOG_APPENDER +
|
||||
"Sleep error in 'Switch-Communicator' Thread's shutdown wait.");
|
||||
}
|
||||
}
|
||||
|
||||
agentCommunicator.get(startProtocol).connect();
|
||||
}
|
||||
|
||||
public void setInterface(int interfaceId) {
|
||||
if (interfaceId != -1) {
|
||||
String newInterface = interfaceList.get(interfaceId);
|
||||
|
||||
if (!newInterface.equals(networkInterface)) {
|
||||
networkInterface = newInterface;
|
||||
|
||||
if (protocol.equals(AgentConstants.HTTP_PROTOCOL) && !protocol.equals(
|
||||
prevProtocol)) {
|
||||
switchCommunicator(prevProtocol, protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setProtocol(int protocolId) {
|
||||
if (protocolId != -1) {
|
||||
String newProtocol = protocolList.get(protocolId);
|
||||
|
||||
if (!protocol.equals(newProtocol)) {
|
||||
prevProtocol = protocol;
|
||||
protocol = newProtocol;
|
||||
switchCommunicator(prevProtocol, protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void changeAlarmStatus(boolean isOn) {
|
||||
VirtualHardwareManager.getInstance().changeAlarmStatus(isOn);
|
||||
isAlarmOn = isOn;
|
||||
}
|
||||
|
||||
public void updateAgentStatus(String status) {
|
||||
this.agentStatus = status;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
/* Getter and Setter Methods for the private variables */
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
|
||||
public void setRootPath(String rootPath) {
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
public String getRootPath() {
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
public void setDeviceReady(boolean deviceReady) {
|
||||
this.deviceReady = deviceReady;
|
||||
}
|
||||
|
||||
public AgentConfiguration getAgentConfigs() {
|
||||
return agentConfigs;
|
||||
}
|
||||
|
||||
public String getDeviceIP() {
|
||||
return deviceIP;
|
||||
}
|
||||
|
||||
public void setDeviceIP(String deviceIP) {
|
||||
this.deviceIP = deviceIP;
|
||||
}
|
||||
|
||||
public String getEnrollmentEP() {
|
||||
return enrollmentEP;
|
||||
}
|
||||
|
||||
public void setEnrollmentEP(String enrollmentEP) {
|
||||
this.enrollmentEP = enrollmentEP;
|
||||
}
|
||||
|
||||
public String getIpRegistrationEP() {
|
||||
return ipRegistrationEP;
|
||||
}
|
||||
|
||||
public void setIpRegistrationEP(String ipRegistrationEP) {
|
||||
this.ipRegistrationEP = ipRegistrationEP;
|
||||
}
|
||||
|
||||
public String getPushDataAPIEP() {
|
||||
return pushDataAPIEP;
|
||||
}
|
||||
|
||||
public void setPushDataAPIEP(String pushDataAPIEP) {
|
||||
this.pushDataAPIEP = pushDataAPIEP;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public String getNetworkInterface() {
|
||||
return networkInterface;
|
||||
}
|
||||
|
||||
public String getAgentStatus() {
|
||||
return agentStatus;
|
||||
}
|
||||
|
||||
public int getPushInterval() {
|
||||
return pushInterval;
|
||||
}
|
||||
|
||||
public void setPushInterval(int pushInterval) {
|
||||
this.pushInterval = pushInterval;
|
||||
TransportHandler transportHandler = agentCommunicator.get(protocol);
|
||||
|
||||
switch (protocol) {
|
||||
case AgentConstants.HTTP_PROTOCOL:
|
||||
((FireAlarmHTTPCommunicator) transportHandler).getDataPushServiceHandler()
|
||||
.cancel(true);
|
||||
break;
|
||||
case AgentConstants.MQTT_PROTOCOL:
|
||||
((FireAlarmMQTTCommunicator) transportHandler).getDataPushServiceHandler()
|
||||
.cancel(true);
|
||||
break;
|
||||
case AgentConstants.XMPP_PROTOCOL:
|
||||
((FireAlarmXMPPCommunicator) transportHandler).getDataPushServiceHandler()
|
||||
.cancel(true);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unknown protocol " + protocol);
|
||||
}
|
||||
transportHandler.publishDeviceData();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("The Data Publish Interval was changed to: " + pushInterval);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getInterfaceList() {
|
||||
return interfaceList;
|
||||
}
|
||||
|
||||
public List<String> getProtocolList() {
|
||||
return protocolList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get temperature reading from device
|
||||
*
|
||||
* @return Temperature
|
||||
*/
|
||||
public int getTemperature() {
|
||||
return VirtualHardwareManager.getInstance().getTemperature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get humidity reading from device
|
||||
*
|
||||
* @return Humidity
|
||||
*/
|
||||
public int getHumidity() {
|
||||
return VirtualHardwareManager.getInstance().getHumidity();
|
||||
}
|
||||
|
||||
public boolean isAlarmOn() {
|
||||
return isAlarmOn;
|
||||
}
|
||||
}
|
@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.json.JSONObject;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.CommunicationUtils;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This class contains all the core operations of the FireAlarm agent that are common to both
|
||||
* Virtual and Real Scenarios. These operations include, connecting to and subscribing to an MQTT
|
||||
* queue and to a XMPP Server. Pushing temperature data to the IoT-Server at timely intervals.
|
||||
* Reading device specific configuration from a configs file etc....
|
||||
*/
|
||||
public class AgentUtilOperations {
|
||||
|
||||
private static final Log log = LogFactory.getLog(AgentUtilOperations.class);
|
||||
private static final String JSON_MESSAGE_KEY = "Msg";
|
||||
private static final String JSON_SIGNATURE_KEY = "Sig";
|
||||
private static final String JSON_SERIAL_KEY = "SerialNumber";
|
||||
|
||||
/**
|
||||
* This method reads the agent specific configurations for the device from the
|
||||
* "deviceConfigs.properties" file found at /repository/conf folder.
|
||||
* If the properties file is not found in the specified path, then the configuration values
|
||||
* are set to the default ones in the 'AgentConstants' class.
|
||||
*
|
||||
* @return an object of type 'AgentConfiguration' which contains all the necessary
|
||||
* configuration attributes
|
||||
*/
|
||||
public static AgentConfiguration readIoTServerConfigs() throws AgentCoreOperationException {
|
||||
AgentManager agentManager = AgentManager.getInstance();
|
||||
AgentConfiguration iotServerConfigs = new AgentConfiguration();
|
||||
Properties properties = new Properties();
|
||||
InputStream propertiesInputStream = null;
|
||||
String propertiesFileName = AgentConstants.AGENT_PROPERTIES_FILE_NAME;
|
||||
String rootPath = "";
|
||||
|
||||
try {
|
||||
ClassLoader loader = AgentUtilOperations.class.getClassLoader();
|
||||
URL path = loader.getResource(propertiesFileName);
|
||||
|
||||
if (path != null) {
|
||||
log.info(AgentConstants.LOG_APPENDER + path);
|
||||
rootPath = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "")
|
||||
.replace("jar:", "").replace("file:", "");
|
||||
|
||||
rootPath = URLDecoder.decode(rootPath, StandardCharsets.UTF_8.toString());
|
||||
agentManager.setRootPath(rootPath);
|
||||
|
||||
String deviceConfigFilePath = rootPath + AgentConstants.AGENT_PROPERTIES_FILE_NAME;
|
||||
propertiesInputStream = new FileInputStream(deviceConfigFilePath);
|
||||
|
||||
//load a properties file from class path, inside static method
|
||||
properties.load(propertiesInputStream);
|
||||
|
||||
iotServerConfigs.setTenantDomain(properties.getProperty(
|
||||
AgentConstants.TENANT_DOMAIN));
|
||||
iotServerConfigs.setDeviceOwner(properties.getProperty(
|
||||
AgentConstants.DEVICE_OWNER_PROPERTY));
|
||||
iotServerConfigs.setDeviceId(properties.getProperty(
|
||||
AgentConstants.DEVICE_ID_PROPERTY));
|
||||
iotServerConfigs.setServerJID(properties.getProperty(
|
||||
AgentConstants.SERVER_JID_PROPERTY));
|
||||
iotServerConfigs.setDeviceName(properties.getProperty(
|
||||
AgentConstants.DEVICE_NAME_PROPERTY));
|
||||
iotServerConfigs.setHTTPS_ServerEndpoint(properties.getProperty(
|
||||
AgentConstants.SERVER_HTTPS_EP_PROPERTY));
|
||||
iotServerConfigs.setHTTP_ServerEndpoint(properties.getProperty(
|
||||
AgentConstants.SERVER_HTTP_EP_PROPERTY));
|
||||
iotServerConfigs.setApimGatewayEndpoint(properties.getProperty(
|
||||
AgentConstants.APIM_GATEWAY_EP_PROPERTY));
|
||||
iotServerConfigs.setMqttBrokerEndpoint(properties.getProperty(
|
||||
AgentConstants.MQTT_BROKER_EP_PROPERTY));
|
||||
iotServerConfigs.setXmppServerEndpoint(properties.getProperty(
|
||||
AgentConstants.XMPP_SERVER_EP_PROPERTY));
|
||||
iotServerConfigs.setXmppServerName(properties.getProperty(
|
||||
AgentConstants.XMPP_SERVER_NAME_PROPERTY));
|
||||
iotServerConfigs.setApiApplicationKey(properties.getProperty(
|
||||
AgentConstants.API_APPLICATION_KEY));
|
||||
iotServerConfigs.setAuthToken(properties.getProperty(
|
||||
AgentConstants.AUTH_TOKEN_PROPERTY));
|
||||
iotServerConfigs.setRefreshToken(properties.getProperty(
|
||||
AgentConstants.REFRESH_TOKEN_PROPERTY));
|
||||
iotServerConfigs.setDataPushInterval(Integer.parseInt(properties.getProperty(
|
||||
AgentConstants.PUSH_INTERVAL_PROPERTY)));
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER + "Tenant Domain: " +
|
||||
iotServerConfigs.getTenantDomain());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Device Owner: " +
|
||||
iotServerConfigs.getDeviceOwner());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Device ID: " +
|
||||
iotServerConfigs.getDeviceId());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Device Name: " +
|
||||
iotServerConfigs.getDeviceName());
|
||||
log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTPS EndPoint: " +
|
||||
iotServerConfigs.getHTTPS_ServerEndpoint());
|
||||
log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTP EndPoint: " +
|
||||
iotServerConfigs.getHTTP_ServerEndpoint());
|
||||
log.info(AgentConstants.LOG_APPENDER + "API-Manager Gateway EndPoint: " +
|
||||
iotServerConfigs.getApimGatewayEndpoint());
|
||||
log.info(AgentConstants.LOG_APPENDER + "MQTT Broker EndPoint: " +
|
||||
iotServerConfigs.getMqttBrokerEndpoint());
|
||||
log.info(AgentConstants.LOG_APPENDER + "XMPP Server EndPoint: " +
|
||||
iotServerConfigs.getXmppServerEndpoint());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Base64Encoded API Application Key: " +
|
||||
iotServerConfigs.getApiApplicationKey());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " +
|
||||
iotServerConfigs.getAuthToken());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " +
|
||||
iotServerConfigs.getRefreshToken());
|
||||
log.info(AgentConstants.LOG_APPENDER + "Data Push Interval: " +
|
||||
iotServerConfigs.getDataPushInterval());
|
||||
log.info(AgentConstants.LOG_APPENDER + "XMPP Server Name: " +
|
||||
iotServerConfigs.getXmppServerName());
|
||||
} else {
|
||||
throw new AgentCoreOperationException(
|
||||
"Failed to load path of resource [" + propertiesFileName + "] from this classpath.");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
String errorMsg = "[" + propertiesFileName + "] file not found at: " + rootPath;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg);
|
||||
|
||||
} catch (IOException ex) {
|
||||
String errorMsg = "Error occurred whilst trying to fetch [" + propertiesFileName + "] from: " +
|
||||
AgentConstants.PROPERTIES_FILE_PATH;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg);
|
||||
} finally {
|
||||
if (propertiesInputStream != null) {
|
||||
try {
|
||||
propertiesInputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Error occurred whilst trying to close InputStream resource used to read the '" +
|
||||
propertiesFileName + "' file");
|
||||
}
|
||||
}
|
||||
}
|
||||
return iotServerConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method constructs the URLs for each of the API Endpoints called by the device agent
|
||||
* Ex: Register API, Push-Data API
|
||||
*/
|
||||
public static void initializeServerEndPoints() {
|
||||
AgentManager agentManager = AgentManager.getInstance();
|
||||
String serverSecureEndpoint = agentManager.getAgentConfigs().getHTTPS_ServerEndpoint();
|
||||
String serverUnSecureEndpoint = agentManager.getAgentConfigs().getHTTP_ServerEndpoint();
|
||||
String backEndContext =AgentConstants.DEVICE_CONTROLLER_API_EP;
|
||||
String scepBackEndContext = AgentConstants.DEVICE_SCEP_API_EP;
|
||||
|
||||
String deviceControllerAPIEndpoint = serverSecureEndpoint + backEndContext;
|
||||
|
||||
String deviceEnrollmentEndpoint =
|
||||
serverUnSecureEndpoint + scepBackEndContext + AgentConstants.DEVICE_ENROLLMENT_API_EP;
|
||||
agentManager.setEnrollmentEP(deviceEnrollmentEndpoint);
|
||||
|
||||
String registerEndpointURL =
|
||||
deviceControllerAPIEndpoint + AgentConstants.DEVICE_REGISTER_API_EP;
|
||||
agentManager.setIpRegistrationEP(registerEndpointURL);
|
||||
|
||||
String pushDataEndPointURL =
|
||||
deviceControllerAPIEndpoint + AgentConstants.DEVICE_PUSH_TEMPERATURE_API_EP;
|
||||
agentManager.setPushDataAPIEP(pushDataEndPointURL);
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER + "IoT Server's Device Controller API Endpoint: " +
|
||||
deviceControllerAPIEndpoint);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Device Enrollment EndPoint: " +
|
||||
registerEndpointURL);
|
||||
log.info(AgentConstants.LOG_APPENDER + "DeviceIP Registration EndPoint: " +
|
||||
registerEndpointURL);
|
||||
log.info(AgentConstants.LOG_APPENDER + "Push-Data API EndPoint: " + pushDataEndPointURL);
|
||||
}
|
||||
|
||||
public static void setHTTPSConfigurations() {
|
||||
String apimEndpoint = AgentManager.getInstance().getAgentConfigs().getApimGatewayEndpoint();
|
||||
System.setProperty("javax.net.ssl.trustStore", AgentConstants.DEVICE_KEYSTORE);
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", AgentConstants.DEVICE_KEYSTORE_PASSWORD);
|
||||
|
||||
try {
|
||||
final String apimHost = TransportUtils.getHostAndPort(apimEndpoint).get(AgentConstants.HOST_PROPERTY);
|
||||
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return hostname.equals(apimHost);
|
||||
}
|
||||
});
|
||||
} catch (TransportHandlerException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Failed to set HTTPS HostNameVerifier to the APIMServer-Host using the APIM-Endpoint " +
|
||||
"string [" + apimEndpoint + "].");
|
||||
log.error(AgentConstants.LOG_APPENDER + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
|
||||
if (EnrollmentManager.getInstance().isEnrolled()) {
|
||||
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
|
||||
String encodedMessage = Base64.encodeBase64String(message.getBytes());
|
||||
String signedPayload;
|
||||
try {
|
||||
signedPayload = CommunicationUtils.signMessage(encodedMessage, devicePrivateKey);
|
||||
} catch (TransportHandlerException e) {
|
||||
String errorMsg = "Error occurred whilst trying to sign encrypted message of: [" + message + "]";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
|
||||
JSONObject jsonPayload = new JSONObject();
|
||||
jsonPayload.put(JSON_MESSAGE_KEY, encodedMessage);
|
||||
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
|
||||
//below statements are temporary fix.
|
||||
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
|
||||
return jsonPayload.toString();
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public static String extractMessageFromPayload(String message) throws AgentCoreOperationException {
|
||||
if (EnrollmentManager.getInstance().isEnrolled()) {
|
||||
String actualMessage;
|
||||
|
||||
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
|
||||
JSONObject jsonPayload = new JSONObject(message);
|
||||
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
|
||||
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
|
||||
boolean verification;
|
||||
|
||||
if (encodedMessage != null && signedPayload != null) {
|
||||
try {
|
||||
verification = CommunicationUtils.verifySignature(
|
||||
encodedMessage.toString(), signedPayload.toString(), serverPublicKey);
|
||||
} catch (TransportHandlerException e) {
|
||||
String errorMsg =
|
||||
"Error occurred whilst trying to verify signature on received message: [" + message + "]";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
} else {
|
||||
String errorMsg = "The received message is in an INVALID format. " +
|
||||
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
|
||||
throw new AgentCoreOperationException(errorMsg);
|
||||
}
|
||||
if (verification) {
|
||||
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()), StandardCharsets.UTF_8);
|
||||
} else {
|
||||
String errorMsg = "Could not verify payload signature. The message was not signed by a valid client";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg);
|
||||
}
|
||||
return actualMessage;
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAuthenticationMethod() {
|
||||
String authMethod = "token";
|
||||
switch (authMethod) {
|
||||
case AgentConstants.TOKEN_AUTHENTICATION_METHOD:
|
||||
return AgentConstants.TOKEN_AUTHENTICATION_METHOD;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static void refreshOAuthToken() throws AgentCoreOperationException {
|
||||
|
||||
AgentManager agentManager = AgentManager.getInstance();
|
||||
String tokenEndpoint = agentManager.getAgentConfigs().getApimGatewayEndpoint();
|
||||
tokenEndpoint = tokenEndpoint + APIManagerTokenUtils.TOKEN_ENDPOINT;
|
||||
|
||||
HttpURLConnection httpConnection = null;
|
||||
BufferedReader connectionBuffer = null;
|
||||
String requestPayload;
|
||||
String dataFromBuffer;
|
||||
StringBuilder responseMessage = new StringBuilder();
|
||||
|
||||
try {
|
||||
String refreshToken = agentManager.getAgentConfigs().getRefreshToken();
|
||||
String applicationScope = "device_type_" + AgentConstants.DEVICE_TYPE +
|
||||
" device_" + agentManager.getAgentConfigs().getDeviceId();
|
||||
|
||||
requestPayload = APIManagerTokenUtils.GRANT_TYPE + "=" + APIManagerTokenUtils.REFRESH_TOKEN + "&" +
|
||||
APIManagerTokenUtils.REFRESH_TOKEN + "=" + refreshToken + "&" +
|
||||
APIManagerTokenUtils.SCOPE + "=" + applicationScope;
|
||||
|
||||
httpConnection = TransportUtils.getHttpConnection(tokenEndpoint);
|
||||
httpConnection.setRequestMethod(AgentConstants.HTTP_POST);
|
||||
httpConnection.setRequestProperty(AgentConstants.AUTHORIZATION_HEADER,
|
||||
"Basic " + agentManager.getAgentConfigs().getApiApplicationKey());
|
||||
httpConnection.setRequestProperty(AgentConstants.CONTENT_TYPE_HEADER, AgentConstants.X_WWW_FORM_URLENCODED);
|
||||
httpConnection.setDoOutput(true);
|
||||
|
||||
DataOutputStream dataOutPutWriter = new DataOutputStream(httpConnection.getOutputStream());
|
||||
dataOutPutWriter.writeBytes(requestPayload);
|
||||
dataOutPutWriter.flush();
|
||||
dataOutPutWriter.close();
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER + "Request to refresh OAuth token was sent to [" +
|
||||
httpConnection.getURL() + "] with payload [" + requestPayload + "].");
|
||||
log.info(AgentConstants.LOG_APPENDER + "Response [" + httpConnection.getResponseCode() + ":" +
|
||||
httpConnection.getResponseMessage() + "] was received for token refresh attempt.");
|
||||
|
||||
if (httpConnection.getResponseCode() == HttpStatus.OK_200) {
|
||||
connectionBuffer = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
|
||||
while ((dataFromBuffer = connectionBuffer.readLine()) != null) {
|
||||
responseMessage.append(dataFromBuffer);
|
||||
}
|
||||
|
||||
log.info(AgentConstants.LOG_APPENDER +
|
||||
"Response " + responseMessage + " was received for the token refresh call.");
|
||||
updateExistingTokens(responseMessage.toString());
|
||||
} else if (httpConnection.getResponseCode() == HttpStatus.BAD_REQUEST_400) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Token refresh call returned with a [400 Bad Request].\nThe refresh-token has " +
|
||||
"probably expired.\nPlease contact System-Admin to get a valid refresh-token.");
|
||||
} else {
|
||||
log.warn(AgentConstants.LOG_APPENDER + "There was an issue with refreshing the Access Token.");
|
||||
}
|
||||
|
||||
} catch (TransportHandlerException e) {
|
||||
throw new AgentCoreOperationException(e);
|
||||
} catch (ProtocolException e) {
|
||||
String errorMsg = "Protocol specific error occurred when trying to set method to " +
|
||||
AgentConstants.HTTP_POST + " for endpoint at: " + tokenEndpoint;
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
|
||||
} catch (IOException e) {
|
||||
String errorMsg = "An IO error occurred whilst trying to get the response code from: " + tokenEndpoint +
|
||||
" for a HTTP " + AgentConstants.HTTP_POST + " call.";
|
||||
log.error(AgentConstants.LOG_APPENDER + errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} finally {
|
||||
if (connectionBuffer != null) {
|
||||
try {
|
||||
connectionBuffer.close();
|
||||
} catch (IOException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"Error encounter whilst attempting to close buffer to connection at: " +
|
||||
tokenEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (httpConnection != null) {
|
||||
httpConnection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateExistingTokens(String responseFromTokenEP) throws AgentCoreOperationException {
|
||||
JSONObject jsonTokenObject = new JSONObject(responseFromTokenEP);
|
||||
String newAccessToken = jsonTokenObject.get(APIManagerTokenUtils.ACCESS_TOKEN).toString();
|
||||
String newRefreshToken = jsonTokenObject.get(APIManagerTokenUtils.REFRESH_TOKEN).toString();
|
||||
|
||||
if (newAccessToken == null || newRefreshToken == null) {
|
||||
String msg =
|
||||
"Neither Access-Token nor Refresh-Token was found in the response [" + responseFromTokenEP + "].";
|
||||
log.error(AgentConstants.LOG_APPENDER + msg);
|
||||
throw new AgentCoreOperationException(msg);
|
||||
}
|
||||
|
||||
AgentManager.getInstance().getAgentConfigs().setAuthToken(newAccessToken);
|
||||
AgentManager.getInstance().getAgentConfigs().setRefreshToken(newRefreshToken);
|
||||
String deviceConfigFilePath =
|
||||
AgentManager.getInstance().getRootPath() + AgentConstants.AGENT_PROPERTIES_FILE_NAME;
|
||||
|
||||
try {
|
||||
PropertiesConfiguration propertyFileConfiguration = new PropertiesConfiguration(deviceConfigFilePath);
|
||||
propertyFileConfiguration.setProperty(AgentConstants.AUTH_TOKEN_PROPERTY, newAccessToken);
|
||||
propertyFileConfiguration.setProperty(AgentConstants.REFRESH_TOKEN_PROPERTY, newRefreshToken);
|
||||
propertyFileConfiguration.save();
|
||||
} catch (ConfigurationException e) {
|
||||
String msg = "Error occurred whilst trying to update the [" + AgentConstants.AGENT_PROPERTIES_FILE_NAME +
|
||||
"] at: " + deviceConfigFilePath + " will the new tokens.";
|
||||
log.error(AgentConstants.LOG_APPENDER + msg);
|
||||
throw new AgentCoreOperationException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private class APIManagerTokenUtils {
|
||||
public static final String TOKEN_ENDPOINT = "/token";
|
||||
public static final String GRANT_TYPE = "grant_type";
|
||||
public static final String ACCESS_TOKEN = "access_token";
|
||||
public static final String REFRESH_TOKEN = "refresh_token";
|
||||
public static final String SCOPE = "scope";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
|
||||
import org.jscep.client.Client;
|
||||
import org.jscep.client.ClientException;
|
||||
import org.jscep.client.EnrollmentResponse;
|
||||
import org.jscep.client.verification.CertificateVerifier;
|
||||
import org.jscep.client.verification.OptimisticCertificateVerifier;
|
||||
import org.jscep.transaction.TransactionException;
|
||||
import org.jscep.transport.response.Capabilities;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
|
||||
import sun.security.x509.X509CertImpl;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* This class controls the entire SCEP enrolment process of the client. It is a singleton for any single client which
|
||||
* has the agent code running in it. The main functionality of this class includes generating a Private-Public Key
|
||||
* Pair for the enrollment flow, creating the Certificate-Sign-Request using the generated Public-Key to send to the
|
||||
* SEP server, Contacting the SCEP server to receive the Signed Certificate and requesting for the server's public
|
||||
* key for encrypting the payloads.
|
||||
* The provider for all Cryptographic functions used in this class are "BouncyCastle" and the Asymmetric-Key pair
|
||||
* algorithm used is "RSA" with a key size of 2048. The signature algorithm used is "SHA1withRSA".
|
||||
* This class also holds the "SCEPUrl" (Server Url read from the configs file), the Private-Public Keys of the
|
||||
* client, Signed SCEP certificate and the server's public certificate.
|
||||
*/
|
||||
|
||||
//TODO: Need to save cert and keys to file after initial enrollment...
|
||||
public class EnrollmentManager {
|
||||
private static final Log log = LogFactory.getLog(EnrollmentManager.class);
|
||||
private static EnrollmentManager enrollmentManager;
|
||||
|
||||
private static final String KEY_PAIR_ALGORITHM = "RSA";
|
||||
private static final String PROVIDER = "BC";
|
||||
private static final String SIGNATURE_ALG = "SHA1withRSA";
|
||||
private static final String CERT_IS_CA_EXTENSION = "is_ca";
|
||||
private static final int KEY_SIZE = 2048;
|
||||
|
||||
// Seed to our PRNG. Make sure this is initialised randomly, NOT LIKE THIS
|
||||
private static final byte[] SEED = ")(*&^%$#@!".getBytes();
|
||||
private static final int CERT_VALIDITY = 730;
|
||||
|
||||
// URL of our SCEP server
|
||||
private String SCEPUrl;
|
||||
private PrivateKey privateKey;
|
||||
private PublicKey publicKey;
|
||||
private PublicKey serverPublicKey;
|
||||
private X509Certificate SCEPCertificate;
|
||||
private boolean isEnrolled = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor of the EnrollmentManager. Initializes the SCEPUrl as read from the configuration file by the
|
||||
* AgentManager.
|
||||
*/
|
||||
private EnrollmentManager() {
|
||||
this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP();
|
||||
//setEnrollmentStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to return the current singleton instance of the EnrollmentManager.
|
||||
*
|
||||
* @return the current singleton instance if available and if not initializes a new instance and returns it.
|
||||
*/
|
||||
public static EnrollmentManager getInstance() {
|
||||
if (enrollmentManager == null) {
|
||||
enrollmentManager = new EnrollmentManager();
|
||||
}
|
||||
return enrollmentManager;
|
||||
}
|
||||
|
||||
|
||||
public void setEnrollmentStatus() {
|
||||
KeyStore keyStore;
|
||||
try {
|
||||
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
|
||||
|
||||
this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) &&
|
||||
keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS) &&
|
||||
keyStore.containsAlias(AgentConstants.SERVER_CA_CERT_ALIAS));
|
||||
|
||||
} catch (KeyStoreException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst accessing the device KeyStore '" +
|
||||
AgentConstants.DEVICE_KEYSTORE + "' with keystore type [" +
|
||||
AgentConstants.DEVICE_KEYSTORE_TYPE + "] to ensure enrollment status.");
|
||||
log.error(AgentConstants.LOG_APPENDER + e);
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (this.isEnrolled) {
|
||||
this.SCEPCertificate = (X509Certificate) keyStore.getCertificate(AgentConstants.DEVICE_CERT_ALIAS);
|
||||
this.privateKey = (PrivateKey) keyStore.getKey(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS,
|
||||
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
|
||||
this.publicKey = SCEPCertificate.getPublicKey();
|
||||
|
||||
X509Certificate serverCACert = (X509Certificate) keyStore.getCertificate(
|
||||
AgentConstants.SERVER_CA_CERT_ALIAS);
|
||||
this.serverPublicKey = serverCACert.getPublicKey();
|
||||
log.info(AgentConstants.LOG_APPENDER +
|
||||
"Device has already been enrolled. Hence, loaded certificate information from device" +
|
||||
" trust-store.");
|
||||
}
|
||||
} catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst accessing the device KeyStore '" +
|
||||
AgentConstants.DEVICE_KEYSTORE + "' to ensure enrollment status.");
|
||||
log.error(AgentConstants.LOG_APPENDER + e);
|
||||
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
|
||||
this.isEnrolled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to control the entire enrollment flow. This method calls the method to create the Private-Public Key
|
||||
* Pair, calls the specific method to generate the Certificate-Sign-Request, creates a one time self signed
|
||||
* certificate to present to the SCEP server with the initial CSR, calls the specific method to connect to the
|
||||
* SCEP Server and to get the SCEP Certificate and also calls the method that requests the SCEP Server for its
|
||||
* PublicKey for future payload encryption.
|
||||
*
|
||||
* @throws AgentCoreOperationException if the private method generateCertSignRequest() fails with an error or if
|
||||
* there is an error creating a self-sign certificate to present to the
|
||||
* server (whilst trying to get the CSR signed)
|
||||
*/
|
||||
public void beginEnrollmentFlow() throws AgentCoreOperationException {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
KeyPair keyPair = generateKeyPair();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
this.publicKey = keyPair.getPublic();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.info(AgentConstants.LOG_APPENDER + "DevicePrivateKey:\n[\n" + privateKey + "\n]\n");
|
||||
log.info(AgentConstants.LOG_APPENDER + "DevicePublicKey:\n[\n" + publicKey + "\n]\n");
|
||||
}
|
||||
|
||||
PKCS10CertificationRequest certSignRequest = generateCertSignRequest();
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------------------------------------------------
|
||||
* Generate an ephemeral self-signed certificate. This is needed to present to the CA in the SCEP request.
|
||||
* In the future, add proper EKU and attributes in the request. The CA does NOT have to honour any of this.
|
||||
* -----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
X500Name issuer = new X500Name("CN=Temporary Issuer");
|
||||
BigInteger serial = new BigInteger(32, new SecureRandom());
|
||||
Date fromDate = new Date();
|
||||
Date toDate = new Date(System.currentTimeMillis() + (CERT_VALIDITY * 86400000L));
|
||||
|
||||
// Build the self-signed cert using BC, sign it with our private key (self-signed)
|
||||
X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(issuer, serial, fromDate, toDate,
|
||||
certSignRequest.getSubject(),
|
||||
certSignRequest.getSubjectPublicKeyInfo());
|
||||
ContentSigner sigGen;
|
||||
X509Certificate tmpCert;
|
||||
|
||||
try {
|
||||
sigGen = new JcaContentSignerBuilder(SIGNATURE_ALG).setProvider(PROVIDER).build(keyPair.getPrivate());
|
||||
tmpCert = new JcaX509CertificateConverter().setProvider(PROVIDER).getCertificate(certBuilder.build(sigGen));
|
||||
} catch (OperatorCreationException e) {
|
||||
String errorMsg = "Error occurred whilst creating a ContentSigner for the Temp-Self-Signed Certificate.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} catch (CertificateException e) {
|
||||
String errorMsg = "Error occurred whilst trying to create Temp-Self-Signed Certificate.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
/**
|
||||
* -----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
this.SCEPCertificate = getSignedCertificateFromServer(tmpCert, certSignRequest);
|
||||
this.serverPublicKey = initPublicKeyOfServer();
|
||||
|
||||
storeCertificateToStore(AgentConstants.DEVICE_CERT_ALIAS, SCEPCertificate);
|
||||
storeKeyToKeyStore(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS, this.privateKey, SCEPCertificate);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.info(AgentConstants.LOG_APPENDER +
|
||||
"SCEPCertificate, DevicePrivateKey, ServerPublicKey was saved to device keystore [" +
|
||||
AgentConstants.DEVICE_KEYSTORE + "]");
|
||||
log.info(AgentConstants.LOG_APPENDER + "TemporaryCertPublicKey:\n[\n" + tmpCert.getPublicKey() + "\n]\n");
|
||||
log.info(AgentConstants.LOG_APPENDER + "ServerPublicKey:\n[\n" + serverPublicKey + "\n]\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void storeCertificateToStore(String alias, Certificate certificate) {
|
||||
KeyStore keyStore;
|
||||
try {
|
||||
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
|
||||
keyStore.setCertificateEntry(alias, certificate);
|
||||
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
|
||||
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
|
||||
|
||||
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"An error occurred whilst trying to store the Certificate received from the SCEP " +
|
||||
"Enrollment.");
|
||||
log.error(AgentConstants.LOG_APPENDER + e);
|
||||
log.warn(AgentConstants.LOG_APPENDER +
|
||||
"SCEP Certificate was not stored in the keystore; " +
|
||||
"Hence the device will be re-enrolled during next restart.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void storeKeyToKeyStore(String alias, Key cryptoKey, Certificate certInCertChain) {
|
||||
KeyStore keyStore;
|
||||
try {
|
||||
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
|
||||
Certificate[] certChain = new Certificate[1];
|
||||
certChain[0] = certInCertChain;
|
||||
|
||||
keyStore.setKeyEntry(alias, cryptoKey, AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray(), certChain);
|
||||
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
|
||||
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
|
||||
|
||||
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
|
||||
log.error(AgentConstants.LOG_APPENDER +
|
||||
"An error occurred whilst trying to store the key with alias " +
|
||||
"[" + alias + "] in the device keystore.");
|
||||
log.error(AgentConstants.LOG_APPENDER + e);
|
||||
log.warn(AgentConstants.LOG_APPENDER +
|
||||
"Key [" + alias + "] was not stored in the keystore; " +
|
||||
"Hence the device will be re-enrolled during next restart.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates the Public-Private Key pair for the current client.
|
||||
*
|
||||
* @return the generated KeyPair object
|
||||
* @throws AgentCoreOperationException when the given Security Provider does not exist or the Algorithmn used to
|
||||
* generate the key pair is invalid.
|
||||
*/
|
||||
private KeyPair generateKeyPair() throws AgentCoreOperationException {
|
||||
|
||||
// Generate key pair
|
||||
KeyPairGenerator keyPairGenerator;
|
||||
try {
|
||||
keyPairGenerator = KeyPairGenerator.getInstance(KEY_PAIR_ALGORITHM, PROVIDER);
|
||||
keyPairGenerator.initialize(KEY_SIZE, new SecureRandom(SEED));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm [" + KEY_PAIR_ALGORITHM + "] provided for KeyPairGenerator is invalid.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} catch (NoSuchProviderException e) {
|
||||
String errorMsg = "Provider [" + PROVIDER + "] provided for KeyPairGenerator does not exist.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
|
||||
return keyPairGenerator.genKeyPair();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates the PKCS10 Certificate Sign Request which is to be sent to the SCEP Server using the
|
||||
* generated PublicKey of the client. The certificate parameters used here are the ones from the AgentManager
|
||||
* which are the values read from the configurations file.
|
||||
*
|
||||
* @return the PKCS10CertificationRequest object created using the client specific configs and the generated
|
||||
* PublicKey
|
||||
* @throws AgentCoreOperationException if an error occurs when creating a content signer to sign the CSR.
|
||||
*/
|
||||
private PKCS10CertificationRequest generateCertSignRequest() throws AgentCoreOperationException {
|
||||
// Build the CN for the cert that's being requested.
|
||||
X500NameBuilder nameBld = new X500NameBuilder(BCStyle.INSTANCE);
|
||||
nameBld.addRDN(BCStyle.CN, AgentManager.getInstance().getAgentConfigs().getTenantDomain());
|
||||
nameBld.addRDN(BCStyle.O, AgentManager.getInstance().getAgentConfigs().getDeviceOwner());
|
||||
nameBld.addRDN(BCStyle.OU, AgentManager.getInstance().getAgentConfigs().getDeviceOwner());
|
||||
nameBld.addRDN(BCStyle.UNIQUE_IDENTIFIER, AgentManager.getInstance().getAgentConfigs().getDeviceId());
|
||||
nameBld.addRDN(BCStyle.SERIALNUMBER, AgentManager.getInstance().getAgentConfigs().getDeviceId());
|
||||
X500Name principal = nameBld.build();
|
||||
|
||||
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder(SIGNATURE_ALG).setProvider(PROVIDER);
|
||||
ContentSigner contentSigner;
|
||||
|
||||
try {
|
||||
contentSigner = contentSignerBuilder.build(this.privateKey);
|
||||
} catch (OperatorCreationException e) {
|
||||
String errorMsg = "Could not create content signer with private key.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
|
||||
// Generate the certificate signing request (csr = PKCS10)
|
||||
PKCS10CertificationRequestBuilder reqBuilder = new JcaPKCS10CertificationRequestBuilder(principal,
|
||||
this.publicKey);
|
||||
return reqBuilder.build(contentSigner);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method connects to the SCEP Server to fetch the signed SCEP Certificate.
|
||||
*
|
||||
* @param tempCert the temporary self-signed certificate of the client required for the initial CSR
|
||||
* request against the SCEP Server.
|
||||
* @param certSignRequest the PKCS10 Certificate-Sign-Request that is to be sent to the SCEP Server.
|
||||
* @return the SCEP-Certificate for the client signed by the SCEP-Server.
|
||||
* @throws AgentCoreOperationException if the SCEPUrl is invalid or if the flow of sending the CSR and getting
|
||||
* the signed certificate fails or if the signed certificate cannot be
|
||||
* retrieved from the reply from the server.
|
||||
*/
|
||||
private X509Certificate getSignedCertificateFromServer(X509Certificate tempCert,
|
||||
PKCS10CertificationRequest certSignRequest)
|
||||
throws AgentCoreOperationException {
|
||||
|
||||
X509Certificate signedSCEPCertificate = null;
|
||||
URL url;
|
||||
EnrollmentResponse enrolResponse;
|
||||
CertStore certStore;
|
||||
|
||||
try {
|
||||
// The URL where we are going to request our cert from
|
||||
url = new URL(this.SCEPUrl);
|
||||
|
||||
/* // This is called when we get the certificate for our CSR signed by CA
|
||||
// Implement this handler to check the CA cert in prod. We can do cert pinning here
|
||||
CallbackHandler cb = new CallbackHandler() {
|
||||
@Override
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated
|
||||
methods, choose Tools | Templates.
|
||||
}
|
||||
};*/
|
||||
|
||||
// Implement verification of the CA cert. VERIFY the CA
|
||||
CertificateVerifier ocv = new OptimisticCertificateVerifier();
|
||||
|
||||
// Instantiate our SCEP client
|
||||
Client scepClient = new Client(url, ocv);
|
||||
|
||||
// Submit our cert for signing. SCEP server should allow the client to specify
|
||||
// the SCEP CA to issue the request against, if there are multiple CAs
|
||||
enrolResponse = scepClient.enrol(tempCert, this.privateKey, certSignRequest);
|
||||
|
||||
// Verify we got what we want, and just print out the cert.
|
||||
certStore = enrolResponse.getCertStore();
|
||||
|
||||
for (Certificate x509Certificate : certStore.getCertificates(null)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(x509Certificate.toString());
|
||||
}
|
||||
signedSCEPCertificate = (X509Certificate) x509Certificate;
|
||||
}
|
||||
|
||||
} catch (MalformedURLException ex) {
|
||||
String errorMsg = "Could not create valid URL from given SCEP URI: " + SCEPUrl;
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, ex);
|
||||
} catch (TransactionException | ClientException e) {
|
||||
String errorMsg = "Enrollment process to SCEP Server at: " + SCEPUrl + " failed.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} catch (CertStoreException e) {
|
||||
String errorMsg = "Could not retrieve [Signed-Certificate] from the response message from SCEP-Server.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
|
||||
return signedSCEPCertificate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Public Key of the SCEP-Server and initializes it for later use. This method contacts the SCEP Server
|
||||
* and fetches its CA Cert and extracts the Public Key of the server from the received reply.
|
||||
*
|
||||
* @return the public key of the SCEP Server which is to be used to encrypt pyloads.
|
||||
* @throws AgentCoreOperationException if the SCEPUrl is invalid or if the flow of sending the CSR and getting
|
||||
* the signed certificate fails or if the signed certificate cannot be
|
||||
* retrieved from the reply from the server.
|
||||
*/
|
||||
private PublicKey initPublicKeyOfServer() throws AgentCoreOperationException {
|
||||
URL url;
|
||||
CertStore certStore;
|
||||
PublicKey serverCertPublicKey = null;
|
||||
|
||||
try {
|
||||
// The URL where we are going to request our cert from
|
||||
url = new URL(this.SCEPUrl);
|
||||
|
||||
/* // This is called when we get the certificate for our CSR signed by CA
|
||||
// Implement this handler to check the CA cert in prod. We can do cert pinning here
|
||||
CallbackHandler cb = new CallbackHandler() {
|
||||
@Override
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated
|
||||
methods, choose Tools | Templates.
|
||||
}
|
||||
};*/
|
||||
|
||||
// Implement verification of the CA cert. VERIFY the CA
|
||||
CertificateVerifier ocv = new OptimisticCertificateVerifier();
|
||||
|
||||
// Instantiate our SCEP client
|
||||
Client scepClient = new Client(url, ocv);
|
||||
|
||||
// Get the CA capabilities. Should return SHA1withRSA for strongest hash and sig. Returns MD5.
|
||||
if (log.isDebugEnabled()) {
|
||||
Capabilities cap = scepClient.getCaCapabilities();
|
||||
log.debug(String.format(
|
||||
"\nStrongestCipher: %s,\nStrongestMessageDigest: %s,\nStrongestSignatureAlgorithm: %s," +
|
||||
"\nIsRenewalSupported: %s,\nIsRolloverSupported: %s",
|
||||
cap.getStrongestCipher(), cap.getStrongestMessageDigest(), cap.getStrongestSignatureAlgorithm(),
|
||||
cap.isRenewalSupported(), cap.isRolloverSupported()));
|
||||
}
|
||||
|
||||
certStore = scepClient.getCaCertificate();
|
||||
|
||||
for (Certificate cert : certStore.getCertificates(null)) {
|
||||
if (cert instanceof X509Certificate) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(((X509Certificate) cert).getIssuerDN().getName());
|
||||
}
|
||||
|
||||
// I have chosen the CA cert based on its BasicConstraintExtension "is_ca" being set to "true"
|
||||
// This is because the returned keystore may contain many certificates including RAs.
|
||||
if (((Boolean) ((X509CertImpl) cert).getBasicConstraintsExtension().get(CERT_IS_CA_EXTENSION))) {
|
||||
serverCertPublicKey = cert.getPublicKey();
|
||||
storeCertificateToStore(AgentConstants.SERVER_CA_CERT_ALIAS, cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (MalformedURLException ex) {
|
||||
String errorMsg = "Could not create valid URL from given SCEP URI: " + SCEPUrl;
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, ex);
|
||||
} catch (ClientException e) {
|
||||
String errorMsg = "Could not retrieve [Server-Certificate] from the SCEP-Server.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} catch (CertStoreException e) {
|
||||
String errorMsg = "Could not retrieve [Server-Certificates] from the response message from SCEP-Server.";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
} catch (IOException e) {
|
||||
String errorMsg = "Error occurred whilst trying to get property ['is_ca'] from the retreived Certificates";
|
||||
log.error(errorMsg);
|
||||
throw new AgentCoreOperationException(errorMsg, e);
|
||||
}
|
||||
|
||||
return serverCertPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Public-Key of the client.
|
||||
*
|
||||
* @return the public key of the client.
|
||||
*/
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Private-Key of the client.
|
||||
*
|
||||
* @return the private key of the client.
|
||||
*/
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SCEP-Certificate of the client.
|
||||
*
|
||||
* @return the SCEP Certificate of the client.
|
||||
*/
|
||||
public X509Certificate getSCEPCertificate() {
|
||||
return SCEPCertificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Public-Key of the Server.
|
||||
*
|
||||
* @return the pubic key of the server.
|
||||
*/
|
||||
public PublicKey getServerPublicKey() {
|
||||
return serverPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the device has already been enrolled with the SCEP Server.
|
||||
*
|
||||
* @return the enrollment status; 'TRUE' if already enrolled else 'FALSE'.
|
||||
*/
|
||||
public boolean isEnrolled() {
|
||||
return isEnrolled;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception;
|
||||
|
||||
|
||||
public class AgentCoreOperationException extends Exception{
|
||||
private static final long serialVersionUID = 2736466230451105710L;
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public AgentCoreOperationException(String msg, Exception nestedEx) {
|
||||
super(msg, nestedEx);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public AgentCoreOperationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
setErrorMessage(message);
|
||||
}
|
||||
|
||||
public AgentCoreOperationException(String msg) {
|
||||
super(msg);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public AgentCoreOperationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AgentCoreOperationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
|
||||
/**
|
||||
* This is a utility class which contains methods common to the communication process of a client and the server. The
|
||||
* methods include encryption/decryption of payloads and signing/verification of payloads received and to be sent.
|
||||
*/
|
||||
public class CommunicationUtils {
|
||||
private static final Log log = LogFactory.getLog(TransportUtils.class);
|
||||
|
||||
// The Signature Algorithm used.
|
||||
private static final String SHA_512 = "SHA-512";
|
||||
// The Encryption Algorithm and the Padding used.
|
||||
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the message with the key that's passed in.
|
||||
*
|
||||
* @param message the message to be encrypted.
|
||||
* @param encryptionKey the key to use for the encryption of the message.
|
||||
* @return the encrypted message in String format.
|
||||
* @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding
|
||||
* issues, encryption key being invalid or the algorithm used is unrecognizable.
|
||||
*/
|
||||
public static String encryptMessage(String message, Key encryptionKey) throws TransportHandlerException {
|
||||
Cipher encrypter;
|
||||
byte[] cipherData;
|
||||
|
||||
try {
|
||||
encrypter = Cipher.getInstance(CIPHER_PADDING);
|
||||
encrypter.init(Cipher.ENCRYPT_MODE, encryptionKey);
|
||||
cipherData = encrypter.doFinal(message.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (NoSuchPaddingException e) {
|
||||
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (BadPaddingException e) {
|
||||
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
}
|
||||
|
||||
return Base64.encodeBase64String(cipherData);
|
||||
}
|
||||
|
||||
///TODO:: Exception needs to change according to the common package
|
||||
/**
|
||||
* Signed a given message using the PrivateKey that's passes in.
|
||||
*
|
||||
* @param message the message to be signed. Ideally some encrypted payload.
|
||||
* @param signatureKey the PrivateKey with which the message is to be signed.
|
||||
* @return the Base64Encoded String of the signed payload.
|
||||
* @throws TransportHandlerException if some error occurs with the signing process which may be related to the
|
||||
* signature algorithm used or the key used for signing.
|
||||
*/
|
||||
public static String signMessage(String message, PrivateKey signatureKey) throws TransportHandlerException {
|
||||
|
||||
Signature signature;
|
||||
String signedEncodedString;
|
||||
|
||||
try {
|
||||
signature = Signature.getInstance(SHA_512);
|
||||
signature.initSign(signatureKey);
|
||||
signature.update(Base64.decodeBase64(message));
|
||||
|
||||
byte[] signatureBytes = signature.sign();
|
||||
signedEncodedString = Base64.encodeBase64String(signatureBytes);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg =
|
||||
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (SignatureException e) {
|
||||
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
}
|
||||
|
||||
return signedEncodedString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies some signed-data against the a Public-Key to ensure that it was produced by the holder of the
|
||||
* corresponding Private Key.
|
||||
*
|
||||
* @param data the actual payoad which was signed by some Private Key.
|
||||
* @param signedData the signed data produced by signing the payload using a Private Key.
|
||||
* @param verificationKey the corresponding Public Key which is an exact pair of the Private-Key with we expect
|
||||
* the data to be signed by.
|
||||
* @return true if the signed data verifies to be signed by the corresponding Private Key.
|
||||
* @throws TransportHandlerException if some error occurs with the verification process which may be related to
|
||||
* the signature algorithm used or the key used for signing.
|
||||
*/
|
||||
public static boolean verifySignature(String data, String signedData, PublicKey verificationKey)
|
||||
throws TransportHandlerException {
|
||||
|
||||
Signature signature;
|
||||
boolean verified;
|
||||
|
||||
try {
|
||||
signature = Signature.getInstance(SHA_512);
|
||||
signature.initVerify(verificationKey);
|
||||
signature.update(Base64.decodeBase64(data));
|
||||
|
||||
verified = signature.verify(Base64.decodeBase64(signedData));
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg =
|
||||
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (SignatureException e) {
|
||||
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
}
|
||||
|
||||
return verified;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the message with the key that's passed in.
|
||||
*
|
||||
* @param encryptedMessage the encrypted message that is supposed to be decrypted.
|
||||
* @param decryptKey the key to use in the decryption process.
|
||||
* @return the decrypted message in String format.
|
||||
* @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding
|
||||
* issues, encryption key being invalid or the algorithm used is unrecognizable.
|
||||
*/
|
||||
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws TransportHandlerException {
|
||||
|
||||
Cipher decrypter;
|
||||
String decryptedMessage;
|
||||
|
||||
try {
|
||||
|
||||
decrypter = Cipher.getInstance(CIPHER_PADDING);
|
||||
decrypter.init(Cipher.DECRYPT_MODE, decryptKey);
|
||||
decryptedMessage = new String(decrypter.doFinal(Base64.decodeBase64(encryptedMessage)),
|
||||
StandardCharsets.UTF_8);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (NoSuchPaddingException e) {
|
||||
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (BadPaddingException e) {
|
||||
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
}
|
||||
|
||||
return decryptedMessage;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport;
|
||||
|
||||
/**
|
||||
* This interface consists of the core functionality related to the transport between any device and the server. The
|
||||
* interface is an abstraction, regardless of the underlying protocol used for the transport. Implementation of this
|
||||
* interface by any class that caters a specific protocol (ex: HTTP, XMPP, MQTT, CoAP) would ideally have methods
|
||||
* specific to the protocol used for communication and thees methods that implement the logic related to the devices
|
||||
* using the protocol.
|
||||
*
|
||||
* @param <T> a message type specific to the protocol implemented
|
||||
*/
|
||||
public interface TransportHandler<T> {
|
||||
int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 10 sec
|
||||
|
||||
void connect();
|
||||
|
||||
boolean isConnected();
|
||||
|
||||
//TODO:: Any errors needs to be thrown ahead
|
||||
void processIncomingMessage(T message, String... messageParams);
|
||||
|
||||
void processIncomingMessage();
|
||||
|
||||
void publishDeviceData(String... publishData);
|
||||
|
||||
void publishDeviceData();
|
||||
|
||||
void disconnect();
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport;
|
||||
|
||||
public class TransportHandlerException extends Exception {
|
||||
private static final long serialVersionUID = 2736466230451105440L;
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public TransportHandlerException(String msg, Exception nestedEx) {
|
||||
super(msg, nestedEx);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public TransportHandlerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
setErrorMessage(message);
|
||||
}
|
||||
|
||||
public TransportHandlerException(String msg) {
|
||||
super(msg);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public TransportHandlerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TransportHandlerException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class TransportUtils {
|
||||
private static final Log log = LogFactory.getLog(TransportUtils.class);
|
||||
|
||||
public static final int MIN_PORT_NUMBER = 9000;
|
||||
public static final int MAX_PORT_NUMBER = 11000;
|
||||
|
||||
/**
|
||||
* Given a server endpoint as a String, this method splits it into Protocol, Host and Port
|
||||
*
|
||||
* @param ipString a network endpoint in the format - '<PROTOCOL>://<HOST>:<PORT>'
|
||||
* @return a map with keys "Protocol", "Host" & "Port" for the related values from the ipString
|
||||
* @throws TransportHandlerException
|
||||
*/
|
||||
public static Map<String, String> getHostAndPort(String ipString)
|
||||
throws TransportHandlerException {
|
||||
Map<String, String> ipPortMap = new HashMap<String, String>();
|
||||
String[] ipPortArray = ipString.split(":");
|
||||
|
||||
if (ipPortArray.length != 3) {
|
||||
String errorMsg =
|
||||
"The IP String - '" + ipString +
|
||||
"' is invalid. It needs to be in format '<PROTOCOL>://<HOST>:<PORT>'.";
|
||||
log.info(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg);
|
||||
}
|
||||
|
||||
ipPortMap.put(AgentConstants.PROTOCOL_PROPERTY, ipPortArray[0]);
|
||||
ipPortMap.put(AgentConstants.HOST_PROPERTY, ipPortArray[1].replace("/", ""));
|
||||
ipPortMap.put(AgentConstants.PORT_PROPERTY, ipPortArray[2]);
|
||||
return ipPortMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates whether a specific IP Address is of IPv4 type
|
||||
*
|
||||
* @param ipAddress the IP Address which needs to be validated
|
||||
* @return true if it is of IPv4 type and false otherwise
|
||||
*/
|
||||
public static boolean validateIPv4(String ipAddress) {
|
||||
try {
|
||||
if (ipAddress == null || ipAddress.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] parts = ipAddress.split("\\.");
|
||||
if (parts.length != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String s : parts) {
|
||||
int i = Integer.parseInt(s);
|
||||
if ((i < 0) || (i > 255)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !ipAddress.endsWith(".");
|
||||
|
||||
} catch (NumberFormatException nfe) {
|
||||
log.warn("The IP Address: " + ipAddress + " could not be validated against IPv4-style");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, String> getInterfaceIPMap() throws TransportHandlerException {
|
||||
|
||||
Map<String, String> interfaceToIPMap = new HashMap<String, String>();
|
||||
Enumeration<NetworkInterface> networkInterfaces;
|
||||
String networkInterfaceName = "";
|
||||
String ipAddress;
|
||||
|
||||
try {
|
||||
networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
} catch (SocketException exception) {
|
||||
String errorMsg =
|
||||
"Error encountered whilst trying to get the list of network-interfaces";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, exception);
|
||||
}
|
||||
|
||||
try {
|
||||
for (; networkInterfaces.hasMoreElements(); ) {
|
||||
networkInterfaceName = networkInterfaces.nextElement().getName();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Network Interface: " + networkInterfaceName);
|
||||
log.debug("------------------------------------------");
|
||||
}
|
||||
|
||||
Enumeration<InetAddress> interfaceIPAddresses = NetworkInterface.getByName(
|
||||
networkInterfaceName).getInetAddresses();
|
||||
|
||||
for (; interfaceIPAddresses.hasMoreElements(); ) {
|
||||
ipAddress = interfaceIPAddresses.nextElement().getHostAddress();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("IP Address: " + ipAddress);
|
||||
}
|
||||
|
||||
if (TransportUtils.validateIPv4(ipAddress)) {
|
||||
interfaceToIPMap.put(networkInterfaceName, ipAddress);
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("------------------------------------------");
|
||||
}
|
||||
}
|
||||
} catch (SocketException exception) {
|
||||
String errorMsg =
|
||||
"Error encountered whilst trying to get the IP Addresses of the network " +
|
||||
"interface: " + networkInterfaceName;
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, exception);
|
||||
}
|
||||
|
||||
return interfaceToIPMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to find a free port between the MIN_PORT_NUMBER(9000) and MAX_PORT_NUMBER(11000).
|
||||
* Tries 'RANDOMLY picked' port numbers between this range up-until "randomAttempts" number of
|
||||
* times. If still fails, then tries each port in descending order from the MAX_PORT_NUMBER
|
||||
* whilst skipping already attempted ones via random selection.
|
||||
*
|
||||
* @param randomAttempts no of times to TEST port numbers picked randomly over the given range
|
||||
* @return an available/free port
|
||||
*/
|
||||
public static synchronized int getAvailablePort(int randomAttempts) {
|
||||
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
|
||||
try {
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
int randomPort = MAX_PORT_NUMBER;
|
||||
while (randomAttempts > 0) {
|
||||
randomPort = secureRandom.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
|
||||
if (checkIfPortAvailable(randomPort)) {
|
||||
return randomPort;
|
||||
}
|
||||
failedPorts.add(randomPort);
|
||||
randomAttempts--;
|
||||
}
|
||||
randomPort = MAX_PORT_NUMBER;
|
||||
while (true) {
|
||||
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
|
||||
return randomPort;
|
||||
}
|
||||
randomPort--;
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean checkIfPortAvailable(int port) {
|
||||
ServerSocket tcpSocket = null;
|
||||
DatagramSocket udpSocket = null;
|
||||
|
||||
try {
|
||||
tcpSocket = new ServerSocket(port);
|
||||
tcpSocket.setReuseAddress(true);
|
||||
|
||||
udpSocket = new DatagramSocket(port);
|
||||
udpSocket.setReuseAddress(true);
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
// denotes the port is in use
|
||||
} finally {
|
||||
if (tcpSocket != null) {
|
||||
try {
|
||||
tcpSocket.close();
|
||||
} catch (IOException e) {
|
||||
/* not to be thrown */
|
||||
}
|
||||
}
|
||||
|
||||
if (udpSocket != null) {
|
||||
udpSocket.close();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a utility method that creates and returns a HTTP connection object.
|
||||
*
|
||||
* @param urlString the URL pattern to which the connection needs to be created
|
||||
* @return an HTTPConnection object which cn be used to send HTTP requests
|
||||
* @throws TransportHandlerException if errors occur when creating the HTTP connection with
|
||||
* the given URL string
|
||||
*/
|
||||
public static HttpURLConnection getHttpConnection(String urlString) throws
|
||||
TransportHandlerException {
|
||||
URL connectionUrl;
|
||||
HttpURLConnection httpConnection;
|
||||
|
||||
try {
|
||||
connectionUrl = new URL(urlString);
|
||||
httpConnection = (HttpURLConnection) connectionUrl.openConnection();
|
||||
} catch (MalformedURLException e) {
|
||||
String errorMsg = "Error occured whilst trying to form HTTP-URL from string: " + urlString;
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, e);
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = "Error occured whilst trying to open a connection to: " + urlString;
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, exception);
|
||||
}
|
||||
return httpConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a utility method that reads and returns the response from a HTTP connection
|
||||
*
|
||||
* @param httpConnection the connection from which a response is expected
|
||||
* @return the response (as a string) from the given HTTP connection
|
||||
* @throws TransportHandlerException if any errors occur whilst reading the response from
|
||||
* the connection stream
|
||||
*/
|
||||
public static String readResponseFromHttpRequest(HttpURLConnection httpConnection)
|
||||
throws TransportHandlerException {
|
||||
BufferedReader bufferedReader;
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(
|
||||
httpConnection.getInputStream(), StandardCharsets.UTF_8));
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = "There is an issue with connecting the reader to the input stream at: " +
|
||||
httpConnection.getURL();
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, exception);
|
||||
}
|
||||
|
||||
String responseLine;
|
||||
StringBuilder completeResponse = new StringBuilder();
|
||||
|
||||
try {
|
||||
while ((responseLine = bufferedReader.readLine()) != null) {
|
||||
completeResponse.append(responseLine);
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
String errorMsg = "Error occured whilst trying read from the connection stream at: " +
|
||||
httpConnection.getURL();
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, exception);
|
||||
}
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (IOException exception) {
|
||||
log.error("Could not succesfully close the bufferedReader to the connection at: " + httpConnection.getURL());
|
||||
}
|
||||
return completeResponse.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.http;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
|
||||
|
||||
/**
|
||||
* This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
|
||||
* the core functionality with regards to device-server communication regardless of the Transport protocol. This
|
||||
* specific class contains the HTTP-Transport specific implementations. The class implements utility methods for the
|
||||
* case of a HTTP communication. However, this "abstract class", even-though it implements the "TransportHandler"
|
||||
* interface, does not contain the logic relevant to the interface methods. The specific functionality of the
|
||||
* interface methods are intended to be implemented by the concrete class that extends this abstract class and
|
||||
* utilizes the HTTP specific functionality (ideally a device API writer who would like to communicate to the device
|
||||
* via HTTP Protocol).
|
||||
*/
|
||||
public abstract class HTTPTransportHandler implements TransportHandler {
|
||||
private static final Log log = LogFactory.getLog(HTTPTransportHandler.class);
|
||||
|
||||
protected Server server;
|
||||
protected int port;
|
||||
protected int timeoutInterval;
|
||||
|
||||
protected HTTPTransportHandler() {
|
||||
this.port = TransportUtils.getAvailablePort(10);
|
||||
this.server = new Server(port);
|
||||
timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
||||
}
|
||||
|
||||
protected HTTPTransportHandler(int port) {
|
||||
this.port = port;
|
||||
this.server = new Server(this.port);
|
||||
timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
||||
}
|
||||
|
||||
protected HTTPTransportHandler(int port, int timeoutInterval) {
|
||||
this.port = port;
|
||||
this.server = new Server(this.port);
|
||||
this.timeoutInterval = timeoutInterval;
|
||||
}
|
||||
|
||||
public void setTimeoutInterval(int timeoutInterval) {
|
||||
this.timeoutInterval = timeoutInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the HTTP server is up and listening for incoming requests.
|
||||
*
|
||||
* @return true if the server is up & listening for requests, else false.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return server.isStarted();
|
||||
}
|
||||
|
||||
|
||||
protected void incrementPort() {
|
||||
this.port = this.port + 1;
|
||||
server = new Server(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts-down the HTTP Server.
|
||||
*/
|
||||
public void closeConnection() throws Exception {
|
||||
if (server != null && isConnected()) {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.mqtt;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallback;
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
|
||||
* the core functionality with regards to device-server communication regardless of the Transport protocol. This
|
||||
* specific class contains the HTTP-Transport specific implementations. The class implements utility methods for the
|
||||
* case of a HTTP communication. However, this "abstract class", even-though it implements the "TransportHandler"
|
||||
* interface, does not contain the logic relevant to the interface methods. The specific functionality of the
|
||||
* interface methods are intended to be implemented by the concrete class that extends this abstract class and
|
||||
* utilizes the HTTP specific functionality (ideally a device API writer who would like to communicate to the device
|
||||
* via HTTP Protocol).
|
||||
* <p/>
|
||||
* This class contains the Device-Management specific implementation for all the MQTT functionality. This includes
|
||||
* connecting to a MQTT Broker & subscribing to the appropriate MQTT-topic, action plan upon losing connection or
|
||||
* successfully delivering a message to the broker and processing incoming messages. Makes use of the 'Paho-MQTT'
|
||||
* library provided by Eclipse Org.
|
||||
*/
|
||||
public abstract class MQTTTransportHandler
|
||||
implements MqttCallback, TransportHandler<MqttMessage> {
|
||||
private static final Log log = LogFactory.getLog(MQTTTransportHandler.class);
|
||||
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
|
||||
|
||||
private MqttClient client;
|
||||
private String clientId;
|
||||
private MqttConnectOptions options;
|
||||
private String clientWillTopic;
|
||||
|
||||
protected String mqttBrokerEndPoint;
|
||||
protected int timeoutInterval;
|
||||
protected String subscribeTopic;
|
||||
|
||||
/**
|
||||
* Constructor for the MQTTTransportHandler which takes in the owner, type of the device
|
||||
* and the MQTT Broker URL and the topic to subscribe.
|
||||
*
|
||||
* @param deviceOwner the owner of the device.
|
||||
* @param deviceType the CDMF Device-Type of the device.
|
||||
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
|
||||
* @param subscribeTopic the MQTT topic to which the client is to be subscribed
|
||||
*/
|
||||
protected MQTTTransportHandler(String deviceOwner, String deviceType,
|
||||
String mqttBrokerEndPoint,
|
||||
String subscribeTopic) {
|
||||
this.clientId = deviceOwner + ":" + deviceType;
|
||||
this.subscribeTopic = subscribeTopic;
|
||||
this.clientWillTopic = deviceType + File.separator + "disconnection";
|
||||
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
|
||||
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
||||
this.initSubscriber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the MQTTTransportHandler which takes in the owner, type of the device
|
||||
* and the MQTT Broker URL and the topic to subscribe. Additionally this constructor takes in
|
||||
* the reconnection-time interval between successive attempts to connect to the broker.
|
||||
*
|
||||
* @param deviceOwner the owner of the device.
|
||||
* @param deviceType the CDMF Device-Type of the device.
|
||||
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
|
||||
* @param subscribeTopic the MQTT topic to which the client is to be subscribed
|
||||
* @param intervalInMillis the time interval in MILLI-SECONDS between successive
|
||||
* attempts to connect to the broker.
|
||||
*/
|
||||
protected MQTTTransportHandler(String deviceOwner, String deviceType,
|
||||
String mqttBrokerEndPoint, String subscribeTopic,
|
||||
int intervalInMillis) {
|
||||
this.clientId = deviceOwner + ":" + deviceType;
|
||||
this.subscribeTopic = subscribeTopic;
|
||||
//TODO:: Use constant strings
|
||||
this.clientWillTopic = deviceType + File.separator + "disconnection";
|
||||
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
|
||||
this.timeoutInterval = intervalInMillis;
|
||||
this.initSubscriber();
|
||||
}
|
||||
|
||||
public void setTimeoutInterval(int timeoutInterval) {
|
||||
this.timeoutInterval = timeoutInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the MQTT-Client. Creates a client using the given MQTT-broker endpoint and the
|
||||
* clientId (which is constructed by a concatenation of [deviceOwner]:[deviceType]). Also sets
|
||||
* the client's options parameter with the clientWillTopic (in-case of connection failure) and
|
||||
* other info. Also sets the call-back this current class.
|
||||
*/
|
||||
private void initSubscriber() {
|
||||
try {
|
||||
client = new MqttClient(this.mqttBrokerEndPoint, clientId, null);
|
||||
//TODO:: Need to check for debug
|
||||
log.info("MQTT subscriber was created with ClientID : " + clientId);
|
||||
} catch (MqttException ex) {
|
||||
//TODO:: Remove unnecessary formatting and print exception
|
||||
String errorMsg = "MQTT Client Error\n" + "\tReason: " + ex.getReasonCode() +
|
||||
"\n\tMessage: " + ex.getMessage() + "\n\tLocalMsg: " +
|
||||
ex.getLocalizedMessage() + "\n\tCause: " + ex.getCause() +
|
||||
"\n\tException: " + ex;
|
||||
log.error(errorMsg);
|
||||
//TODO:: Throw the error out
|
||||
}
|
||||
|
||||
options = new MqttConnectOptions();
|
||||
options.setCleanSession(false);
|
||||
//TODO:: Use constant strings
|
||||
options.setWill(clientWillTopic, "Connection-Lost".getBytes(StandardCharsets.UTF_8), 2,
|
||||
true);
|
||||
client.setCallback(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the connection to the MQTT-Broker persists.
|
||||
*
|
||||
* @return true if the client is connected to the MQTT-Broker, else false.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return client.isConnected();
|
||||
}
|
||||
|
||||
|
||||
protected void connectToQueue(String username, String password) throws TransportHandlerException {
|
||||
options.setUserName(username);
|
||||
options.setPassword(password.toCharArray());
|
||||
connectToQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the MQTT-Broker and if successfully established connection.
|
||||
*
|
||||
* @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
|
||||
*/
|
||||
protected void connectToQueue() throws TransportHandlerException {
|
||||
try {
|
||||
client.connect(options);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Subscriber connected to queue at: " + this.mqttBrokerEndPoint);
|
||||
}
|
||||
} catch (MqttSecurityException ex) {
|
||||
String errorMsg = "MQTT Security Exception when connecting to queue\n" + "\tReason: " +
|
||||
" " +
|
||||
ex.getReasonCode() + "\n\tMessage: " + ex.getMessage() +
|
||||
"\n\tLocalMsg: " + ex.getLocalizedMessage() + "\n\tCause: " +
|
||||
ex.getCause() + "\n\tException: " + ex;
|
||||
//TODO:: Compulsory log of errors and remove formatted error
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
throw new TransportHandlerException(errorMsg, ex);
|
||||
|
||||
} catch (MqttException ex) {
|
||||
//TODO:: Compulsory log of errors and remove formatted error
|
||||
String errorMsg = "MQTT Exception when connecting to queue\n" + "\tReason: " +
|
||||
ex.getReasonCode() + "\n\tMessage: " + ex.getMessage() +
|
||||
"\n\tLocalMsg: " + ex.getLocalizedMessage() + "\n\tCause: " +
|
||||
ex.getCause() + "\n\tException: " + ex;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
throw new TransportHandlerException(errorMsg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to the MQTT-Topic specific to this MQTT Client. (The MQTT-Topic specific to the
|
||||
* device is taken in as a constructor parameter of this class) .
|
||||
*
|
||||
* @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker
|
||||
* fails.
|
||||
*/
|
||||
protected void subscribeToQueue() throws TransportHandlerException {
|
||||
try {
|
||||
//TODO:: QoS Level take it from a variable
|
||||
client.subscribe(subscribeTopic, 0);
|
||||
log.info("Subscriber '" + clientId + "' subscribed to topic: " + subscribeTopic);
|
||||
} catch (MqttException ex) {
|
||||
//TODO:: Compulsory log of errors and remove formatted error
|
||||
String errorMsg = "MQTT Exception when trying to subscribe to topic: " +
|
||||
subscribeTopic + "\n\tReason: " + ex.getReasonCode() +
|
||||
"\n\tMessage: " + ex.getMessage() + "\n\tLocalMsg: " +
|
||||
ex.getLocalizedMessage() + "\n\tCause: " + ex.getCause() +
|
||||
"\n\tException: " + ex;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
|
||||
throw new TransportHandlerException(errorMsg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to publish reply-messages for the control signals received.
|
||||
* Invocation of this method calls its overloaded-method with a QoS equal to that of the
|
||||
* default value.
|
||||
*
|
||||
* @param topic the topic to which the reply message is to be published.
|
||||
* @param payLoad the reply-message (payload) of the MQTT publish action.
|
||||
*/
|
||||
protected void publishToQueue(String topic, String payLoad)
|
||||
throws TransportHandlerException {
|
||||
publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an overloaded method that publishes MQTT reply-messages for control signals
|
||||
* received form the IoT-Server.
|
||||
*
|
||||
* @param topic the topic to which the reply message is to be published
|
||||
* @param payLoad the reply-message (payload) of the MQTT publish action.
|
||||
* @param qos the Quality-of-Service of the current publish action.
|
||||
* Could be 0(At-most once), 1(At-least once) or 2(Exactly once)
|
||||
*/
|
||||
protected void publishToQueue(String topic, String payLoad, int qos, boolean retained)
|
||||
throws TransportHandlerException {
|
||||
try {
|
||||
client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully");
|
||||
}
|
||||
} catch (MqttException ex) {
|
||||
String errorMsg =
|
||||
"MQTT Client Error" + "\n\tReason: " + ex.getReasonCode() + "\n\tMessage: " +
|
||||
ex.getMessage() + "\n\tLocalMsg: " + ex.getLocalizedMessage() +
|
||||
"\n\tCause: " + ex.getCause() + "\n\tException: " + ex;
|
||||
log.info(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void publishToQueue(String topic, MqttMessage message)
|
||||
throws TransportHandlerException {
|
||||
try {
|
||||
client.publish(topic, message);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
|
||||
}
|
||||
} catch (MqttException ex) {
|
||||
//TODO:: Compulsory log of errors and remove formatted error
|
||||
String errorMsg =
|
||||
"MQTT Client Error" + "\n\tReason: " + ex.getReasonCode() + "\n\tMessage: " +
|
||||
ex.getMessage() + "\n\tLocalMsg: " + ex.getLocalizedMessage() +
|
||||
"\n\tCause: " + ex.getCause() + "\n\tException: " + ex;
|
||||
log.info(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback method which is triggered once the MQTT client losers its connection to the broker.
|
||||
* Spawns a new thread that executes necessary actions to try and reconnect to the endpoint.
|
||||
*
|
||||
* @param throwable a Throwable Object containing the details as to why the failure occurred.
|
||||
*/
|
||||
@Override
|
||||
public void connectionLost(Throwable throwable) {
|
||||
log.warn("Lost Connection for client: " + this.clientId +
|
||||
" to " + this.mqttBrokerEndPoint + ".\nThis was due to - " + throwable.getMessage());
|
||||
|
||||
Thread reconnectThread = new Thread() {
|
||||
public void run() {
|
||||
connect();
|
||||
}
|
||||
};
|
||||
reconnectThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method which is triggered upon receiving a MQTT Message from the broker. Spawns a
|
||||
* new thread that executes any actions to be taken with the received message.
|
||||
*
|
||||
* @param topic the MQTT-Topic to which the received message was published to and the
|
||||
* client was subscribed to.
|
||||
* @param mqttMessage the actual MQTT-Message that was received from the broker.
|
||||
*/
|
||||
@Override
|
||||
public void messageArrived(final String topic, final MqttMessage mqttMessage) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.info("Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic + "'.");
|
||||
}
|
||||
|
||||
Thread messageProcessorThread = new Thread() {
|
||||
public void run() {
|
||||
processIncomingMessage(mqttMessage, topic);
|
||||
}
|
||||
};
|
||||
messageProcessorThread.setDaemon(true);
|
||||
messageProcessorThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method which gets triggered upon successful completion of a message delivery to
|
||||
* the broker.
|
||||
*
|
||||
* @param iMqttDeliveryToken the MQTT-DeliveryToken which includes the details about the
|
||||
* specific message delivery.
|
||||
*/
|
||||
@Override
|
||||
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
|
||||
String message = "";
|
||||
try {
|
||||
message = iMqttDeliveryToken.getMessage().toString();
|
||||
} catch (MqttException e) {
|
||||
//TODO:: Throw errors
|
||||
log.error(
|
||||
"Error occurred whilst trying to read the message from the MQTT delivery token.");
|
||||
}
|
||||
String topic = iMqttDeliveryToken.getTopics()[0];
|
||||
String client = iMqttDeliveryToken.getClient().getClientId();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Message - '" + message + "' of client [" + client + "] for the topic (" +
|
||||
topic + ") was delivered successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the MQTT Broker.
|
||||
*/
|
||||
public void closeConnection() throws MqttException {
|
||||
if (client != null && isConnected()) {
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.xmpp;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.FromContainsFilter;
|
||||
import org.jivesoftware.smack.filter.OrFilter;
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.filter.ToContainsFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
|
||||
|
||||
/**
|
||||
* This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
|
||||
* the core functionality with regards to device-server communication regardless of the Transport protocol. This
|
||||
* specific class contains the HTTP-Transport specific implementations. The class implements utility methods for the
|
||||
* case of a HTTP communication. However, this "abstract class", even-though it implements the "TransportHandler"
|
||||
* interface, does not contain the logic relevant to the interface methods. The specific functionality of the
|
||||
* interface methods are intended to be implemented by the concrete class that extends this abstract class and
|
||||
* utilizes the HTTP specific functionality (ideally a device API writer who would like to communicate to the device
|
||||
* via HTTP Protocol).
|
||||
* <p/>
|
||||
* This class contains the IoT-Server specific implementation for all the XMPP functionality. This includes
|
||||
* connecting to a XMPP Server & Login-In using the device's/server's XMPP-Account, Setting listeners and filters on
|
||||
* incoming XMPP messages and Sending XMPP replies for messages received. Makes use of the 'Smack-XMPP' library
|
||||
* provided by jivesoftware/igniterealtime.
|
||||
*/
|
||||
public abstract class XMPPTransportHandler implements TransportHandler<Message> {
|
||||
private static final Log log = LogFactory.getLog(XMPPTransportHandler.class);
|
||||
|
||||
protected String server;
|
||||
protected int timeoutInterval; // millis
|
||||
|
||||
//TODO:: Shouldnt be hard-coded. Need to be read from configs
|
||||
private static final int DEFAULT_XMPP_PORT = 5222;
|
||||
private XMPPConnection connection;
|
||||
private int port;
|
||||
private ConnectionConfiguration config;
|
||||
private PacketFilter filter;
|
||||
private PacketListener listener;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for XMPPTransportHandler passing only the server-IP.
|
||||
*
|
||||
* @param server the IP of the XMPP server.
|
||||
*/
|
||||
protected XMPPTransportHandler(String server) {
|
||||
this.server = server;
|
||||
this.port = DEFAULT_XMPP_PORT;
|
||||
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
||||
initXMPPClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for XMPPTransportHandler passing server-IP and the XMPP-port.
|
||||
*
|
||||
* @param server the IP of the XMPP server.
|
||||
* @param port the XMPP server's port to connect to. (default - 5222)
|
||||
*/
|
||||
protected XMPPTransportHandler(String server, int port) {
|
||||
this.server = server;
|
||||
this.port = port;
|
||||
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
||||
initXMPPClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for XMPPTransportHandler passing server-IP, the XMPP-port and the
|
||||
* timeoutInterval used by listeners to the server and for reconnection schedules.
|
||||
*
|
||||
* @param server the IP of the XMPP server.
|
||||
* @param port the XMPP server's port to connect to. (default - 5222)
|
||||
* @param timeoutInterval the timeout interval to use for the connection and reconnection
|
||||
*/
|
||||
protected XMPPTransportHandler(String server, int port, int timeoutInterval) {
|
||||
this.server = server;
|
||||
this.port = port;
|
||||
this.timeoutInterval = timeoutInterval;
|
||||
initXMPPClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client's time-out-limit whilst waiting for XMPP-replies from server.
|
||||
*
|
||||
* @param millis the time in millis to be set as the time-out-limit whilst waiting for a
|
||||
* XMPP-reply.
|
||||
*/
|
||||
public void setTimeoutInterval(int millis) {
|
||||
this.timeoutInterval = millis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the connection to the XMPP-Server persists.
|
||||
*
|
||||
* @return true if the client is connected to the XMPP-Server, else false.
|
||||
*/
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return connection.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the XMPP Client. Sets the time-out-limit whilst waiting for XMPP-replies from
|
||||
* server. Sets the XMPP configurations to connect to the server and creates the
|
||||
* XMPPConnection object used for connecting and Logging-In.
|
||||
*/
|
||||
private void initXMPPClient() {
|
||||
log.info(String.format("Initializing connection to XMPP Server at %1$s via port " +
|
||||
"%2$d.", server, port));
|
||||
SmackConfiguration.setPacketReplyTimeout(timeoutInterval);
|
||||
config = new ConnectionConfiguration(server, port);
|
||||
// TODO:: Need to enable SASL-Authentication appropriately
|
||||
config.setSASLAuthenticationEnabled(false);
|
||||
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
|
||||
connection = new XMPPConnection(config);
|
||||
}
|
||||
|
||||
//TODO:: Re-check all exception handling
|
||||
|
||||
/**
|
||||
* Connects to the XMPP-Server and if attempt unsuccessful, then throws exception.
|
||||
*
|
||||
* @throws TransportHandlerException in the event of 'Connecting to' the XMPP server fails.
|
||||
*/
|
||||
protected void connectToServer() throws TransportHandlerException {
|
||||
try {
|
||||
connection.connect();
|
||||
log.info(String.format("Connection to XMPP Server at %1$s established successfully......", server));
|
||||
|
||||
} catch (XMPPException xmppExcepion) {
|
||||
String errorMsg = "Connection attempt to the XMPP Server at " + server + " via port " + port + " failed.";
|
||||
log.info(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, xmppExcepion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If successfully established connection, then tries to Log in using the device's XMPP
|
||||
* Account credentials.
|
||||
*
|
||||
* @param username the username of the device's XMPP-Account.
|
||||
* @param password the password of the device's XMPP-Account.
|
||||
* @param resource the resource the resource, specific to the XMPP-Account to which the login
|
||||
* is made to
|
||||
* @throws TransportHandlerException in the event of 'Logging into' the XMPP server fails.
|
||||
*/
|
||||
protected void loginToServer(String username, String password, String resource)
|
||||
throws TransportHandlerException {
|
||||
if (isConnected()) {
|
||||
try {
|
||||
if (resource == null) {
|
||||
connection.login(username, password);
|
||||
log.info(String.format("Logged into XMPP Server at %1$s as user %2$s......", server, username));
|
||||
} else {
|
||||
connection.login(username, password, resource);
|
||||
log.info(String.format("Logged into XMPP Server at %1$s as user %2$s on resource %3$s......",
|
||||
server, username, resource));
|
||||
}
|
||||
} catch (XMPPException xmppException) {
|
||||
String errorMsg =
|
||||
"Login attempt to the XMPP Server at " + server + " with username - " + username + " failed.";
|
||||
log.error(errorMsg);
|
||||
throw new TransportHandlerException(errorMsg, xmppException);
|
||||
}
|
||||
} else {
|
||||
String errorMsg = "Not connected to XMPP-Server to attempt Login. Please 'connectToServer' before Login";
|
||||
throw new TransportHandlerException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a filter for all the incoming XMPP-Messages on the Sender's JID (XMPP-Account ID).
|
||||
* Also creates a listener for the incoming messages and connects the listener to the
|
||||
* XMPPConnection alongside the set filter.
|
||||
*
|
||||
* @param senderJID the JID (XMPP-Account ID of the sender) to which the filter is to be set.
|
||||
*/
|
||||
protected void setFilterOnSender(String senderJID) {
|
||||
filter = new AndFilter(new PacketTypeFilter(Message.class), new FromContainsFilter(
|
||||
senderJID));
|
||||
listener = new PacketListener() {
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
if (packet instanceof Message) {
|
||||
final Message xmppMessage = (Message) packet;
|
||||
Thread msgProcessThread = new Thread() {
|
||||
public void run() {
|
||||
processIncomingMessage(xmppMessage);
|
||||
}
|
||||
};
|
||||
msgProcessThread.setDaemon(true);
|
||||
msgProcessThread.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connection.addPacketListener(listener, filter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a filter for all the incoming XMPP-Messages on the Receiver's JID (XMPP-Account ID).
|
||||
* Also creates a listener for the incoming messages and connects the listener to the
|
||||
* XMPPConnection alongside the set filter.
|
||||
*
|
||||
* @param receiverJID the JID (XMPP-Account ID of the receiver) to which the filter is to be
|
||||
* set.
|
||||
*/
|
||||
protected void setFilterOnReceiver(String receiverJID) {
|
||||
filter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter(
|
||||
receiverJID));
|
||||
listener = new PacketListener() {
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
if (packet instanceof Message) {
|
||||
final Message xmppMessage = (Message) packet;
|
||||
Thread msgProcessThread = new Thread() {
|
||||
public void run() {
|
||||
processIncomingMessage(xmppMessage);
|
||||
}
|
||||
};
|
||||
msgProcessThread.setDaemon(true);
|
||||
msgProcessThread.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connection.addPacketListener(listener, filter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a filter for all the incoming XMPP-Messages on the From-JID & To-JID (XMPP-Account IDs)
|
||||
* passed in. Also creates a listener for the incoming messages and connects the listener to
|
||||
* the XMPPConnection alongside the set filter.
|
||||
*
|
||||
* @param senderJID the From-JID (XMPP-Account ID) to which the filter is to be set.
|
||||
* @param receiverJID the To-JID (XMPP-Account ID) to which the filter is to be set.
|
||||
* @param andCondition if true: then filter is set with 'AND' operator (senderJID &&
|
||||
* receiverJID),
|
||||
* if false: then the filter is set with 'OR' operator (senderJID |
|
||||
* receiverJID)
|
||||
*/
|
||||
protected void setMessageFilterAndListener(String senderJID, String receiverJID, boolean
|
||||
andCondition) {
|
||||
PacketFilter jidFilter;
|
||||
|
||||
if (andCondition) {
|
||||
jidFilter = new AndFilter(new FromContainsFilter(senderJID), new ToContainsFilter(
|
||||
receiverJID));
|
||||
} else {
|
||||
jidFilter = new OrFilter(new FromContainsFilter(senderJID), new ToContainsFilter(
|
||||
receiverJID));
|
||||
}
|
||||
|
||||
filter = new AndFilter(new PacketTypeFilter(Message.class), jidFilter);
|
||||
listener = new PacketListener() {
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
if (packet instanceof Message) {
|
||||
final Message xmppMessage = (Message) packet;
|
||||
Thread msgProcessThread = new Thread() {
|
||||
public void run() {
|
||||
processIncomingMessage(xmppMessage);
|
||||
}
|
||||
};
|
||||
msgProcessThread.setDaemon(true);
|
||||
msgProcessThread.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connection.addPacketListener(listener, filter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends an XMPP message. Calls the overloaded method with Subject set to "Reply-From-Device"
|
||||
*
|
||||
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
|
||||
* @param message the XMPP-Message that is to be sent.
|
||||
*/
|
||||
protected void sendXMPPMessage(String JID, String message) {
|
||||
sendXMPPMessage(JID, message, "XMPP-Message");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overloaded method to send an XMPP message. Includes the subject to be mentioned in the
|
||||
* message that is sent.
|
||||
*
|
||||
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
|
||||
* @param message the XMPP-Message that is to be sent.
|
||||
* @param subject the subject that the XMPP-Message would carry.
|
||||
*/
|
||||
protected void sendXMPPMessage(String JID, String message, String subject) {
|
||||
Message xmppMessage = new Message();
|
||||
xmppMessage.setTo(JID);
|
||||
xmppMessage.setSubject(subject);
|
||||
xmppMessage.setBody(message);
|
||||
xmppMessage.setType(Message.Type.chat);
|
||||
sendXMPPMessage(JID, xmppMessage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends an XMPP message.
|
||||
*
|
||||
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
|
||||
* @param xmppMessage the XMPP-Message that is to be sent.
|
||||
*/
|
||||
protected void sendXMPPMessage(String JID, Message xmppMessage) {
|
||||
connection.sendPacket(xmppMessage);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Message: '" + xmppMessage.getBody() + "' sent to XMPP JID [" + JID +
|
||||
"] sent successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disables default debugger provided by the XMPPConnection.
|
||||
*/
|
||||
protected void disableDebugger() {
|
||||
connection.DEBUG_ENABLED = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the connection to the XMPP Server.
|
||||
*/
|
||||
public void closeConnection() {
|
||||
if (connection != null && isConnected()) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.ui.AgentUI;
|
||||
|
||||
import javax.sound.midi.InvalidMidiDataException;
|
||||
import javax.sound.midi.MidiSystem;
|
||||
import javax.sound.midi.MidiUnavailableException;
|
||||
import javax.sound.midi.Sequence;
|
||||
import javax.sound.midi.Sequencer;
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* This class use to emulate virtual hardware functionality
|
||||
*/
|
||||
public class VirtualHardwareManager {
|
||||
|
||||
private static final Log log = LogFactory.getLog(VirtualHardwareManager.class);
|
||||
|
||||
private static VirtualHardwareManager virtualHardwareManager;
|
||||
|
||||
private AgentUI agentUI;
|
||||
private Sequencer sequencer = null;
|
||||
|
||||
private int temperature = 30, humidity = 30;
|
||||
private int temperatureMin = 20, temperatureMax = 50, humidityMin = 20, humidityMax = 50;
|
||||
private int temperatureSVF = 50, humiditySVF = 50;
|
||||
private boolean isTemperatureRandomized, isHumidityRandomized;
|
||||
private boolean isTemperatureSmoothed, isHumiditySmoothed;
|
||||
|
||||
private VirtualHardwareManager(){
|
||||
}
|
||||
|
||||
public static VirtualHardwareManager getInstance(){
|
||||
if (virtualHardwareManager == null){
|
||||
virtualHardwareManager = new VirtualHardwareManager();
|
||||
}
|
||||
return virtualHardwareManager;
|
||||
}
|
||||
|
||||
public void init(){
|
||||
try {
|
||||
// Set System L&F for Device UI
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (UnsupportedLookAndFeelException e) {
|
||||
log.error(
|
||||
"'UnsupportedLookAndFeelException' error occurred whilst initializing the" +
|
||||
" Agent UI.");
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.error(
|
||||
"'ClassNotFoundException' error occurred whilst initializing the Agent UI.");
|
||||
} catch (InstantiationException e) {
|
||||
log.error(
|
||||
"'InstantiationException' error occurred whilst initializing the Agent UI.");
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error(
|
||||
"'IllegalAccessException' error occurred whilst initializing the Agent UI.");
|
||||
}
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
agentUI = new AgentUI();
|
||||
agentUI.setVisible(true);
|
||||
}
|
||||
});
|
||||
setAudioSequencer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get temperature from emulated device
|
||||
* @return Temperature
|
||||
*/
|
||||
public int getTemperature() {
|
||||
if (isTemperatureRandomized) {
|
||||
temperature = getRandom(temperatureMax, temperatureMin, temperature,
|
||||
isTemperatureSmoothed, temperatureSVF);
|
||||
agentUI.updateTemperature(temperature);
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(int temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get humidity from emulated device
|
||||
* @return Humidity
|
||||
*/
|
||||
public int getHumidity() {
|
||||
if (isHumidityRandomized) {
|
||||
humidity = getRandom(humidityMax, humidityMin, humidity, isHumiditySmoothed,
|
||||
humiditySVF);
|
||||
agentUI.updateHumidity(humidity);
|
||||
}
|
||||
return humidity;
|
||||
}
|
||||
|
||||
public void setHumidity(int humidity) {
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
public void setTemperatureMin(int temperatureMin) {
|
||||
this.temperatureMin = temperatureMin;
|
||||
}
|
||||
|
||||
public void setTemperatureMax(int temperatureMax) {
|
||||
this.temperatureMax = temperatureMax;
|
||||
}
|
||||
|
||||
public void setHumidityMin(int humidityMin) {
|
||||
this.humidityMin = humidityMin;
|
||||
}
|
||||
|
||||
public void setHumidityMax(int humidityMax) {
|
||||
this.humidityMax = humidityMax;
|
||||
}
|
||||
|
||||
public void setIsHumidityRandomized(boolean isHumidityRandomized) {
|
||||
this.isHumidityRandomized = isHumidityRandomized;
|
||||
}
|
||||
|
||||
public void setIsTemperatureRandomized(boolean isTemperatureRandomized) {
|
||||
this.isTemperatureRandomized = isTemperatureRandomized;
|
||||
}
|
||||
|
||||
public void setTemperatureSVF(int temperatureSVF) {
|
||||
this.temperatureSVF = temperatureSVF;
|
||||
}
|
||||
|
||||
public void setHumiditySVF(int humiditySVF) {
|
||||
this.humiditySVF = humiditySVF;
|
||||
}
|
||||
|
||||
public void setIsTemperatureSmoothed(boolean isTemperatureSmoothed) {
|
||||
this.isTemperatureSmoothed = isTemperatureSmoothed;
|
||||
}
|
||||
|
||||
public void setIsHumiditySmoothed(boolean isHumiditySmoothed) {
|
||||
this.isHumiditySmoothed = isHumiditySmoothed;
|
||||
}
|
||||
|
||||
public void changeAlarmStatus(boolean isOn) {
|
||||
agentUI.setAlarmStatus(isOn);
|
||||
|
||||
if (isOn) {
|
||||
sequencer.start();
|
||||
} else {
|
||||
sequencer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private int getRandom(int max, int min, int current, boolean isSmoothed, int svf) {
|
||||
if (isSmoothed) {
|
||||
int offset = (max - min) * svf / 100;
|
||||
double mx = current + offset;
|
||||
max = (mx > max) ? max : (int) Math.round(mx);
|
||||
double mn = current - offset;
|
||||
min = (mn < min) ? min : (int) Math.round(mn);
|
||||
}
|
||||
try {
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
return secureRandom.nextInt(max - min) + min;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
|
||||
}
|
||||
}
|
||||
|
||||
private void setAudioSequencer() {
|
||||
InputStream audioSrc = AgentUtilOperations.class.getResourceAsStream(
|
||||
"/" + AgentConstants.AUDIO_FILE_NAME);
|
||||
Sequence sequence;
|
||||
|
||||
try {
|
||||
sequence = MidiSystem.getSequence(audioSrc);
|
||||
sequencer = MidiSystem.getSequencer();
|
||||
if(sequencer != null) {
|
||||
sequencer.open();
|
||||
sequencer.setSequence(sequence);
|
||||
sequencer.setLoopCount(Clip.LOOP_CONTINUOUSLY);
|
||||
}
|
||||
} catch (InvalidMidiDataException e) {
|
||||
log.error("AudioReader: Error whilst setting MIDI Audio reader sequence");
|
||||
} catch (IOException e) {
|
||||
log.error("AudioReader: Error whilst getting audio sequence from stream");
|
||||
} catch (MidiUnavailableException e) {
|
||||
log.error("AudioReader: Error whilst openning MIDI Audio reader sequencer");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,910 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.ui;
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.VirtualHardwareManager;
|
||||
|
||||
import java.awt.*;
|
||||
import java.net.URL;
|
||||
import java.util.Calendar;
|
||||
import javax.swing.*;
|
||||
|
||||
public class AgentUI extends JFrame {
|
||||
|
||||
private boolean isTemperatureRandomized, isHumidityRandomized;
|
||||
private boolean isTemperatureSmoothed, isHumiditySmoothed;
|
||||
|
||||
private volatile boolean isAlarmOn = false;
|
||||
|
||||
private JLabel picLabelBulbOn, picLabelBulbOff;
|
||||
|
||||
// Variables declaration - do not modify
|
||||
private JCheckBox chkbxEmulate;
|
||||
private JCheckBox chkbxHumidityRandom;
|
||||
private JCheckBox chkbxHumiditySmooth;
|
||||
private JCheckBox chkbxTemperatureRandom;
|
||||
private JCheckBox chkbxTemperatureSmooth;
|
||||
private JComboBox cmbInterface;
|
||||
private JComboBox cmbPeriod;
|
||||
private JComboBox cmbProtocol;
|
||||
private JLabel jLabel1;
|
||||
private JLabel jLabel10;
|
||||
private JLabel jLabel11;
|
||||
private JLabel jLabel12;
|
||||
private JLabel jLabel2;
|
||||
private JLabel jLabel20;
|
||||
private JLabel jLabel23;
|
||||
private JLabel jLabel24;
|
||||
private JLabel jLabel25;
|
||||
private JLabel jLabel3;
|
||||
private JLabel jLabel4;
|
||||
private JLabel jLabel5;
|
||||
private JLabel jLabel6;
|
||||
private JLabel jLabel7;
|
||||
private JLabel jLabel8;
|
||||
private JLabel jLabel9;
|
||||
private JPanel jPanel1;
|
||||
private JPanel jPanel2;
|
||||
private JPanel jPanel3;
|
||||
private JPanel jPanel4;
|
||||
private JPanel jPanel6;
|
||||
private JPanel jPanel7;
|
||||
private JPanel jPanel8;
|
||||
private JPanel jPanel9;
|
||||
private JSeparator jSeparator1;
|
||||
private JSeparator jSeparator5;
|
||||
private JLabel lblAgentName;
|
||||
private JLabel lblStatus;
|
||||
private JPanel pnlBulbStatus;
|
||||
private JSpinner spinnerHumidity;
|
||||
private JSpinner spinnerInterval;
|
||||
private JSpinner spinnerTemperature;
|
||||
private JTextField txtHumidityMax;
|
||||
private JTextField txtHumidityMin;
|
||||
private JTextField txtHumiditySVF;
|
||||
private JTextField txtTemperatureMax;
|
||||
private JTextField txtTemperatureMin;
|
||||
private JTextField txtTemperatureSVF;
|
||||
// End of variables declaration
|
||||
|
||||
private Runnable uiUpdater = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pnlBulbStatus.removeAll();
|
||||
pnlBulbStatus.add(isAlarmOn ? picLabelBulbOn : picLabelBulbOff);
|
||||
pnlBulbStatus.updateUI();
|
||||
lblStatus.setText(AgentManager.getInstance().getAgentStatus());
|
||||
if (isTemperatureRandomized) {
|
||||
txtTemperatureMinActionPerformed(null);
|
||||
txtTemperatureMaxActionPerformed(null);
|
||||
if (isTemperatureSmoothed) {
|
||||
txtTemperatureSVFActionPerformed(null);
|
||||
}
|
||||
}
|
||||
if (isHumidityRandomized) {
|
||||
txtHumidityMinActionPerformed(null);
|
||||
txtHumidityMaxActionPerformed(null);
|
||||
if (isHumiditySmoothed) {
|
||||
txtHumiditySVFActionPerformed(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates new form AgentUI
|
||||
*/
|
||||
public AgentUI() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void initComponents() {
|
||||
|
||||
lblAgentName = new JLabel();
|
||||
jLabel2 = new JLabel();
|
||||
jPanel1 = new JPanel();
|
||||
jLabel3 = new JLabel();
|
||||
pnlBulbStatus = new JPanel();
|
||||
jPanel2 = new JPanel();
|
||||
jLabel4 = new JLabel();
|
||||
chkbxTemperatureRandom = new JCheckBox();
|
||||
jSeparator1 = new JSeparator();
|
||||
jPanel7 = new JPanel();
|
||||
jLabel5 = new JLabel();
|
||||
txtTemperatureMin = new JTextField();
|
||||
jLabel6 = new JLabel();
|
||||
txtTemperatureMax = new JTextField();
|
||||
jLabel10 = new JLabel();
|
||||
txtTemperatureSVF = new JTextField();
|
||||
spinnerTemperature = new JSpinner();
|
||||
chkbxTemperatureSmooth = new JCheckBox();
|
||||
jPanel6 = new JPanel();
|
||||
jLabel20 = new JLabel();
|
||||
lblStatus = new JLabel();
|
||||
jPanel8 = new JPanel();
|
||||
jLabel23 = new JLabel();
|
||||
chkbxHumidityRandom = new JCheckBox();
|
||||
jSeparator5 = new JSeparator();
|
||||
jPanel9 = new JPanel();
|
||||
jLabel24 = new JLabel();
|
||||
txtHumidityMin = new JTextField();
|
||||
jLabel25 = new JLabel();
|
||||
txtHumidityMax = new JTextField();
|
||||
txtHumiditySVF = new JTextField();
|
||||
jLabel11 = new JLabel();
|
||||
spinnerHumidity = new JSpinner();
|
||||
chkbxHumiditySmooth = new JCheckBox();
|
||||
jPanel3 = new JPanel();
|
||||
jLabel7 = new JLabel();
|
||||
spinnerInterval = new JSpinner();
|
||||
jLabel8 = new JLabel();
|
||||
jLabel9 = new JLabel();
|
||||
cmbProtocol = new JComboBox();
|
||||
jLabel12 = new JLabel();
|
||||
cmbInterface = new JComboBox();
|
||||
jPanel4 = new JPanel();
|
||||
chkbxEmulate = new JCheckBox();
|
||||
cmbPeriod = new JComboBox();
|
||||
jLabel1 = new JLabel();
|
||||
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
setTitle("Fire Alarm Emulator");
|
||||
setResizable(false);
|
||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation(dim.width / 2 - 650 / 2, dim.height / 2 - 440 / 2);
|
||||
|
||||
lblAgentName.setFont(new Font("Cantarell", 1, 24)); // NOI18N
|
||||
lblAgentName.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
lblAgentName.setText("Device Name: " + AgentManager.getInstance().getDeviceName());
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
int currentYear = now.get(Calendar.YEAR);
|
||||
jLabel2.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
jLabel2.setText("Copyright (c) " + currentYear + ", WSO2 Inc.");
|
||||
|
||||
jPanel1.setBackground(new Color(220, 220, 220));
|
||||
|
||||
jLabel3.setFont(new Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel3.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
jLabel3.setText("Alarm Status");
|
||||
|
||||
pnlBulbStatus.setBackground(new Color(220, 220, 220));
|
||||
|
||||
GroupLayout pnlBulbStatusLayout = new GroupLayout(pnlBulbStatus);
|
||||
pnlBulbStatus.setLayout(pnlBulbStatusLayout);
|
||||
pnlBulbStatusLayout.setHorizontalGroup(
|
||||
pnlBulbStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
pnlBulbStatusLayout.setVerticalGroup(
|
||||
pnlBulbStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 167, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(pnlBulbStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel3, GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel3)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlBulbStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel2.setBackground(new Color(220, 220, 220));
|
||||
|
||||
jLabel4.setFont(new Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel4.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
jLabel4.setText("Temperature");
|
||||
|
||||
chkbxTemperatureRandom.setText("Randomize Data");
|
||||
chkbxTemperatureRandom.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxTemperatureRandomActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator1.setOrientation(SwingConstants.VERTICAL);
|
||||
|
||||
jPanel7.setBackground(new Color(220, 220, 220));
|
||||
|
||||
jLabel5.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
jLabel5.setText("Min");
|
||||
|
||||
txtTemperatureMin.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtTemperatureMin.setText("20");
|
||||
txtTemperatureMin.setEnabled(false);
|
||||
txtTemperatureMin.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureMinActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel6.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
jLabel6.setText("Max");
|
||||
|
||||
txtTemperatureMax.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtTemperatureMax.setText("50");
|
||||
txtTemperatureMax.setEnabled(false);
|
||||
txtTemperatureMax.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureMaxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel10.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
jLabel10.setText("SV %");
|
||||
|
||||
txtTemperatureSVF.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtTemperatureSVF.setText("50");
|
||||
txtTemperatureSVF.setEnabled(false);
|
||||
txtTemperatureSVF.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureSVFActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
GroupLayout jPanel7Layout = new GroupLayout(jPanel7);
|
||||
jPanel7.setLayout(jPanel7Layout);
|
||||
jPanel7Layout.setHorizontalGroup(
|
||||
jPanel7Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel7Layout.createSequentialGroup()
|
||||
.addComponent(jLabel5)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureMin, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel6)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureMax, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel10)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureSVF, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel7Layout.setVerticalGroup(
|
||||
jPanel7Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel7Layout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel7Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(txtTemperatureMin, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtTemperatureMax, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel6)
|
||||
.addComponent(jLabel5)
|
||||
.addComponent(jLabel10)
|
||||
.addComponent(txtTemperatureSVF, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(35, 35, 35))
|
||||
);
|
||||
|
||||
spinnerTemperature.setFont(new Font("Cantarell", 1, 24)); // NOI18N
|
||||
spinnerTemperature.setModel(new SpinnerNumberModel(30, 0, 100, 1));
|
||||
spinnerTemperature.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerTemperatureStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkbxTemperatureSmooth.setText("Smooth Variation");
|
||||
chkbxTemperatureSmooth.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxTemperatureSmoothActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
|
||||
jPanel2.setLayout(jPanel2Layout);
|
||||
jPanel2Layout.setHorizontalGroup(
|
||||
jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jLabel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(spinnerTemperature))
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 6, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(chkbxTemperatureRandom)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(chkbxTemperatureSmooth)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel2Layout.setVerticalGroup(
|
||||
jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator1)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(
|
||||
|
||||
GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxTemperatureRandom)
|
||||
.addComponent(chkbxTemperatureSmooth))
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel7, GroupLayout.PREFERRED_SIZE, 51, GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(jLabel4, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerTemperature)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel6.setBackground(new Color(253, 254, 209));
|
||||
|
||||
jLabel20.setText("Connection Status:");
|
||||
jLabel20.setVerticalTextPosition(SwingConstants.TOP);
|
||||
|
||||
lblStatus.setFont(new Font("Cantarell", 1, 15)); // NOI18N
|
||||
lblStatus.setText("Not Connected");
|
||||
|
||||
GroupLayout jPanel6Layout = new GroupLayout(jPanel6);
|
||||
jPanel6.setLayout(jPanel6Layout);
|
||||
jPanel6Layout.setHorizontalGroup(
|
||||
jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel6Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel20)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel6Layout.setVerticalGroup(
|
||||
jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jLabel20, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblStatus)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel8.setBackground(new Color(220, 220, 220));
|
||||
|
||||
jLabel23.setFont(new Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel23.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
jLabel23.setText("Humidity");
|
||||
|
||||
chkbxHumidityRandom.setText("Randomize Data");
|
||||
chkbxHumidityRandom.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxHumidityRandomActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator5.setOrientation(SwingConstants.VERTICAL);
|
||||
|
||||
jPanel9.setBackground(new Color(220, 220, 220));
|
||||
|
||||
jLabel24.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
jLabel24.setText("Min");
|
||||
|
||||
txtHumidityMin.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtHumidityMin.setText("20");
|
||||
txtHumidityMin.setEnabled(false);
|
||||
txtHumidityMin.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumidityMinActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel25.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
jLabel25.setText("Max");
|
||||
|
||||
txtHumidityMax.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtHumidityMax.setText("50");
|
||||
txtHumidityMax.setEnabled(false);
|
||||
txtHumidityMax.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumidityMaxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
txtHumiditySVF.setHorizontalAlignment(JTextField.CENTER);
|
||||
txtHumiditySVF.setText("50");
|
||||
txtHumiditySVF.setEnabled(false);
|
||||
txtHumiditySVF.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumiditySVFActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel11.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
jLabel11.setText("SV %");
|
||||
|
||||
GroupLayout jPanel9Layout = new GroupLayout(jPanel9);
|
||||
jPanel9.setLayout(jPanel9Layout);
|
||||
jPanel9Layout.setHorizontalGroup(
|
||||
jPanel9Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel9Layout.createSequentialGroup()
|
||||
.addComponent(jLabel24)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumidityMin, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel25)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumidityMax, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel11)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumiditySVF, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel9Layout.setVerticalGroup(
|
||||
jPanel9Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel9Layout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel9Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel9Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(txtHumiditySVF, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel9Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(txtHumidityMin, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtHumidityMax, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel25)
|
||||
.addComponent(jLabel24)))
|
||||
.addGap(35, 35, 35))
|
||||
);
|
||||
|
||||
spinnerHumidity.setFont(new Font("Cantarell", 1, 24)); // NOI18N
|
||||
spinnerHumidity.setModel(new SpinnerNumberModel(30, 0, 100, 1));
|
||||
spinnerHumidity.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerHumidityStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkbxHumiditySmooth.setText("Smooth Variation");
|
||||
chkbxHumiditySmooth.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxHumiditySmoothActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
GroupLayout jPanel8Layout = new GroupLayout(jPanel8);
|
||||
jPanel8.setLayout(jPanel8Layout);
|
||||
jPanel8Layout.setHorizontalGroup(
|
||||
jPanel8Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel23, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(spinnerHumidity))
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator5, GroupLayout.PREFERRED_SIZE, 6, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel8Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jPanel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addComponent(chkbxHumidityRandom)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(chkbxHumiditySmooth)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel8Layout.setVerticalGroup(
|
||||
jPanel8Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator5)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(
|
||||
GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxHumidityRandom)
|
||||
.addComponent(chkbxHumiditySmooth))
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel9, GroupLayout.PREFERRED_SIZE, 51, GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 1, Short.MAX_VALUE))
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addComponent(jLabel23, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerHumidity)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel3.setBackground(new Color(207, 233, 234));
|
||||
|
||||
jLabel7.setText("Data Push Interval:");
|
||||
|
||||
spinnerInterval.setModel(new SpinnerNumberModel(Integer.valueOf(AgentManager.getInstance().getPushInterval()), Integer.valueOf(1), null, Integer.valueOf(1)));
|
||||
spinnerInterval.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerIntervalStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel8.setText("Seconds");
|
||||
|
||||
jLabel9.setText("Protocol:");
|
||||
|
||||
cmbProtocol.setModel(new DefaultComboBoxModel(new String[] { "MQTT", "XMPP", "HTTP" }));
|
||||
cmbProtocol.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbProtocolActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel12.setText("Interface:");
|
||||
|
||||
cmbInterface.setModel(new DefaultComboBoxModel(new String[] { "eth0" }));
|
||||
cmbInterface.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbInterfaceActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
|
||||
jPanel3.setLayout(jPanel3Layout);
|
||||
jPanel3Layout.setHorizontalGroup(
|
||||
jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel3Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel7)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerInterval, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel8)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel12)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbInterface, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel9)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbProtocol, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel3Layout.setVerticalGroup(
|
||||
jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel12)
|
||||
.addComponent(cmbInterface, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(spinnerInterval, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel8)
|
||||
.addComponent(jLabel9)
|
||||
.addComponent(cmbProtocol, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel4.setBackground(new Color(169, 253, 173));
|
||||
|
||||
chkbxEmulate.setText("Emulate data");
|
||||
chkbxEmulate.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxEmulateActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cmbPeriod.setModel(new DefaultComboBoxModel(new String[] { "1 hour", "1 day", "1 week", "1 month " }));
|
||||
cmbPeriod.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbPeriodActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText("Emulation Period");
|
||||
|
||||
GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
|
||||
jPanel4.setLayout(jPanel4Layout);
|
||||
jPanel4Layout.setHorizontalGroup(
|
||||
jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(chkbxEmulate)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbPeriod, GroupLayout.PREFERRED_SIZE, 162, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel4Layout.setVerticalGroup(
|
||||
jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
|
||||
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxEmulate)
|
||||
.addComponent(cmbPeriod, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel1))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
GroupLayout layout = new GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblAgentName, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel6, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(
|
||||
GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel8, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addComponent(jLabel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblAgentName, GroupLayout.PREFERRED_SIZE, 53, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel8, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel2, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
|
||||
chkbxTemperatureSmooth.setEnabled(false);
|
||||
chkbxTemperatureSmooth.setEnabled(false);
|
||||
|
||||
cmbInterface.removeAllItems();
|
||||
for (String item : AgentManager.getInstance().getInterfaceList()){
|
||||
cmbInterface.addItem(item);
|
||||
}
|
||||
cmbInterface.setEnabled(false);
|
||||
|
||||
cmbProtocol.removeAllItems();
|
||||
for (String item : AgentManager.getInstance().getProtocolList()){
|
||||
cmbProtocol.addItem(item);
|
||||
}
|
||||
cmbProtocol.setSelectedItem(AgentConstants.DEFAULT_PROTOCOL);
|
||||
|
||||
URL urlAlarmOn = this.getClass().getResource("/alarm-on.gif");
|
||||
ImageIcon imageIconAlarmOn = new ImageIcon(urlAlarmOn);
|
||||
|
||||
URL urlAlarmOff = this.getClass().getResource("/alarm-off.gif");
|
||||
ImageIcon imageIconAlarmOff = new ImageIcon(urlAlarmOff);
|
||||
|
||||
picLabelBulbOn = new JLabel(imageIconAlarmOn);
|
||||
picLabelBulbOn.setSize(pnlBulbStatus.getSize());
|
||||
|
||||
picLabelBulbOff = new JLabel(imageIconAlarmOff);
|
||||
picLabelBulbOff.setSize(pnlBulbStatus.getSize());
|
||||
|
||||
new Thread(uiUpdater).start();
|
||||
|
||||
AgentManager.getInstance().setDeviceReady(true);
|
||||
}
|
||||
|
||||
|
||||
private void chkbxTemperatureRandomActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
isTemperatureRandomized = chkbxTemperatureRandom.isSelected();
|
||||
VirtualHardwareManager.getInstance().setIsTemperatureRandomized(isTemperatureRandomized);
|
||||
spinnerTemperature.setEnabled(!isTemperatureRandomized);
|
||||
txtTemperatureMax.setEnabled(isTemperatureRandomized);
|
||||
txtTemperatureMin.setEnabled(isTemperatureRandomized);
|
||||
chkbxTemperatureSmooth.setEnabled(isTemperatureRandomized);
|
||||
txtTemperatureSVF.setEnabled(isTemperatureRandomized && isTemperatureSmoothed);
|
||||
}
|
||||
|
||||
private void chkbxHumidityRandomActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
isHumidityRandomized = chkbxHumidityRandom.isSelected();
|
||||
VirtualHardwareManager.getInstance().setIsHumidityRandomized(isHumidityRandomized);
|
||||
spinnerHumidity.setEnabled(!isHumidityRandomized);
|
||||
txtHumidityMax.setEnabled(isHumidityRandomized);
|
||||
txtHumidityMin.setEnabled(isHumidityRandomized);
|
||||
chkbxHumiditySmooth.setEnabled(isHumidityRandomized);
|
||||
txtTemperatureSVF.setEnabled(isHumidityRandomized && isHumiditySmoothed);
|
||||
}
|
||||
|
||||
private void spinnerTemperatureStateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
if (!isTemperatureRandomized) {
|
||||
try {
|
||||
int temperature = Integer.parseInt(spinnerTemperature.getValue().toString());
|
||||
VirtualHardwareManager.getInstance().setTemperature(temperature);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid temperature value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
spinnerTemperature.setValue(VirtualHardwareManager.getInstance().getTemperature());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spinnerHumidityStateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
if (!isHumidityRandomized) {
|
||||
try {
|
||||
int humidity = Integer.parseInt(spinnerHumidity.getValue().toString());
|
||||
VirtualHardwareManager.getInstance().setHumidity(humidity);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid humidity value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
spinnerHumidity.setValue(VirtualHardwareManager.getInstance().getHumidity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void txtTemperatureMinActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int temperature = Integer.parseInt(txtTemperatureMin.getText());
|
||||
VirtualHardwareManager.getInstance().setTemperatureMin(temperature);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid temperature value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtTemperatureMin.setText("20");
|
||||
}
|
||||
}
|
||||
|
||||
private void txtTemperatureMaxActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int temperature = Integer.parseInt(txtTemperatureMax.getText());
|
||||
VirtualHardwareManager.getInstance().setTemperatureMax(temperature);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid temperature value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtTemperatureMax.setText("50");
|
||||
}
|
||||
}
|
||||
|
||||
private void txtHumidityMinActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int humidity = Integer.parseInt(txtHumidityMin.getText());
|
||||
VirtualHardwareManager.getInstance().setHumidityMin(humidity);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid humidity value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtHumidityMin.setText("20");
|
||||
}
|
||||
}
|
||||
|
||||
private void txtHumidityMaxActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int humidity = Integer.parseInt(txtHumidityMax.getText());
|
||||
VirtualHardwareManager.getInstance().setHumidityMax(humidity);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid humidity value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtHumidityMax.setText("50");
|
||||
}
|
||||
}
|
||||
|
||||
private void spinnerIntervalStateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
try {
|
||||
int interval = Integer.parseInt(spinnerInterval.getValue().toString());
|
||||
AgentManager.getInstance().setPushInterval(interval);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid time interval value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
spinnerInterval.setValue(5);
|
||||
}
|
||||
}
|
||||
|
||||
private void cmbInterfaceActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
AgentManager.getInstance().setInterface(cmbInterface.getSelectedIndex());
|
||||
}
|
||||
|
||||
private void cmbProtocolActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
if (cmbProtocol.getSelectedIndex() != -1 && cmbProtocol.getItemAt(
|
||||
cmbProtocol.getSelectedIndex()).equals(AgentConstants.HTTP_PROTOCOL)) {
|
||||
cmbInterface.setEnabled(true);
|
||||
} else {
|
||||
cmbInterface.setEnabled(false);
|
||||
}
|
||||
|
||||
AgentManager.getInstance().setProtocol(cmbProtocol.getSelectedIndex());
|
||||
|
||||
}
|
||||
|
||||
private void txtTemperatureSVFActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int temperatureSVF = Integer.parseInt(txtTemperatureSVF.getText());
|
||||
VirtualHardwareManager.getInstance().setTemperatureSVF(temperatureSVF);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtTemperatureSVF.setText("50");
|
||||
}
|
||||
}
|
||||
|
||||
private void txtHumiditySVFActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
try {
|
||||
int humiditySVF = Integer.parseInt(txtHumiditySVF.getText());
|
||||
VirtualHardwareManager.getInstance().setHumiditySVF(humiditySVF);
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(this, "Invalid value", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
txtHumiditySVF.setText("50");
|
||||
}
|
||||
}
|
||||
|
||||
private void chkbxTemperatureSmoothActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
isTemperatureSmoothed = chkbxTemperatureSmooth.isSelected();
|
||||
txtTemperatureSVF.setEnabled(isTemperatureSmoothed);
|
||||
VirtualHardwareManager.getInstance().setIsTemperatureSmoothed(isTemperatureSmoothed);
|
||||
}
|
||||
|
||||
private void chkbxHumiditySmoothActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
isHumiditySmoothed = chkbxHumiditySmooth.isSelected();
|
||||
txtHumiditySVF.setEnabled(isHumiditySmoothed);
|
||||
VirtualHardwareManager.getInstance().setIsHumiditySmoothed(isHumiditySmoothed);
|
||||
}
|
||||
|
||||
private void cmbPeriodActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
// TODO add your handling code here:
|
||||
}
|
||||
|
||||
private void chkbxEmulateActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
// TODO add your handling code here:
|
||||
}
|
||||
|
||||
public void setAlarmStatus(boolean isAlarmOn) {
|
||||
this.isAlarmOn = isAlarmOn;
|
||||
}
|
||||
|
||||
public void updateTemperature(int temperature) {
|
||||
spinnerTemperature.setValue(temperature);
|
||||
spinnerTemperature.updateUI();
|
||||
}
|
||||
|
||||
public void updateHumidity(int humidity) {
|
||||
spinnerHumidity.setValue(humidity);
|
||||
spinnerHumidity.updateUI();
|
||||
}
|
||||
|
||||
}
|
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,35 @@
|
||||
ad#
|
||||
# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
|
||||
#[Device-Configurations]
|
||||
server-name=WSO2IoTServer
|
||||
owner=shabirmean
|
||||
deviceId=t4ctwq8qfl11
|
||||
device-name=SMEAN_t4ctwq8qfl11
|
||||
controller-context=/virtual_firealarm/device
|
||||
scep-context=/virtual_firealarm_scep
|
||||
https-ep=https://localhost:9443
|
||||
http-ep=http://localhost:9763
|
||||
apim-ep=http://192.168.67.21:8281
|
||||
mqtt-ep=tcp://192.168.67.21:1883
|
||||
xmpp-ep=http://204.232.188.215:5222
|
||||
auth-method=token
|
||||
auth-token=79d68b50ae5f5a06e812889979b3453
|
||||
refresh-token=8bdda6359dddad218cff3354d5a8cb3b
|
||||
network-interface=en0
|
||||
push-interval=14
|
||||
xmpp-server-name=localhost
|
Binary file not shown.
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="VirtualAgentUI" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project VirtualAgentUI.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="VirtualAgentUI-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=e60df945
|
||||
build.xml.script.CRC32=7c331eea
|
||||
build.xml.stylesheet.CRC32=8064a381@1.75.2.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=e60df945
|
||||
nbproject/build-impl.xml.script.CRC32=18800575
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
|
@ -0,0 +1,2 @@
|
||||
compile.on.save=true
|
||||
user.properties.file=/home/lahiru/.netbeans/8.2/build.properties
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||
<group>
|
||||
<file>file:/home/lahiru/WSO2IOT/carbon-device-mgt-plugins/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/ui/src/org/wso2/carbon/device/mgt/iot/agent/virtual/VirtualAgentUI.java</file>
|
||||
</group>
|
||||
</open-files>
|
||||
</project-private>
|
@ -0,0 +1,73 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processor.options=
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/VirtualAgentUI.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.8
|
||||
javac.target=1.8
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=org.wso2.carbon.device.mgt.iot.agent.virtual.VirtualAgentUI
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>VirtualAgentUI</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
After Width: | Height: | Size: 6.8 KiB |
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.agent.virtual;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import org.wso2.carbon.device.mgt.iot.agent.virtual.ui.AgentUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author charitha
|
||||
*/
|
||||
public class VirtualAgentUI {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// Set System L&F
|
||||
UIManager.setLookAndFeel(
|
||||
UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
|
||||
// handle exception
|
||||
}
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new AgentUI().setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,779 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="3"/>
|
||||
<Property name="title" type="java.lang.String" value="Fire Alarm Emulator"/>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblAgentName" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jPanel6" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel8" max="32767" attributes="0"/>
|
||||
<Component id="jPanel2" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="jLabel2" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jPanel4" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jPanel3" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblAgentName" min="-2" pref="53" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jPanel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel8" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jPanel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel4" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" pref="28" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="lblAgentName">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="24" style="1"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" value="Device Name: WSO2 IoT Virtual Agent"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="Copyright (c) 2015, WSO2 Inc."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="pnlBulbStatus" max="32767" attributes="0"/>
|
||||
<Component id="jLabel3" pref="190" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pnlBulbStatus" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="18" style="0"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="Bulb Status"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="pnlBulbStatus">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="167" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="jLabel4" max="32767" attributes="0"/>
|
||||
<Component id="spinnerTemperature" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel7" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="chkbxTemperatureRandom" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="chkbxTemperatureSmooth" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jSeparator1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="chkbxTemperatureRandom" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkbxTemperatureSmooth" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel7" min="-2" pref="51" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel4" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spinnerTemperature" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="18" style="0"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="Temperature"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkbxTemperatureRandom">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Randomize Data"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkbxTemperatureRandomActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel7">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtTemperatureMin" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtTemperatureMax" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtTemperatureSVF" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="txtTemperatureMin" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtTemperatureMax" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtTemperatureSVF" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" value="Min"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtTemperatureMin">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="20"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtTemperatureMinActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" value="Max"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtTemperatureMax">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="50"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtTemperatureMaxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel10">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" value="SV %"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtTemperatureSVF">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="50"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtTemperatureSVFActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerTemperature">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="24" style="1"/>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="30" maximum="100" minimum="0" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerTemperatureStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkbxTemperatureSmooth">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Smooth Variation"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkbxTemperatureSmoothActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel6">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="d1" green="fe" red="fd" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel20" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblStatus" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="273" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="jLabel20" pref="27" max="32767" attributes="0"/>
|
||||
<Component id="lblStatus" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel20">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Connection Status:"/>
|
||||
<Property name="verticalTextPosition" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblStatus">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="15" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Not Connected"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel8">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel23" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<Component id="spinnerHumidity" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jSeparator5" min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="jPanel9" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="chkbxHumidityRandom" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="chkbxHumiditySmooth" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jSeparator5" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="chkbxHumidityRandom" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkbxHumiditySmooth" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel9" min="-2" pref="51" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel23" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spinnerHumidity" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel23">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="18" style="0"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="Humidity"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkbxHumidityRandom">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Randomize Data"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkbxHumidityRandomActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator5">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel9">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="dc" green="dc" red="dc" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel24" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtHumidityMin" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel25" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtHumidityMax" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel11" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtHumiditySVF" min="-2" pref="45" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtHumiditySVF" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="txtHumidityMin" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtHumidityMax" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel25" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel24" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel24">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" value="Min"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtHumidityMin">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="20"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtHumidityMinActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel25">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" value="Max"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtHumidityMax">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="50"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtHumidityMaxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtHumiditySVF">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" value="50"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtHumiditySVFActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel11">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="4"/>
|
||||
<Property name="text" type="java.lang.String" value="SV %"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerHumidity">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Cantarell" size="24" style="1"/>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="30" maximum="100" minimum="0" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerHumidityStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkbxHumiditySmooth">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Smooth Variation"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkbxHumiditySmoothActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ea" green="e9" red="cf" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel7" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spinnerInterval" min="-2" pref="55" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel8" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jLabel12" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cmbInterface" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel9" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cmbProtocol" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cmbInterface" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spinnerInterval" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cmbProtocol" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Data Push Interval:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerInterval">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="5" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerIntervalStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel8">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Seconds"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel9">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Protocol:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cmbProtocol">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="3">
|
||||
<StringItem index="0" value="MQTT"/>
|
||||
<StringItem index="1" value="XMPP"/>
|
||||
<StringItem index="2" value="HTTP"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cmbProtocolActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel12">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Interface:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cmbInterface">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="1">
|
||||
<StringItem index="0" value="eth0"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cmbInterfaceActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel4">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ad" green="fd" red="a9" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkbxEmulate" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cmbPeriod" min="-2" pref="162" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="chkbxEmulate" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cmbPeriod" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="chkbxEmulate">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Emulate data"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkbxEmulateActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cmbPeriod">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="4">
|
||||
<StringItem index="0" value="1 hour"/>
|
||||
<StringItem index="1" value="1 day"/>
|
||||
<StringItem index="2" value="1 week"/>
|
||||
<StringItem index="3" value="1 month "/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cmbPeriodActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Emulation Period"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,711 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.agent.virtual.ui;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author charitha
|
||||
*/
|
||||
public class AgentUI extends javax.swing.JFrame {
|
||||
|
||||
/**
|
||||
* Creates new form AgentUI
|
||||
*/
|
||||
public AgentUI() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
lblAgentName = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
pnlBulbStatus = new javax.swing.JPanel();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
chkbxTemperatureRandom = new javax.swing.JCheckBox();
|
||||
jSeparator1 = new javax.swing.JSeparator();
|
||||
jPanel7 = new javax.swing.JPanel();
|
||||
jLabel5 = new javax.swing.JLabel();
|
||||
txtTemperatureMin = new javax.swing.JTextField();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
txtTemperatureMax = new javax.swing.JTextField();
|
||||
jLabel10 = new javax.swing.JLabel();
|
||||
txtTemperatureSVF = new javax.swing.JTextField();
|
||||
spinnerTemperature = new javax.swing.JSpinner();
|
||||
chkbxTemperatureSmooth = new javax.swing.JCheckBox();
|
||||
jPanel6 = new javax.swing.JPanel();
|
||||
jLabel20 = new javax.swing.JLabel();
|
||||
lblStatus = new javax.swing.JLabel();
|
||||
jPanel8 = new javax.swing.JPanel();
|
||||
jLabel23 = new javax.swing.JLabel();
|
||||
chkbxHumidityRandom = new javax.swing.JCheckBox();
|
||||
jSeparator5 = new javax.swing.JSeparator();
|
||||
jPanel9 = new javax.swing.JPanel();
|
||||
jLabel24 = new javax.swing.JLabel();
|
||||
txtHumidityMin = new javax.swing.JTextField();
|
||||
jLabel25 = new javax.swing.JLabel();
|
||||
txtHumidityMax = new javax.swing.JTextField();
|
||||
txtHumiditySVF = new javax.swing.JTextField();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
spinnerHumidity = new javax.swing.JSpinner();
|
||||
chkbxHumiditySmooth = new javax.swing.JCheckBox();
|
||||
jPanel3 = new javax.swing.JPanel();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
spinnerInterval = new javax.swing.JSpinner();
|
||||
jLabel8 = new javax.swing.JLabel();
|
||||
jLabel9 = new javax.swing.JLabel();
|
||||
cmbProtocol = new javax.swing.JComboBox();
|
||||
jLabel12 = new javax.swing.JLabel();
|
||||
cmbInterface = new javax.swing.JComboBox();
|
||||
jPanel4 = new javax.swing.JPanel();
|
||||
chkbxEmulate = new javax.swing.JCheckBox();
|
||||
cmbPeriod = new javax.swing.JComboBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
||||
setTitle("Fire Alarm Emulator");
|
||||
setResizable(false);
|
||||
|
||||
lblAgentName.setFont(new java.awt.Font("Cantarell", 1, 24)); // NOI18N
|
||||
lblAgentName.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
lblAgentName.setText("Device Name: WSO2 IoT Virtual Agent");
|
||||
|
||||
jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
jLabel2.setText("Copyright (c) 2015, WSO2 Inc.");
|
||||
|
||||
jPanel1.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
jLabel3.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
jLabel3.setText("Bulb Status");
|
||||
|
||||
pnlBulbStatus.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
javax.swing.GroupLayout pnlBulbStatusLayout = new javax.swing.GroupLayout(pnlBulbStatus);
|
||||
pnlBulbStatus.setLayout(pnlBulbStatusLayout);
|
||||
pnlBulbStatusLayout.setHorizontalGroup(
|
||||
pnlBulbStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
pnlBulbStatusLayout.setVerticalGroup(
|
||||
pnlBulbStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 167, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(pnlBulbStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel3)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlBulbStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel2.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
jLabel4.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
jLabel4.setText("Temperature");
|
||||
|
||||
chkbxTemperatureRandom.setText("Randomize Data");
|
||||
chkbxTemperatureRandom.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxTemperatureRandomActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
|
||||
|
||||
jPanel7.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
jLabel5.setText("Min");
|
||||
|
||||
txtTemperatureMin.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtTemperatureMin.setText("20");
|
||||
txtTemperatureMin.setEnabled(false);
|
||||
txtTemperatureMin.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureMinActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
|
||||
jLabel6.setText("Max");
|
||||
|
||||
txtTemperatureMax.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtTemperatureMax.setText("50");
|
||||
txtTemperatureMax.setEnabled(false);
|
||||
txtTemperatureMax.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureMaxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
|
||||
jLabel10.setText("SV %");
|
||||
|
||||
txtTemperatureSVF.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtTemperatureSVF.setText("50");
|
||||
txtTemperatureSVF.setEnabled(false);
|
||||
txtTemperatureSVF.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtTemperatureSVFActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
|
||||
jPanel7.setLayout(jPanel7Layout);
|
||||
jPanel7Layout.setHorizontalGroup(
|
||||
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel7Layout.createSequentialGroup()
|
||||
.addComponent(jLabel5)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureMin, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel6)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureMax, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel10)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtTemperatureSVF, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel7Layout.setVerticalGroup(
|
||||
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel7Layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(txtTemperatureMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtTemperatureMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel6)
|
||||
.addComponent(jLabel5)
|
||||
.addComponent(jLabel10)
|
||||
.addComponent(txtTemperatureSVF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(35, 35, 35))
|
||||
);
|
||||
|
||||
spinnerTemperature.setFont(new java.awt.Font("Cantarell", 1, 24)); // NOI18N
|
||||
spinnerTemperature.setModel(new javax.swing.SpinnerNumberModel(30, 0, 100, 1));
|
||||
spinnerTemperature.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerTemperatureStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkbxTemperatureSmooth.setText("Smooth Variation");
|
||||
chkbxTemperatureSmooth.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxTemperatureSmoothActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
|
||||
jPanel2.setLayout(jPanel2Layout);
|
||||
jPanel2Layout.setHorizontalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(spinnerTemperature))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(chkbxTemperatureRandom)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(chkbxTemperatureSmooth)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel2Layout.setVerticalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator1)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxTemperatureRandom)
|
||||
.addComponent(chkbxTemperatureSmooth))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerTemperature)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel6.setBackground(new java.awt.Color(253, 254, 209));
|
||||
|
||||
jLabel20.setText("Connection Status:");
|
||||
jLabel20.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
|
||||
|
||||
lblStatus.setFont(new java.awt.Font("Cantarell", 1, 15)); // NOI18N
|
||||
lblStatus.setText("Not Connected");
|
||||
|
||||
javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
|
||||
jPanel6.setLayout(jPanel6Layout);
|
||||
jPanel6Layout.setHorizontalGroup(
|
||||
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel6Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel20)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(273, 273, 273))
|
||||
);
|
||||
jPanel6Layout.setVerticalGroup(
|
||||
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jLabel20, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
|
||||
.addComponent(lblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel8.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
jLabel23.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N
|
||||
jLabel23.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
jLabel23.setText("Humidity");
|
||||
|
||||
chkbxHumidityRandom.setText("Randomize Data");
|
||||
chkbxHumidityRandom.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxHumidityRandomActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator5.setOrientation(javax.swing.SwingConstants.VERTICAL);
|
||||
|
||||
jPanel9.setBackground(new java.awt.Color(220, 220, 220));
|
||||
|
||||
jLabel24.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
jLabel24.setText("Min");
|
||||
|
||||
txtHumidityMin.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtHumidityMin.setText("20");
|
||||
txtHumidityMin.setEnabled(false);
|
||||
txtHumidityMin.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumidityMinActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel25.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
|
||||
jLabel25.setText("Max");
|
||||
|
||||
txtHumidityMax.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtHumidityMax.setText("50");
|
||||
txtHumidityMax.setEnabled(false);
|
||||
txtHumidityMax.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumidityMaxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
txtHumiditySVF.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
txtHumiditySVF.setText("50");
|
||||
txtHumiditySVF.setEnabled(false);
|
||||
txtHumiditySVF.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtHumiditySVFActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
|
||||
jLabel11.setText("SV %");
|
||||
|
||||
javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9);
|
||||
jPanel9.setLayout(jPanel9Layout);
|
||||
jPanel9Layout.setHorizontalGroup(
|
||||
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel9Layout.createSequentialGroup()
|
||||
.addComponent(jLabel24)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumidityMin, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel25)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumidityMax, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel11)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHumiditySVF, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel9Layout.setVerticalGroup(
|
||||
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel9Layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(txtHumiditySVF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(txtHumidityMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtHumidityMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel25)
|
||||
.addComponent(jLabel24)))
|
||||
.addGap(35, 35, 35))
|
||||
);
|
||||
|
||||
spinnerHumidity.setFont(new java.awt.Font("Cantarell", 1, 24)); // NOI18N
|
||||
spinnerHumidity.setModel(new javax.swing.SpinnerNumberModel(30, 0, 100, 1));
|
||||
spinnerHumidity.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerHumidityStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkbxHumiditySmooth.setText("Smooth Variation");
|
||||
chkbxHumiditySmooth.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxHumiditySmoothActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8);
|
||||
jPanel8.setLayout(jPanel8Layout);
|
||||
jPanel8Layout.setHorizontalGroup(
|
||||
jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(spinnerHumidity))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jPanel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addComponent(chkbxHumidityRandom)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(chkbxHumiditySmooth)))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel8Layout.setVerticalGroup(
|
||||
jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator5)
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxHumidityRandom)
|
||||
.addComponent(chkbxHumiditySmooth))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel9, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 1, Short.MAX_VALUE))
|
||||
.addGroup(jPanel8Layout.createSequentialGroup()
|
||||
.addComponent(jLabel23, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerHumidity)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel3.setBackground(new java.awt.Color(207, 233, 234));
|
||||
|
||||
jLabel7.setText("Data Push Interval:");
|
||||
|
||||
spinnerInterval.setModel(new javax.swing.SpinnerNumberModel(5, 1, null, 1));
|
||||
spinnerInterval.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerIntervalStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel8.setText("Seconds");
|
||||
|
||||
jLabel9.setText("Protocol:");
|
||||
|
||||
cmbProtocol.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "MQTT", "XMPP", "HTTP" }));
|
||||
cmbProtocol.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbProtocolActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel12.setText("Interface:");
|
||||
|
||||
cmbInterface.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "eth0" }));
|
||||
cmbInterface.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbInterfaceActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
|
||||
jPanel3.setLayout(jPanel3Layout);
|
||||
jPanel3Layout.setHorizontalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel3Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel7)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerInterval, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel8)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel12)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbInterface, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel9)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbProtocol, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel3Layout.setVerticalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel12)
|
||||
.addComponent(cmbInterface, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(spinnerInterval, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel8)
|
||||
.addComponent(jLabel9)
|
||||
.addComponent(cmbProtocol, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jPanel4.setBackground(new java.awt.Color(169, 253, 173));
|
||||
|
||||
chkbxEmulate.setText("Emulate data");
|
||||
chkbxEmulate.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chkbxEmulateActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cmbPeriod.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1 hour", "1 day", "1 week", "1 month " }));
|
||||
cmbPeriod.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cmbPeriodActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText("Emulation Period");
|
||||
|
||||
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
|
||||
jPanel4.setLayout(jPanel4Layout);
|
||||
jPanel4Layout.setHorizontalGroup(
|
||||
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(chkbxEmulate)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cmbPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel4Layout.setVerticalGroup(
|
||||
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(chkbxEmulate)
|
||||
.addComponent(cmbPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel1))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblAgentName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblAgentName, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void chkbxTemperatureRandomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkbxTemperatureRandomActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkbxTemperatureRandomActionPerformed
|
||||
|
||||
private void chkbxHumidityRandomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkbxHumidityRandomActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkbxHumidityRandomActionPerformed
|
||||
|
||||
private void spinnerTemperatureStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerTemperatureStateChanged
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_spinnerTemperatureStateChanged
|
||||
|
||||
private void spinnerHumidityStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerHumidityStateChanged
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_spinnerHumidityStateChanged
|
||||
|
||||
private void txtTemperatureMinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtTemperatureMinActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtTemperatureMinActionPerformed
|
||||
|
||||
private void txtTemperatureMaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtTemperatureMaxActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtTemperatureMaxActionPerformed
|
||||
|
||||
private void txtHumidityMinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtHumidityMinActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtHumidityMinActionPerformed
|
||||
|
||||
private void txtHumidityMaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtHumidityMaxActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtHumidityMaxActionPerformed
|
||||
|
||||
private void spinnerIntervalStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerIntervalStateChanged
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_spinnerIntervalStateChanged
|
||||
|
||||
private void cmbInterfaceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbInterfaceActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cmbInterfaceActionPerformed
|
||||
|
||||
private void cmbProtocolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbProtocolActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cmbProtocolActionPerformed
|
||||
|
||||
private void txtTemperatureSVFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtTemperatureSVFActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtTemperatureSVFActionPerformed
|
||||
|
||||
private void txtHumiditySVFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtHumiditySVFActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_txtHumiditySVFActionPerformed
|
||||
|
||||
private void chkbxTemperatureSmoothActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkbxTemperatureSmoothActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkbxTemperatureSmoothActionPerformed
|
||||
|
||||
private void chkbxHumiditySmoothActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkbxHumiditySmoothActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkbxHumiditySmoothActionPerformed
|
||||
|
||||
private void cmbPeriodActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbPeriodActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cmbPeriodActionPerformed
|
||||
|
||||
private void chkbxEmulateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkbxEmulateActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_chkbxEmulateActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox chkbxEmulate;
|
||||
private javax.swing.JCheckBox chkbxHumidityRandom;
|
||||
private javax.swing.JCheckBox chkbxHumiditySmooth;
|
||||
private javax.swing.JCheckBox chkbxTemperatureRandom;
|
||||
private javax.swing.JCheckBox chkbxTemperatureSmooth;
|
||||
private javax.swing.JComboBox cmbInterface;
|
||||
private javax.swing.JComboBox cmbPeriod;
|
||||
private javax.swing.JComboBox cmbProtocol;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel10;
|
||||
private javax.swing.JLabel jLabel11;
|
||||
private javax.swing.JLabel jLabel12;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel20;
|
||||
private javax.swing.JLabel jLabel23;
|
||||
private javax.swing.JLabel jLabel24;
|
||||
private javax.swing.JLabel jLabel25;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
private javax.swing.JLabel jLabel5;
|
||||
private javax.swing.JLabel jLabel6;
|
||||
private javax.swing.JLabel jLabel7;
|
||||
private javax.swing.JLabel jLabel8;
|
||||
private javax.swing.JLabel jLabel9;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JPanel jPanel3;
|
||||
private javax.swing.JPanel jPanel4;
|
||||
private javax.swing.JPanel jPanel6;
|
||||
private javax.swing.JPanel jPanel7;
|
||||
private javax.swing.JPanel jPanel8;
|
||||
private javax.swing.JPanel jPanel9;
|
||||
private javax.swing.JSeparator jSeparator1;
|
||||
private javax.swing.JSeparator jSeparator5;
|
||||
private javax.swing.JLabel lblAgentName;
|
||||
private javax.swing.JLabel lblStatus;
|
||||
private javax.swing.JPanel pnlBulbStatus;
|
||||
private javax.swing.JSpinner spinnerHumidity;
|
||||
private javax.swing.JSpinner spinnerInterval;
|
||||
private javax.swing.JSpinner spinnerTemperature;
|
||||
private javax.swing.JTextField txtHumidityMax;
|
||||
private javax.swing.JTextField txtHumidityMin;
|
||||
private javax.swing.JTextField txtHumiditySVF;
|
||||
private javax.swing.JTextField txtTemperatureMax;
|
||||
private javax.swing.JTextField txtTemperatureMin;
|
||||
private javax.swing.JTextField txtTemperatureSVF;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -0,0 +1,350 @@
|
||||
<?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>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>WSO2 Carbon - IoT Server VirtualFireAlarm API</name>
|
||||
<description>WSO2 Carbon - Virtual FireAlarm Service Management API Implementation</description>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<properties>
|
||||
<cxf-bundle-package.version>2.7.18</cxf-bundle-package.version>
|
||||
</properties>
|
||||
|
||||
<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>
|
||||
|
||||
<!--MQTT -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--IOT -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpasyncclient</artifactId>
|
||||
<version>4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--JAX-RS -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax</groupId>
|
||||
<artifactId>javaee-web-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient.wso2</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle.wso2</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.user.api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.queuing</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.base</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.axis2.wso2</groupId>
|
||||
<artifactId>axis2</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smack</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smackx</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-fileupload.wso2</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant.wso2</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant.wso2</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-httpclient.wso2</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.equinox</groupId>
|
||||
<artifactId>javax.servlet</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.registry.api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smack</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smackx</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.wso2.carbon.analytics</groupId>-->
|
||||
<!-- <artifactId>org.wso2.carbon.analytics.api</artifactId>-->
|
||||
<!-- <scope>provided</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-bundle</artifactId>
|
||||
<version>3.0.0-milestone2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-bundle-jaxrs</artifactId>
|
||||
<scope>provided</scope>
|
||||
<version>${cxf-bundle-package.version}</version>
|
||||
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-jaxrs</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json.wso2</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>${wso2.maven.compiler.source}</source>
|
||||
<target>${wso2.maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<warName>virtual_firealarm</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jacoco-initialize</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jacoco-site</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
|
||||
<outputDirectory>${basedir}/target/coverage-reports/site</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scope;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* This class consists the functions/APIs specific to the "actions" of the VirtualFirealarm device-type. These APIs
|
||||
* include the ones that are used by the [Device] to contact the server (i.e: Enrollment & Publishing Data) and the
|
||||
* ones used by the [Server/Owner] to contact the [Device] (i.e: sending control signals). This class also initializes
|
||||
* the transport 'Connectors' [XMPP & MQTT] specific to the VirtualFirealarm device-type in order to communicate with
|
||||
* such devices and to receive messages form it.
|
||||
*/
|
||||
@SwaggerDefinition(
|
||||
info = @Info(
|
||||
version = "1.0.0",
|
||||
title = "",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = "name", value = "virtual_firealarm"),
|
||||
@ExtensionProperty(name = "context", value = "/virtual_firealarm"),
|
||||
})
|
||||
}
|
||||
),
|
||||
tags = {
|
||||
@Tag(name = "virtual_firealarm,device_management", description = "")
|
||||
}
|
||||
)
|
||||
@Scopes(
|
||||
scopes = {
|
||||
@Scope(
|
||||
name = "Enroll device",
|
||||
description = "",
|
||||
key = "perm:firealarm:enroll",
|
||||
permissions = {"/device-mgt/devices/enroll/firealarm"},
|
||||
roles = {"Internal/devicemgt-user"}
|
||||
)
|
||||
}
|
||||
)
|
||||
public interface VirtualFireAlarmService {
|
||||
|
||||
String SCOPE = "scope";
|
||||
|
||||
/**
|
||||
* This is an API called/used from within the Server(Front-End) or by a device Owner. It sends a control command to
|
||||
* the VirtualFirealarm device to switch `ON` or `OFF` its buzzer. The method also takes in the protocol to be used
|
||||
* to connect-to and send the command to the device.
|
||||
*
|
||||
* @param deviceId the ID of the VirtualFirealarm device on which the buzzer needs to switched `ON` or `OFF`.
|
||||
* @param state the state to which the buzzer on the device needs to be changed. Either "ON" or "OFF".
|
||||
* (Case-Insensitive String)
|
||||
*/
|
||||
@POST
|
||||
@Path("device/{deviceId}/buzz")
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "Switch Buzzer",
|
||||
notes = "",
|
||||
response = Response.class,
|
||||
tags = "virtual_firealarm",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response switchBuzzer(@PathParam("deviceId") String deviceId,
|
||||
@FormParam("state") String state);
|
||||
|
||||
/**
|
||||
* Retrieve Sensor data for the device type
|
||||
*/
|
||||
@Path("device/stats/{deviceId}")
|
||||
@GET
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Retrieve Sensor data for the device type",
|
||||
notes = "",
|
||||
response = Response.class,
|
||||
tags = "virtual_firealarm",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
|
||||
})
|
||||
}
|
||||
)
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
|
||||
@QueryParam("to") long to);
|
||||
|
||||
@Path("device/download")
|
||||
@GET
|
||||
@Produces("application/zip")
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Download agent",
|
||||
notes = "",
|
||||
response = Response.class,
|
||||
tags = "virtual_firealarm",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:firealarm:enroll")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
|
||||
|
||||
}
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
|
||||
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
|
||||
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
||||
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
||||
import org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dao.DeviceEventsDAO;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dao.DeviceEventsDAOImpl;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.VirtualFirealarmXMPPException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppAccount;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppServerClient;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
|
||||
|
||||
private static final String KEY_TYPE = "PRODUCTION";
|
||||
private static ApiApplicationKey apiApplicationKey;
|
||||
private static Log log = LogFactory.getLog(VirtualFireAlarmServiceImpl.class);
|
||||
|
||||
@POST
|
||||
@Path("device/{deviceId}/buzz")
|
||||
public Response switchBuzzer(@PathParam("deviceId") String deviceId, @FormParam("state") String state) {
|
||||
if (state == null || state.isEmpty()) {
|
||||
log.error("State is not defined for the buzzer operation");
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
String switchToState = state.toUpperCase();
|
||||
if (!switchToState.equals(VirtualFireAlarmConstants.STATE_ON) && !switchToState.equals(
|
||||
VirtualFireAlarmConstants.STATE_OFF)) {
|
||||
log.error("The requested state change shoud be either - 'ON' or 'OFF'");
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
try {
|
||||
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
|
||||
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
|
||||
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
String resource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
|
||||
String actualMessage = resource + ":" + switchToState;
|
||||
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
|
||||
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
|
||||
|
||||
ConfigOperation commandOp = new ConfigOperation();
|
||||
commandOp.setCode("buzz");
|
||||
commandOp.setEnabled(true);
|
||||
commandOp.setPayLoad(actualMessage);
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty(VirtualFireAlarmConstants.CLIENT_JID_PROPERTY_KEY, deviceId + "@" + XmppConfig
|
||||
.getInstance().getServerName());
|
||||
props.setProperty(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "CONTROL-REQUEST");
|
||||
props.setProperty(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
|
||||
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
|
||||
commandOp.setProperties(props);
|
||||
|
||||
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
|
||||
deviceIdentifiers.add(new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE));
|
||||
APIUtil.getDeviceManagementService().addOperation(VirtualFireAlarmConstants.DEVICE_TYPE, commandOp,
|
||||
deviceIdentifiers);
|
||||
return Response.ok().build();
|
||||
} catch (InvalidDeviceException e) {
|
||||
String msg = "Error occurred while executing command operation to send keywords";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
} catch (DeviceAccessAuthorizationException e) {
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
} catch (OperationManagementException e) {
|
||||
String msg = "Error occurred while executing command operation upon ringing the buzzer";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
@Path("device/stats/{deviceId}")
|
||||
@GET
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response getVirtualFirealarmStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
|
||||
@QueryParam("to") long to) {
|
||||
try {
|
||||
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
|
||||
new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE),
|
||||
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
DeviceEventsDAO eventsDAO = new DeviceEventsDAOImpl();
|
||||
SensorRecord sensorRecord = eventsDAO.getStats(deviceId, from, to);
|
||||
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecord).build();
|
||||
|
||||
} catch (DeviceAccessAuthorizationException e) {
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
@Path("device/download")
|
||||
@GET
|
||||
@Produces("application/zip")
|
||||
public Response downloadSketch(@QueryParam("deviceName") String deviceName,
|
||||
@QueryParam("sketchType") String sketchType) {
|
||||
try {
|
||||
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();
|
||||
return resp;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return Response.status(400).entity(ex.getMessage()).build();//bad request
|
||||
} catch (DeviceManagementException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
} catch (JWTClientException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
} catch (APIManagerException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
} catch (UserStoreException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
} catch (VirtualFirealarmXMPPException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean register(String deviceId, String name) {
|
||||
try {
|
||||
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||
deviceIdentifier.setId(deviceId);
|
||||
deviceIdentifier.setType(VirtualFireAlarmConstants.DEVICE_TYPE);
|
||||
if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) {
|
||||
return false;
|
||||
}
|
||||
Device device = new Device();
|
||||
device.setDeviceIdentifier(deviceId);
|
||||
EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
|
||||
enrolmentInfo.setDateOfEnrolment(new Date().getTime());
|
||||
enrolmentInfo.setDateOfLastUpdate(new Date().getTime());
|
||||
enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
|
||||
enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
|
||||
device.setName(name);
|
||||
device.setType(VirtualFireAlarmConstants.DEVICE_TYPE);
|
||||
enrolmentInfo.setOwner(APIUtil.getAuthenticatedUser());
|
||||
device.setEnrolmentInfo(enrolmentInfo);
|
||||
return APIUtil.getDeviceManagementService().enrollDevice(device);
|
||||
} catch (DeviceManagementException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
|
||||
throws DeviceManagementException, APIManagerException, JWTClientException,
|
||||
UserStoreException, VirtualFirealarmXMPPException {
|
||||
//create new device id
|
||||
String deviceId = shortUUID();
|
||||
boolean status = register(deviceId, deviceName);
|
||||
if (!status) {
|
||||
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
|
||||
throw new DeviceManagementException(msg);
|
||||
}
|
||||
if (apiApplicationKey == null) {
|
||||
String adminUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
|
||||
.getRealmConfiguration().getAdminUserName();
|
||||
String tenantAdminDomainName = PrivilegedCarbonContext.getThreadLocalCarbonContext()
|
||||
.getTenantDomain();
|
||||
String applicationUsername =
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
|
||||
.getAdminUserName() + "@" + PrivilegedCarbonContext.getThreadLocalCarbonContext()
|
||||
.getTenantDomain();
|
||||
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
|
||||
String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
|
||||
try {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantAdminDomainName);
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(adminUsername);
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
|
||||
|
||||
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
|
||||
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true,
|
||||
VirtualFireAlarmConstants.APIM_APPLICATION_TOKEN_VALIDITY_PERIOD);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
|
||||
|
||||
String deviceType = sketchType.replace(" ", "");
|
||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||
StringBuilder scopes = new StringBuilder("device:" + deviceType + ":" + deviceId);
|
||||
|
||||
// add scopes for event publishing
|
||||
scopes.append(" perm:topic:pub:" + tenantDomain + ":" + deviceType + ":" + deviceId + ":temperature");
|
||||
|
||||
// add scopes for retrieve operation topic /tenantDomain/deviceType/deviceId/operation/#
|
||||
scopes.append(" perm:topic:sub:" + tenantDomain + ":" + deviceType + ":" + deviceId + ":operation");
|
||||
|
||||
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
|
||||
apiApplicationKey.getConsumerSecret(), owner,
|
||||
scopes.toString());
|
||||
|
||||
String accessToken = accessTokenInfo.getAccessToken();
|
||||
String refreshToken = accessTokenInfo.getRefreshToken();
|
||||
XmppAccount newXmppAccount = new XmppAccount();
|
||||
newXmppAccount.setAccountName(deviceId);
|
||||
newXmppAccount.setUsername(deviceId);
|
||||
newXmppAccount.setPassword(accessToken);
|
||||
newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser());
|
||||
|
||||
status = XmppServerClient.createAccount(newXmppAccount);
|
||||
if (!status) {
|
||||
String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
|
||||
".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" +
|
||||
".common.config.server.configs";
|
||||
throw new DeviceManagementException(msg);
|
||||
}
|
||||
ZipUtil ziputil = new ZipUtil();
|
||||
return ziputil.createZipFile(owner, sketchType, deviceId, deviceName, apiApplicationKey.toString(),
|
||||
accessToken, refreshToken);
|
||||
}
|
||||
|
||||
private static String shortUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
|
||||
return Long.toString(l, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.constants;
|
||||
|
||||
public class VirtualFireAlarmConstants {
|
||||
public final static String DEVICE_TYPE = "virtual_firealarm";
|
||||
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
|
||||
public final static String DEVICE_PLUGIN_DEVICE_ID = "VIRTUAL_FIREALARM_DEVICE_ID";
|
||||
public final static String STATE_ON = "ON";
|
||||
public final static String STATE_OFF = "OFF";
|
||||
|
||||
public static final String URL_PREFIX = "http://";
|
||||
public static final String BULB_CONTEXT = "BULB";
|
||||
public static final String POLICY_CONTEXT = "POLICY";
|
||||
|
||||
//sensor events sumerized table name for temperature
|
||||
// public static final String TEMPERATURE_EVENT_TABLE = "IOT_PER_DEVICE_STREAM_VIRTUALFIREALARM_TEMPERATURE";
|
||||
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
|
||||
|
||||
//mqtt tranport related constants
|
||||
public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt";
|
||||
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
|
||||
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
|
||||
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
|
||||
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
|
||||
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
|
||||
public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
|
||||
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
|
||||
public static final int DEFAULT_MQTT_PORT = 1886;
|
||||
|
||||
//xmpp transport related constants
|
||||
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
|
||||
public static final String XMPP_ADAPTER_TYPE = "xmpp";
|
||||
public static final String PASSWORD_PROPERTY_KEY = "password";
|
||||
public static final String JID_PROPERTY_KEY = "jid";
|
||||
public static final String CLIENT_JID_PROPERTY_KEY = "xmpp.client.jid";
|
||||
public static final String SUBJECT_PROPERTY_KEY = "xmpp.client.subject";
|
||||
public static final String MESSAGE_TYPE_PROPERTY_KEY = "xmpp.client.messageType";
|
||||
public static final String CHAT_PROPERTY_KEY = "chat";
|
||||
|
||||
public static final String USERNAME_PROPERTY_KEY = "username";
|
||||
public static final String DCR_PROPERTY_KEY = "dcrUrl";
|
||||
public static final String BROKER_URL_PROPERTY_KEY = "url";
|
||||
public static final String SCOPES_PROPERTY_KEY = "scopes";
|
||||
public static final String QOS_PROPERTY_KEY = "qos";
|
||||
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
|
||||
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
|
||||
public static final String TOPIC = "topic";
|
||||
public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher";
|
||||
|
||||
public static final String CONTENT_VALIDATION = "contentValidator";
|
||||
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
|
||||
public static final String RESOURCE = "resource";
|
||||
|
||||
public static final String JSON_SERIAL_KEY = "SerialNumber";
|
||||
public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
|
||||
public static final String JSON_MESSAGE_KEY = "Msg";
|
||||
public static final String JSON_SIGNATURE_KEY = "Sig";
|
||||
|
||||
public static final String HOST_KEY = "host";
|
||||
public static final String PORT_KEY = "port";
|
||||
|
||||
public static final String SERVER_NAME = "serverName";
|
||||
|
||||
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
|
||||
|
||||
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
|
||||
|
||||
public static final String PERM_ENROLL_FIRE_ALARM = "/permission/admin/device-mgt/devices/enroll/firealarm";
|
||||
public static final String PERM_OWNING_DEVICE_VIEW = "/permission/admin/device-mgt/devices/owning-device/view";
|
||||
|
||||
public static final String ROLE_NAME = "internal/devicemgt-user";
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
|
||||
*
|
||||
* Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* Licensed under the Entgra Commercial License, Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://entgra.io/licenses/entgra-commercial/1.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.dao;
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
|
||||
|
||||
public interface DeviceEventsDAO {
|
||||
|
||||
SensorRecord getStats(String deviceId, long fromTime, long toTime);
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
|
||||
*
|
||||
* Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* Licensed under the Entgra Commercial License, Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://entgra.io/licenses/entgra-commercial/1.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.dao;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.*;
|
||||
import org.wso2.carbon.device.mgt.core.dao.util.*;
|
||||
|
||||
public class DeviceEventsDAOFactory {
|
||||
|
||||
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(DeviceEventsDAOFactory.class);
|
||||
private static javax.sql.DataSource dataSource;
|
||||
private static String databaseEngine;
|
||||
private static final ThreadLocal<java.sql.Connection> currentConnection = new ThreadLocal<>();
|
||||
|
||||
public static void init(String jndiName) {
|
||||
dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiName, null);
|
||||
try {
|
||||
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
|
||||
} catch (java.sql.SQLException e) {
|
||||
log.error("Error occurred while retrieving config.datasource connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static DeviceEventsDAO getDeviceEventDao() {
|
||||
return new DeviceEventsDAOImpl();
|
||||
}
|
||||
|
||||
public static void openDBConnection() throws DBConnectionException {
|
||||
java.sql.Connection conn = currentConnection.get();
|
||||
if (conn != null) {
|
||||
throw new IllegalTransactionStateException("Database connection has already been obtained.");
|
||||
}
|
||||
try {
|
||||
conn = dataSource.getConnection();
|
||||
} catch (java.sql.SQLException e) {
|
||||
throw new DBConnectionException("Failed to get a database connection.", e);
|
||||
}
|
||||
currentConnection.set(conn);
|
||||
}
|
||||
|
||||
public static void beginTransaction() throws DBConnectionException {
|
||||
try {
|
||||
java.sql.Connection conn = dataSource.getConnection();
|
||||
conn.setAutoCommit(false);
|
||||
currentConnection.set(conn);
|
||||
} catch (java.sql.SQLException e) {
|
||||
throw new DBConnectionException("Error occurred while retrieving datasource connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static java.sql.Connection getConnection() throws DBConnectionException {
|
||||
if (currentConnection.get() == null) {
|
||||
try {
|
||||
currentConnection.set(dataSource.getConnection());
|
||||
} catch (java.sql.SQLException e) {
|
||||
throw new DBConnectionException("Error occurred while retrieving data source connection", e);
|
||||
}
|
||||
}
|
||||
return currentConnection.get();
|
||||
}
|
||||
|
||||
public static void commitTransaction() throws DBConnectionException {
|
||||
try {
|
||||
java.sql.Connection conn = currentConnection.get();
|
||||
if (conn != null) {
|
||||
conn.commit();
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Datasource connection associated with the current thread is null, hence commit " +
|
||||
"has not been attempted");
|
||||
}
|
||||
}
|
||||
} catch (java.sql.SQLException e) {
|
||||
throw new DBConnectionException("Error occurred while committing the transaction", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeConnection() {
|
||||
java.sql.Connection conn = currentConnection.get();
|
||||
try {
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
}
|
||||
} catch (java.sql.SQLException e) {
|
||||
log.error("Error occurred while close the connection");
|
||||
}
|
||||
currentConnection.remove();
|
||||
}
|
||||
|
||||
public static void rollbackTransaction() {
|
||||
java.sql.Connection conn = currentConnection.get();
|
||||
if (conn == null) {
|
||||
throw new org.wso2.carbon.device.mgt.common.exceptions.IllegalTransactionStateException("Database connection is not active. Hence, rollback is "
|
||||
+ "not attempted.");
|
||||
}
|
||||
try {
|
||||
conn.rollback();
|
||||
} catch (java.sql.SQLException e) {
|
||||
log.warn("Error occurred while roll-backing the transaction", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
|
||||
*
|
||||
* Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* Licensed under the Entgra Commercial License, Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://entgra.io/licenses/entgra-commercial/1.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.dao;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.*;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
/**
|
||||
* Implements MobileDeviceDAO for Android Devices.
|
||||
*/
|
||||
public class DeviceEventsDAOImpl implements DeviceEventsDAO {
|
||||
|
||||
private static final Log log = LogFactory.getLog(DeviceEventsDAOImpl.class);
|
||||
|
||||
@Override
|
||||
public SensorRecord getStats(String deviceId, long fromTime, long toTime) {
|
||||
String sql = "SELECT * FROM TABLE_VIRTUALFIREALARM_CARBONSUPER_RDBMS_PUBLISHER WHERE " +
|
||||
"META_DEVICEID = ? AND " +
|
||||
"META_TIME >= ? AND " +
|
||||
"META_TIME <= ? " +
|
||||
"ORDER BY META_TIME ASC";
|
||||
Map<Long, Float> stats = new LinkedHashMap<>();
|
||||
try {
|
||||
DeviceEventsDAOFactory.init("jdbc/EVENT_DB");
|
||||
Connection conn = DeviceEventsDAOFactory.getConnection();
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setString(1, deviceId);
|
||||
stmt.setLong(2, fromTime);
|
||||
stmt.setLong(3, toTime);
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
stats.put(rs.getLong("META_TIME"), rs.getFloat("TEMPERATURE"));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while retrieving device details";
|
||||
log.error(msg);
|
||||
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining DB connection to retrieve device details";
|
||||
log.error(msg);
|
||||
|
||||
}
|
||||
// stats.entrySet()
|
||||
// .stream()
|
||||
// .sorted(Map.Entry.<Long, Float>comparingByKey())
|
||||
// .forEach(System.out::println);
|
||||
return new SensorRecord(stats);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@XmlRootElement
|
||||
/**
|
||||
* This stores sensor event data for virtual fire alarm sense.
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class SensorRecord {
|
||||
|
||||
@XmlElementWrapper(required = true, name = "stats")
|
||||
private Map<Long, Float> stats;
|
||||
|
||||
public Map<Long, Float> getStats() {
|
||||
return stats;
|
||||
}
|
||||
|
||||
public void setStats(Map<Long, Float> stats) {
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
public SensorRecord(Map<Long, Float> stats) {
|
||||
this.stats = stats;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception;
|
||||
|
||||
public class VirtualFireAlarmException extends Exception {
|
||||
private static final long serialVersionUID = 118512086957330189L;
|
||||
|
||||
public VirtualFireAlarmException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
|
||||
public VirtualFireAlarmException(String errorMessage, Throwable throwable) {
|
||||
super(errorMessage, throwable);
|
||||
}
|
||||
|
||||
public VirtualFireAlarmException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.listener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.CarbonConstants;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.user.api.AuthorizationManager;
|
||||
import org.wso2.carbon.user.api.Permission;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.user.api.UserStoreManager;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
public class VirtualFireAlarmPermissionUpdateListener implements ServletContextListener {
|
||||
|
||||
private static Log log = LogFactory.getLog(VirtualFireAlarmPermissionUpdateListener.class);
|
||||
private static PrivilegedCarbonContext threadLocalCarbonContext;
|
||||
private static RealmService realmService;
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||
threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
realmService = (RealmService) threadLocalCarbonContext.getOSGiService(RealmService.class, null);
|
||||
UserStoreManager userStoreManager = getUserStoreManager();
|
||||
try {
|
||||
if (userStoreManager != null) {
|
||||
if (!userStoreManager.isExistingRole(VirtualFireAlarmConstants.ROLE_NAME)) {
|
||||
userStoreManager.addRole(VirtualFireAlarmConstants.ROLE_NAME, null, getPermissions());
|
||||
} else {
|
||||
getAuthorizationManager().authorizeRole(VirtualFireAlarmConstants.ROLE_NAME,
|
||||
VirtualFireAlarmConstants.PERM_ENROLL_FIRE_ALARM, CarbonConstants.UI_PERMISSION_ACTION);
|
||||
getAuthorizationManager().authorizeRole(VirtualFireAlarmConstants.ROLE_NAME,
|
||||
VirtualFireAlarmConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants.UI_PERMISSION_ACTION);
|
||||
}
|
||||
}
|
||||
} catch (UserStoreException e) {
|
||||
log.error("Error while creating a role and adding a user for Raspberry PI.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||
|
||||
}
|
||||
|
||||
private UserStoreManager getUserStoreManager() {
|
||||
UserStoreManager userStoreManager;
|
||||
try {
|
||||
if (realmService == null) {
|
||||
String msg = "Realm service has not initialized.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
int tenantId = threadLocalCarbonContext.getTenantId();
|
||||
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
|
||||
realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
|
||||
} catch (UserStoreException e) {
|
||||
String msg = "Error occurred while retrieving current user store manager";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return userStoreManager;
|
||||
}
|
||||
|
||||
private AuthorizationManager getAuthorizationManager() {
|
||||
AuthorizationManager authorizationManager;
|
||||
try {
|
||||
if (realmService == null) {
|
||||
String msg = "Realm service has not initialized.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
int tenantId = threadLocalCarbonContext.getTenantId();
|
||||
authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
|
||||
} catch (UserStoreException e) {
|
||||
String msg = "Error occurred while retrieving current user store manager";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return authorizationManager;
|
||||
}
|
||||
|
||||
private Permission[] getPermissions() {
|
||||
Permission androidSense = new Permission(VirtualFireAlarmConstants.PERM_ENROLL_FIRE_ALARM,
|
||||
CarbonConstants.UI_PERMISSION_ACTION);
|
||||
Permission view = new Permission(VirtualFireAlarmConstants.PERM_OWNING_DEVICE_VIEW,
|
||||
CarbonConstants.UI_PERMISSION_ACTION);
|
||||
return new Permission[]{androidSense, view};
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
|
||||
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
|
||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
|
||||
|
||||
/**
|
||||
* This class provides utility functions used by REST-API.
|
||||
*/
|
||||
public class APIUtil {
|
||||
|
||||
private static Log log = LogFactory.getLog(APIUtil.class);
|
||||
|
||||
public static String getAuthenticatedUser() {
|
||||
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
String username = threadLocalCarbonContext.getUsername();
|
||||
String tenantDomain = threadLocalCarbonContext.getTenantDomain();
|
||||
if (username.endsWith(tenantDomain)) {
|
||||
return username.substring(0, username.lastIndexOf("@"));
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
public static DeviceManagementProviderService getDeviceManagementService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
DeviceManagementProviderService deviceManagementProviderService =
|
||||
(DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null);
|
||||
if (deviceManagementProviderService == null) {
|
||||
String msg = "Device Management service has not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return deviceManagementProviderService;
|
||||
}
|
||||
|
||||
public static APIManagementProviderService getAPIManagementProviderService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
APIManagementProviderService apiManagementProviderService =
|
||||
(APIManagementProviderService) ctx.getOSGiService(APIManagementProviderService.class, null);
|
||||
if (apiManagementProviderService == null) {
|
||||
String msg = "API management provider service has not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return apiManagementProviderService;
|
||||
}
|
||||
|
||||
public static JWTClientManagerService getJWTClientManagerService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
JWTClientManagerService jwtClientManagerService =
|
||||
(JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
|
||||
if (jwtClientManagerService == null) {
|
||||
String msg = "JWT Client manager service has not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return jwtClientManagerService;
|
||||
}
|
||||
|
||||
public static String getTenantDomainOftheUser() {
|
||||
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
return threadLocalCarbonContext.getTenantDomain();
|
||||
}
|
||||
|
||||
public static DeviceAccessAuthorizationService getDeviceAccessAuthorizationService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
|
||||
(DeviceAccessAuthorizationService) ctx.getOSGiService(DeviceAccessAuthorizationService.class, null);
|
||||
if (deviceAccessAuthorizationService == null) {
|
||||
String msg = "Device Authorization service has not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return deviceAccessAuthorizationService;
|
||||
}
|
||||
|
||||
public static PlatformConfigurationManagementService getTenantConfigurationManagementService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
PlatformConfigurationManagementService tenantConfigurationManagementService =
|
||||
(PlatformConfigurationManagementService) ctx.getOSGiService(PlatformConfigurationManagementService.class, null);
|
||||
if (tenantConfigurationManagementService == null) {
|
||||
String msg = "Tenant configuration Management service not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return tenantConfigurationManagementService;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
|
||||
|
||||
public class VirtualFireAlarmUtilConstants {
|
||||
|
||||
public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
|
||||
public static final String DEVICE_OWNER = "DEVICE_OWNER";
|
||||
public static final String DEVICE_ID = "DEVICE_ID";
|
||||
public static final String DEVICE_NAME = "DEVICE_NAME";
|
||||
public static final String HTTPS_EP = "HTTPS_EP";
|
||||
public static final String HTTP_EP = "HTTP_EP";
|
||||
public static final String APIM_EP = "APIM_EP";
|
||||
public static final String MQTT_EP = "MQTT_EP";
|
||||
public static final String XMPP_EP = "XMPP_EP";
|
||||
public static final String VIRTUAL_FIREALARM_HTTPS_EP = "VIRTUAL_FIREALARM_HTTPS_EP";
|
||||
public static final String VIRTUAL_FIREALARM_HTTP_EP = "VIRTUAL_FIREALARM_HTTP_EP";
|
||||
public static final String VIRTUAL_FIREALARM_APIM_EP = "VIRTUAL_FIREALARM_APIM_EP";
|
||||
public static final String VIRTUAL_FIREALARM_MQTT_EP = "VIRTUAL_FIREALARM_MQTT_EP";
|
||||
public static final String VIRTUAL_FIREALARM_XMPP_EP = "VIRTUAL_FIREALARM_XMPP_EP";
|
||||
public static final String API_APPLICATION_KEY = "API_APPLICATION_KEY";
|
||||
public static final String DEVICE_TOKEN = "DEVICE_TOKEN";
|
||||
public static final String DEVICE_REFRESH_TOKEN = "DEVICE_REFRESH_TOKEN";
|
||||
public static final String SERVER_NAME = "SERVER_NAME";
|
||||
public static final String SERVER_JID = "SERVER_JID";
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* This is an utility class to hold zip files.
|
||||
*/
|
||||
public class ZipArchive {
|
||||
|
||||
private byte[] zipFileContent = null;
|
||||
private String fileName = null;
|
||||
|
||||
public ZipArchive(String fileName, byte[] zipFile) {
|
||||
this.fileName = fileName;
|
||||
this.zipFileContent = zipFile;
|
||||
}
|
||||
|
||||
public byte[] getZipFileContent() {
|
||||
return zipFileContent;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
}
|
@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.JSONObject;
|
||||
import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
|
||||
import org.wso2.carbon.core.util.Utils;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
|
||||
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.SocketException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* This is used to create a zip file that includes the necessary configuration required for the agent.
|
||||
*/
|
||||
public class ZipUtil {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ZipUtil.class);
|
||||
|
||||
private static final String 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 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 templateSketchPath = sketchFolder + File.separator + deviceType;
|
||||
String iotServerIP;
|
||||
|
||||
try {
|
||||
iotServerIP = "127.0.0.1"; //getServerUrl();
|
||||
String httpsServerEP = Utils.replaceSystemProperty(HTTPS_PROTOCOL_URL);
|
||||
String httpServerEP = Utils.replaceSystemProperty(HTTP_PROTOCOL_URL);
|
||||
String mqttEndpoint = Utils.replaceSystemProperty(DEFAULT_MQTT_ENDPOINT);
|
||||
if (mqttEndpoint.contains(LOCALHOST)) {
|
||||
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
|
||||
httpsServerEP = httpsServerEP.replace(LOCALHOST, iotServerIP);
|
||||
httpServerEP = httpServerEP.replace(LOCALHOST, iotServerIP);
|
||||
}
|
||||
|
||||
String xmppEndpoint = "";
|
||||
if (XmppConfig.getInstance().isEnabled()) {
|
||||
xmppEndpoint = XmppConfig.getInstance().getHost() + ":" + XmppConfig.getInstance().getPort();
|
||||
if (xmppEndpoint.contains(LOCALHOST)) {
|
||||
xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP);
|
||||
}
|
||||
}
|
||||
PlatformConfiguration configuration = APIUtil.getTenantConfigurationManagementService().getConfiguration(
|
||||
CONFIG_TYPE);
|
||||
if (configuration != null && configuration.getConfiguration() != null && configuration
|
||||
.getConfiguration().size() > 0) {
|
||||
List<ConfigurationEntry> configurations = configuration.getConfiguration();
|
||||
for (ConfigurationEntry configurationEntry : configurations) {
|
||||
switch (configurationEntry.getName()) {
|
||||
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_HTTPS_EP:
|
||||
httpsServerEP = (String)configurationEntry.getValue();
|
||||
break;
|
||||
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_HTTP_EP:
|
||||
httpServerEP = (String)configurationEntry.getValue();
|
||||
break;
|
||||
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_MQTT_EP:
|
||||
mqttEndpoint = (String)configurationEntry.getValue();
|
||||
break;
|
||||
case VirtualFireAlarmUtilConstants.VIRTUAL_FIREALARM_XMPP_EP:
|
||||
xmppEndpoint = (String)configurationEntry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey).trim();
|
||||
|
||||
Map<String, String> contextParams = new HashMap<>();
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.TENANT_DOMAIN, APIUtil.getTenantDomainOftheUser());
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_OWNER, owner);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_ID, deviceId);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_NAME, deviceName);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.HTTPS_EP, httpsServerEP);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.HTTP_EP, httpServerEP);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.APIM_EP, httpServerEP);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.MQTT_EP, mqttEndpoint);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.XMPP_EP, "XMPP:" + xmppEndpoint);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.API_APPLICATION_KEY, base64EncodedApplicationKey);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_TOKEN, token);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_REFRESH_TOKEN, refreshToken);
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.SERVER_NAME, XmppConfig.getInstance().getServerName() == null
|
||||
? "" : XmppConfig.getInstance().getServerName());
|
||||
contextParams.put(VirtualFireAlarmUtilConstants.SERVER_JID, XmppConfig.getInstance().getJid() == null
|
||||
? "" : XmppConfig.getInstance().getJid());
|
||||
|
||||
ZipArchive zipFile;
|
||||
zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName);
|
||||
return zipFile;
|
||||
} catch (IOException e) {
|
||||
throw new DeviceManagementException("Zip File Creation Failed", e);
|
||||
} catch (ConfigurationManagementException e) {
|
||||
throw new DeviceManagementException("Failed to retrieve configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getBase64EncodedAPIAppKey(String apiAppCredentialsAsJSONString) {
|
||||
|
||||
JSONObject jsonObject = new JSONObject(apiAppCredentialsAsJSONString);
|
||||
String consumerKey = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_ID).toString();
|
||||
String consumerSecret = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_SECRET).toString();
|
||||
String stringToEncode = consumerKey + ":" + consumerSecret;
|
||||
return Base64.encodeBase64String(stringToEncode.getBytes());
|
||||
}
|
||||
|
||||
private static String getServerUrl() {
|
||||
try {
|
||||
return org.apache.axis2.util.Utils.getIpAddress();
|
||||
} catch (SocketException e) {
|
||||
log.warn("Failed retrieving the hostname, therefore set to localhost", e);
|
||||
return "localhost";
|
||||
}
|
||||
}
|
||||
|
||||
private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams
|
||||
, String zipFileName)
|
||||
throws DeviceManagementException, IOException {
|
||||
String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath;
|
||||
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) {
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, List<String>> getProperties(String propertyFilePath) throws IOException {
|
||||
Properties prop = new Properties();
|
||||
InputStream input = null;
|
||||
|
||||
try {
|
||||
input = new FileInputStream(propertyFilePath);
|
||||
// load a properties file
|
||||
prop.load(input);
|
||||
Map<String, List<String>> properties = new HashMap<String, List<String>>();
|
||||
|
||||
String templates = prop.getProperty("templates");
|
||||
List<String> list = new ArrayList<String>(Arrays.asList(templates.split(",")));
|
||||
properties.put("templates", list);
|
||||
|
||||
final String filename = prop.getProperty("zipfilename");
|
||||
list = new ArrayList<String>() {{
|
||||
add(filename);
|
||||
}};
|
||||
properties.put("zipfilename", list);
|
||||
return properties;
|
||||
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Failed closing connection", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseTemplate(String srcFile, Map contextParams) throws IOException {
|
||||
//read from file
|
||||
FileInputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(srcFile);
|
||||
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());
|
||||
}
|
||||
return content;
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] createZipArchive(String srcFolder, List<TemplateFile> processTemplateFiles) throws IOException {
|
||||
ZipOutputStream out = null;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
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 null;
|
||||
}
|
||||
for (String sd : subdirList) {
|
||||
// get a list of files from current directory
|
||||
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 null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
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
|
||||
{
|
||||
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);
|
||||
out.write(IOUtils.toByteArray(new FileInputStream(f)));
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
out.finish();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp;
|
||||
|
||||
|
||||
public class VirtualFirealarmXMPPException extends Exception{
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public VirtualFirealarmXMPPException(String msg, Exception nestedEx) {
|
||||
super(msg, nestedEx);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public VirtualFirealarmXMPPException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
setErrorMessage(message);
|
||||
}
|
||||
|
||||
public VirtualFirealarmXMPPException(String msg) {
|
||||
super(msg);
|
||||
setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public VirtualFirealarmXMPPException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public VirtualFirealarmXMPPException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp;
|
||||
|
||||
/**
|
||||
* holds the information related to account that needs to be created on xmpp server.
|
||||
*/
|
||||
public class XmppAccount {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String accountName;
|
||||
private String email;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
public class XmppConfig {
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
private String username;
|
||||
private String password;
|
||||
private String serverName;
|
||||
private boolean enabled;
|
||||
private String jid;
|
||||
private static XmppConfig xmppConfig = new XmppConfig();
|
||||
private static final Log log = LogFactory.getLog(XmppConfig.class);
|
||||
private static final String ENABLED = "enabled";
|
||||
private static final String USERNAME = "username";
|
||||
private static final String PASSWORD = "password";
|
||||
private static final String HOST = "host";
|
||||
private static final String PORT = "port";
|
||||
private static final String SERVERNAME = "serverName";
|
||||
private static final String JID = "jid";
|
||||
|
||||
private XmppConfig() {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
InputStream input = classLoader.getResourceAsStream("../xmpp.properties");
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(input);
|
||||
enabled = Boolean.parseBoolean(properties.getProperty(ENABLED, "false"));
|
||||
host = properties.getProperty(HOST);
|
||||
port = Integer.parseInt(properties.getProperty(PORT));
|
||||
username = properties.getProperty(USERNAME);
|
||||
password = properties.getProperty(PASSWORD);
|
||||
serverName = properties.getProperty(SERVERNAME);
|
||||
jid = properties.getProperty(JID);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load xmpp config properties.");
|
||||
}
|
||||
}
|
||||
|
||||
public static XmppConfig getInstance() {
|
||||
return xmppConfig;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp;
|
||||
|
||||
import org.jivesoftware.smack.AccountManager;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmppServerClient {
|
||||
|
||||
public static boolean createAccount(XmppAccount xmppAccount) throws VirtualFirealarmXMPPException {
|
||||
if (XmppConfig.getInstance().isEnabled()) {
|
||||
if (xmppAccount != null) {
|
||||
try {
|
||||
ConnectionConfiguration config = new ConnectionConfiguration(XmppConfig.getInstance().getHost(),
|
||||
XmppConfig.getInstance().getPort(),
|
||||
"Accounts");
|
||||
XMPPConnection xmppConnection = new XMPPConnection(config);
|
||||
xmppConnection.connect();
|
||||
xmppConnection.login(XmppConfig.getInstance().getUsername(), XmppConfig.getInstance().getPassword());
|
||||
AccountManager accountManager = xmppConnection.getAccountManager();
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("username", xmppAccount.getUsername());
|
||||
attributes.put("password", xmppAccount.getPassword());
|
||||
attributes.put("email", xmppAccount.getEmail());
|
||||
attributes.put("name", xmppAccount.getAccountName());
|
||||
accountManager.createAccount(xmppAccount.getUsername(), xmppAccount.getPassword(), attributes);
|
||||
xmppConnection.disconnect();
|
||||
return true;
|
||||
} catch (XMPPException e) {
|
||||
if (e.getXMPPError().getCode() == 409) {
|
||||
//AccountAlreadyExist
|
||||
return true;
|
||||
} else {
|
||||
throw new VirtualFirealarmXMPPException(
|
||||
"XMPP account creation failed. Error: " + e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new VirtualFirealarmXMPPException("Invalid XMPP attributes");
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<!-- This file contains the list of permissions that are associated with URL end points
|
||||
of the web app. Each permission should contain the name, permission path ,API path
|
||||
(URL) , HTTP method and OAUTH2 authorization scope (not-required).
|
||||
When defining dynamic paths for APIs, path variables are denoted by '*' notation.
|
||||
NOTE: All the endpoints of the web app should be available in this file. Otherwise
|
||||
it will result 403 error at the runtime.
|
||||
-->
|
||||
<PermissionConfiguration>
|
||||
<APIVersion></APIVersion>
|
||||
<!-- Device related APIs -->
|
||||
<Permission>
|
||||
<name>Download device</name>
|
||||
<path>/device-mgt/user/devices</path>
|
||||
<url>/device/download</url>
|
||||
<method>GET</method>
|
||||
<scope>virtual_firealarm_user</scope>
|
||||
</Permission>
|
||||
<Permission>
|
||||
<name>Control Buzz</name>
|
||||
<path>/device-mgt/user/operation</path>
|
||||
<url>/device/*/buzz</url>
|
||||
<method>POST</method>
|
||||
<scope>virtual_firealarm_user</scope>
|
||||
</Permission>
|
||||
<Permission>
|
||||
<name>Get Stats</name>
|
||||
<path>/device-mgt/user/stats</path>
|
||||
<url>/device/stats/*</url>
|
||||
<method>GET</method>
|
||||
<scope>virtual_firealarm_user</scope>
|
||||
</Permission>
|
||||
</PermissionConfiguration>
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2005-2013 WSO2, Inc. (http://wso2.com)
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
|
||||
-->
|
||||
<Classloading xmlns="http://wso2.org/projects/as/classloading">
|
||||
|
||||
<!-- Parent-first or child-first. Default behaviour is child-first.-->
|
||||
<ParentFirst>false</ParentFirst>
|
||||
|
||||
<!--
|
||||
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
|
||||
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
|
||||
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
|
||||
-->
|
||||
<Environments>CXF3,Carbon</Environments>
|
||||
</Classloading>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
|
||||
|
||||
<jaxrs:server id="VirtualFireAlarm" address="/">
|
||||
<jaxrs:serviceBeans>
|
||||
<bean id="VirtualFireAlarmService"
|
||||
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmServiceImpl">
|
||||
</bean>
|
||||
</jaxrs:serviceBeans>
|
||||
<jaxrs:providers>
|
||||
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
|
||||
</beans>
|
||||
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<web-app version="2.5"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
metadata-complete="true">
|
||||
<display-name>WSO2 IoT Server</display-name>
|
||||
<description>WSO2 IoT Server</description>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<context-param>
|
||||
<param-name>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>
|
||||
<param-name>managed-api-enabled</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.listener.VirtualFireAlarmPermissionUpdateListener</listener-class>
|
||||
</listener>
|
||||
|
||||
</web-app>
|
@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
|
||||
#[XMPP-Configurations]
|
||||
enabled=false
|
||||
username=admin
|
||||
password=admin
|
||||
host=localhost
|
||||
port=5222
|
||||
serverName=localhost
|
||||
jid=admin@localhost
|
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2014, 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>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>device-types</artifactId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>virtual-fire-alarm-plugin</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>WSO2 Carbon - Virtual Fire Alarm Plugin</name>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<modules>
|
||||
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl</module>
|
||||
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-scr-plugin</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-scr-scrdescriptor</id>
|
||||
<goals>
|
||||
<goal>scr</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>device-types-feature</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>WSO2 Carbon - Device Management IoT Plugins Feature</name>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<modules>
|
||||
<module>virtual-fire-alarm-plugin-feature</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
@ -0,0 +1,157 @@
|
||||
<?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>virtual-fire-alarm-plugin-feature</artifactId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend.feature</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>WSO2 Carbon - IoT Server VirtualFireAlarm Backend Feature</name>
|
||||
<url>http://wso2.org</url>
|
||||
<description>This feature contains the VirtualFireAlarm Device type specific backend implementations for the IoT Server
|
||||
</description>
|
||||
|
||||
<!-- <properties>-->
|
||||
<!-- <orbit.h2.version>1.4.199.wso2v1</orbit.h2.version>-->
|
||||
<!-- </properties>-->
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</artifactId>
|
||||
<version>${carbon.devicemgt.plugins.version}</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.orbit.com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${orbit.h2.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>src/main/resources</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>resources</directory>
|
||||
<includes>
|
||||
<include>build.properties</include>
|
||||
<include>p2.inf</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-jaxrs-war</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api
|
||||
</artifactId>
|
||||
<type>war</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>${project.build.directory}/maven-shared-archive-resources/webapps/</outputDirectory>
|
||||
<destFileName>virtual_firealarm.war</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-agent-jar</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl
|
||||
</artifactId>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>${project.build.directory}/maven-shared-archive-resources/agent/</outputDirectory>
|
||||
<destFileName>wso2-firealarm-virtual-agent.jar</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.wso2.maven</groupId>
|
||||
<artifactId>carbon-p2-plugin</artifactId>
|
||||
<version>${carbon.p2.plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>p2-feature-generation</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>p2-feature-gen</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<id>org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend</id>
|
||||
<propertiesFile>../../../features/etc/feature.properties</propertiesFile>
|
||||
<adviceFile>
|
||||
<properties>
|
||||
<propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
|
||||
<propertyDef>org.eclipse.equinox.p2.type.group:true</propertyDef>
|
||||
</properties>
|
||||
</adviceFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
|
||||
#[Device-Configurations]
|
||||
tenantDomain=${TENANT_DOMAIN}
|
||||
owner=${DEVICE_OWNER}
|
||||
deviceId=${DEVICE_ID}
|
||||
device-name=${DEVICE_NAME}
|
||||
https-ep=${HTTPS_EP}
|
||||
http-ep=${HTTP_EP}
|
||||
apim-ep=${APIM_EP}
|
||||
mqtt-ep=${MQTT_EP}
|
||||
xmpp-ep=${XMPP_EP}
|
||||
application-key=${API_APPLICATION_KEY}
|
||||
auth-token=${DEVICE_TOKEN}
|
||||
refresh-token=${DEVICE_REFRESH_TOKEN}
|
||||
push-interval=15
|
||||
xmpp-server-name=${SERVER_NAME}
|
||||
server-jid=${SERVER_JID}
|
||||
|
@ -0,0 +1,2 @@
|
||||
templates=deviceConfig.properties
|
||||
zipfilename=FireAlarmVirtualAgent.zip
|
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
echo.
|
||||
echo.WSO2 IOT Sample
|
||||
echo.Virtual Fire Alarm
|
||||
echo.initializing agent
|
||||
echo.
|
||||
java -jar wso2-firealarm-virtual-agent.jar
|
@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "----------------------------------------------------------------"
|
||||
echo "| WSO2 IOT Sample "
|
||||
echo "| Virtual RaspiAlarm "
|
||||
echo "| ---------------- "
|
||||
echo "| ....initializing startup-script "
|
||||
echo "----------------------------------------------------------------"
|
||||
|
||||
#while true; do
|
||||
# read -p "What is the network-interface of your device that the Agent should use (find from ifconfig. ex: wlan0,en0,eth0..) > " interface
|
||||
#
|
||||
# echo "Setting the network-interface to " $interface
|
||||
# sed s/^network-interface=.*/network-interface=$interface/ deviceConfig.properties > myTmp
|
||||
# mv -f myTmp deviceConfig.properties
|
||||
# break;
|
||||
#done
|
||||
#
|
||||
#while true; do
|
||||
# read -p "Whats the time-interval (in seconds) between successive Data-Pushes to the WSO2-IoT-Server (ex: '60' indicates 1 minute) > " interval
|
||||
#
|
||||
# if [ $interval -eq $interval 2>/dev/null ]
|
||||
# then
|
||||
# echo "Setting data-push interval to " $interval " seconds."
|
||||
# sed s/^push-interval=.*/push-interval=$interval/ deviceConfig.properties > myTmp
|
||||
# mv -f myTmp deviceConfig.properties
|
||||
# break;
|
||||
# else
|
||||
# echo "Input needs to be an integer indicating the number seconds between successive data-pushes."
|
||||
# fi
|
||||
#done
|
||||
|
||||
|
||||
java -jar wso2-firealarm-virtual-agent.jar
|
||||
|
||||
#while true; do
|
||||
# read -p "Do you wish to run 'apt-get update' and continue? [Yes/No] " yn
|
||||
# case $yn in
|
||||
# [Yy]* ) sudo apt-get update;
|
||||
# break;;
|
||||
# [Nn]* ) echo "Continuing without apt-get update...";
|
||||
# break;;
|
||||
# * ) echo "Please answer yes or no.";
|
||||
# esac
|
||||
#done
|
||||
#
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "apt-get update failed.... Some dependencies may not get installed"
|
||||
# echo "If an already installed version of the package exists, try running:"
|
||||
# echo "----------------------------------------------------------------"
|
||||
# echo "sudo -i"
|
||||
# echo "cd /var/lib/dpkg/info"
|
||||
# echo "rm -rf wso2-raspi-alarm*"
|
||||
# echo "dpkg --remove --force-remove-reinstreq wso2-raspi-alarm"
|
||||
# echo "exit"
|
||||
# echo "----------------------------------------------------------------"
|
||||
# echo "Retry Installation...."
|
||||
# break;
|
||||
#fi
|
||||
#
|
||||
#echo "Installing 'gdebi' package..."
|
||||
#sudo apt-get install gdebi # installation of gdebi
|
||||
#
|
||||
#
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "gdebi installation failed.... dependencies will not be installed without gdebi"
|
||||
# read -p "Do you wish to continue without gdebi? [Yes/No] " yn
|
||||
# case $yn in
|
||||
# [Yy]* ) echo "Continueing without gdebi.....";;
|
||||
# [Nn]* ) echo "Try to resolve errors and re-run the script.";
|
||||
# exit;;
|
||||
# * ) exit;;
|
||||
# esac
|
||||
#fi
|
||||
#
|
||||
#
|
||||
#for f in ./wso2-raspi-alarm_1.0_armhf.deb; do
|
||||
# ## Check if the glob gets expanded to existing files.
|
||||
# ## If not, f here will be exactly the pattern above
|
||||
# ## and the exists test will evaluate to false.
|
||||
# # [ -e "$f" ] && echo "'wso2-raspi-alarm_1.0_armhf.deb' file found and installing" || echo "'wso2-raspi-alarm_1.0_armhf.deb' file does not exist in current path"; exit;
|
||||
# if [ -e "$f" ]; then
|
||||
# echo "'wso2-raspi-alarm_1.0_armhf.deb' file found and installing now...."
|
||||
# else
|
||||
# echo "'wso2-raspi-alarm_1.0_armhf.deb' file does not exist in current path. \nExiting installation...";
|
||||
# exit;
|
||||
# fi
|
||||
# ## This is all we needed to know, so we can break after the first iteration
|
||||
# break
|
||||
#done
|
||||
#
|
||||
#echo "Installing the 'wso2-raspi-alarm deb package'"
|
||||
#sudo gdebi wso2-raspi-alarm_1.0_armhf.deb
|
||||
#
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "Installation Failed...."
|
||||
# exit;
|
||||
#fi
|
||||
|
||||
#sudo killall -9 python
|
||||
#
|
||||
#for f in ./RaspberryAgent.zip; do
|
||||
# ## Check if the glob gets expanded to existing files.
|
||||
# ## If not, f here will be exactly the pattern above
|
||||
# ## and the exists test will evaluate to false.
|
||||
# # [ -e "$f" ] && echo "'wso2-raspi-alarm_1.0_armhf.deb' file found and installing" || echo "'wso2-raspi-alarm_1.0_armhf.deb' file does not exist in current path"; exit;
|
||||
# if [ -e "$f" ]; then
|
||||
# echo "Agent files found......"
|
||||
# sudo rm -rf /usr/local/src/RaspberryAgent
|
||||
# sudo unzip RaspberryAgent.zip -d /usr/local/src/
|
||||
# else
|
||||
# echo "'RaspberryAgent.zip' file does not exist in current path. \nInstalling without upgrading agent...";
|
||||
# fi
|
||||
# ## This is all we needed to know, so we can break after the first iteration
|
||||
# break
|
||||
#done
|
||||
#
|
||||
#for f in /usr/local/src/RaspberryAgent/rc.local; do
|
||||
# ## Check if the glob gets expanded to existing files.
|
||||
# ## If not, f here will be exactly the pattern above
|
||||
# ## and the exists test will evaluate to false.
|
||||
# if [ -e "$f" ]; then
|
||||
# echo "Copying boot script"
|
||||
# sudo mv /usr/local/src/RaspberryAgent/rc.local /etc/rc.local
|
||||
# sudo chmod +x /etc/rc.local
|
||||
# else
|
||||
# echo "Unable to set agent statup on boot";
|
||||
# fi
|
||||
# ## This is all we needed to know, so we can break after the first iteration
|
||||
# break
|
||||
#done
|
||||
#
|
||||
#for f in ./deviceConfigs.cfg; do
|
||||
# ## Check if the glob gets expanded to existing files.
|
||||
# ## If not, f here will be exactly the pattern above
|
||||
# ## and the exists test will evaluate to false.
|
||||
# if [ -e "$f" ]; then
|
||||
# echo "Configuration file found......"
|
||||
# else
|
||||
# echo "'deviceConfigs.cfg' file does not exist in current path. \nExiting installation...";
|
||||
# exit;
|
||||
# fi
|
||||
# ## This is all we needed to know, so we can break after the first iteration
|
||||
# break
|
||||
#done
|
||||
#
|
||||
#echo "Altering Configuration file"
|
||||
#sed -i 's|[/,]||g' deviceConfigs.cfg
|
||||
#
|
||||
#echo "Copying configurations file to /usr/local/src/RaspberryAgent"
|
||||
#sudo cp ./deviceConfigs.cfg /usr/local/src/RaspberryAgent/
|
||||
#
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "Copying configuration file failed...."
|
||||
# exit;
|
||||
#fi
|
||||
#
|
||||
#while true; do
|
||||
# read -p "Whats the time-interval (in seconds) between successive Data-Pushes to the WSO2-DC (ex: '60' indicates 1 minute) > " input
|
||||
#
|
||||
# if [ $input -eq $input 2>/dev/null ]
|
||||
# then
|
||||
# echo "Setting data-push interval to $input seconds."
|
||||
# echo $input > /usr/local/src/RaspberryAgent/time-interval
|
||||
# break;
|
||||
# else
|
||||
# echo "Input needs to be an integer indicating the number seconds between successive data-pushes."
|
||||
# fi
|
||||
#done
|
||||
#
|
||||
#cd /usr/local/src/RaspberryAgent/
|
||||
#sudo chmod +x RaspberryStats.py
|
||||
#sudo nohup ./RaspberryStats.py -i $input </dev/null &
|
||||
#
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "Could not start the service..."
|
||||
# exit;
|
||||
#else
|
||||
# echo "Running the RaspberryAgent service...."
|
||||
#fi
|
||||
#
|
||||
#echo "--------------------------------------------------------------------------"
|
||||
#echo "| Successfully Started "
|
||||
#echo "| -------------------------- "
|
||||
#echo "| cd to /usr/local/src/RaspberryAgent"
|
||||
#echo "| run 'sudo nohup ./RaspberryStats.py -i time </dev/null &'to start service manually."
|
||||
#echo "| Relapce time with the time-interval (in seconds) between successive Data-Pushes to the WSO2-DC (ex: '60' indicates 1 minute)"
|
||||
#echo "| Find logs at: /usr/local/src/RaspberryAgent/logs/RaspberryStats.log"
|
||||
#echo "---------------------------------------------------------------------------"
|
||||
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
custom = true
|
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
<DeviceTypeConfiguration name="virtual_firealarm">
|
||||
<Features>
|
||||
<Feature code="buzz">
|
||||
<Name>Control buzzer</Name>
|
||||
<Description>Control buzzer on Virtual Firealarm</Description>
|
||||
<Operation context="/virtual_firealarm/device/{deviceId}/buzz" method="POST">
|
||||
</Operation>
|
||||
</Feature>
|
||||
</Features>
|
||||
|
||||
<ProvisioningConfig>
|
||||
<SharedWithAllTenants>true</SharedWithAllTenants>
|
||||
</ProvisioningConfig>
|
||||
|
||||
<PushNotificationProviderConfig type="MQTT">
|
||||
<FileBasedProperties>true</FileBasedProperties>
|
||||
</PushNotificationProviderConfig>
|
||||
|
||||
<!--<PushNotificationProviderConfig type="XMPP">-->
|
||||
<!--<FileBasedProperties>true</FileBasedProperties>-->
|
||||
<!--<!–if file based properties is set to false then the configuration will be picked from platform configuration–>-->
|
||||
<!--<ConfigProperties>-->
|
||||
<!--<Property Name="xmpp.adapter.name">virtualfirealarm.xmpp.adapter</Property>-->
|
||||
<!--<Property Name="host">localhost</Property>-->
|
||||
<!--<Property Name="port">5222</Property>-->
|
||||
<!--<Property Name="username">admin</Property>-->
|
||||
<!--<Property Name="password">admin</Property>-->
|
||||
<!--<Property Name="jid">admin@localhost</Property>-->
|
||||
<!--<Property Name="server.name">localhost</Property>-->
|
||||
<!--</ConfigProperties>-->
|
||||
<!--</PushNotificationProviderConfig>-->
|
||||
|
||||
<License>
|
||||
<Language>en_US</Language>
|
||||
<Version>1.0.0</Version>
|
||||
<Text>This is license text</Text>
|
||||
</License>
|
||||
|
||||
</DeviceTypeConfiguration>
|
@ -0,0 +1,16 @@
|
||||
instructions.configure = \
|
||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/deployment/server/webapps/);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/webapps/,target:${installFolder}/../../../repository/deployment/server/webapps/,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/deployment/server/devicetypes/);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/devicetypes/,target:${installFolder}/../../../repository/deployment/server/devicetypes/,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/receiver/,target:${installFolder}/../../../repository/deployment/server/eventreceivers/,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/streams/,target:${installFolder}/../../../repository/deployment/server/eventstreams/,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/publisher/,target:${installFolder}/../../../repository/deployment/server/eventpublishers/,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/sketches/);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/sketches/virtual_firealarm/);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend_${feature.version}/agent/,target:${installFolder}/../../../repository/resources/sketches/virtual_firealarm/,overwrite:true);\
|
||||
|
||||
instructions.unconfigure = \
|
||||
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../../repository/deployment/server/webapps/virtual_firealarm.war);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../../repository/deployment/server/webapps/virtual_firealarm);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../../repository/deployment/server/devicetypes/virtual_firealarm.xml);\
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<eventPublisher name="virtual_firealarm_rdbms_publisher-carbon.super" processing="enable"
|
||||
statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventpublisher">
|
||||
<from streamName="iot.per.device.stream.virtualfirealarm" version="1.0.0"/>
|
||||
<mapping customMapping="disable" type="map"/>
|
||||
<to eventAdapterType="rdbms">
|
||||
<property name="datasource.name">EVENT_DB</property>
|
||||
<property name="table.name">table_virtualfirealarm_carbonsuper_rdbms_publisher</property>
|
||||
<property name="execution.mode">insert</property>
|
||||
</to>
|
||||
</eventPublisher>
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
<eventReceiver name="virtualfirealarm_receiver-carbon.super" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
|
||||
<from eventAdapterType="oauth-mqtt">
|
||||
<property name="contentTransformer"/>
|
||||
<property name="topic">carbon.super/virtual_firealarm/+/temperature</property>
|
||||
<property name="contentValidator">default</property>
|
||||
<property name="cleanSession">true</property>
|
||||
</from>
|
||||
<mapping customMapping="disable" type="json"/>
|
||||
<to streamName="iot.per.device.stream.virtualfirealarm" version="1.0.0"/>
|
||||
|
||||
</eventReceiver>
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "iot.per.device.stream.virtualfirealarm",
|
||||
"version": "1.0.0",
|
||||
"nickName": "virtual_firealarm",
|
||||
"description": "Temperature data received from the virtual_firealarm",
|
||||
"metaData": [
|
||||
{"name":"owner","type":"STRING"},
|
||||
{"name":"deviceId","type":"STRING"},
|
||||
{"name":"time","type":"TIMESTAMP"}
|
||||
],
|
||||
"payloadData": [
|
||||
{
|
||||
"name": "temperature","type": "FLOAT"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
~
|
||||
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||
~ Version 2.0 (the "License"); you may not use this file except
|
||||
~ in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>device-types-feature</artifactId>
|
||||
<version>6.0.16-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>virtual-fire-alarm-plugin-feature</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>WSO2 Carbon - IoT Server VirtualFireAlarm Device Feature</name>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<modules>
|
||||
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.backend.feature</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
Loading…
Reference in new issue