Commit 0505077c by Alex Rhodes

initial commit

parents
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>IoT-Server</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8
eclipse.preferences.version=1
org.eclipse.jpt.core.platform=eclipselink2_4
org.eclipse.jpt.jpa.core.discoverAnnotatedClasses=true
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="IoT-Server">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="IoT-Server"/>
<property name="java-output-path" value="/IoT-Server/target/classes"/>
</wb-module>
</project-modules>
<root>
<facet id="jst.jaxrs">
<node name="libprov">
<attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
</node>
</facet>
<facet id="jpt.jpa">
<node name="libprov">
<attribute name="provider-id" value="jpa-no-op-library-provider"/>
</node>
</facet>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.8"/>
<installed facet="jst.web" version="3.1"/>
<installed facet="jpt.jpa" version="2.0"/>
<installed facet="jst.jaxrs" version="2.0"/>
</faceted-project>
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
Window
\ No newline at end of file
disabled=06target
eclipse.preferences.version=1
This diff is collapsed. Click to expand it.
/*
IoT Server - Light switch client
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This script, to be run on a web-connected arduino microcontroller, is an example of a simple HTTP client of the web service
IoT Server - Lightswitch client
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/
This page is an example of a simple http client for the IoT web service.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <SPI.h>
#include <Ethernet.h>
//Set a unique name to assign to your device
String deviceName = "arduino-lightswitch";
//Set host and port where your web service is running
char registration_address[] = "192.168.0.8";
int servicePort = 8080;
//Set the mac address and desired IP address of the service
byte mac[] = {0xAA, 0xAA, 0xBB, 0xBB, 0xCC, 0xCC};
IPAddress ip(192, 168, 0, 35);
EthernetServer server(80);
EthernetClient client;
int lightPin = 8;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
delay(500);
Serial.println("Server starting..");
Ethernet.begin(mac, ip);
String ip = ipToString(Ethernet.localIP());
//Register with the web service
registerDevice(ip,deviceName);
server.begin();
Serial.print("Server started at ");
Serial.println(Ethernet.localIP());
pinMode(lightPin,OUTPUT);
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
String input = "";
if (client.available()) {
input = client.readStringUntil('\r');
Serial.println(input);
delay(10);
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("Arduino server");
client.println("</html>");
}
delay(1);
client.stop();
Serial.println("client disconnected");
if(input.indexOf("light=off")!= -1){
Serial.println("Turning off");
digitalWrite(lightPin,LOW);
}
if(input.indexOf("light=on") != -1){
Serial.println("Turning on");
digitalWrite(lightPin,HIGH);
}
}
}
//Register the device's unique name and IP address via the web service REST API
void registerDevice(String ip, String deviceName){
Serial.println("Registering " + deviceName + " with service at " + ip);
if(client.connect(registration_address,servicePort)){
Serial.println("connected..");
client.println("GET /IoT-Server/rest/insecure/register?name="+deviceName+"&ip="+ip+" HTTP/1.1");
client.println("Host: " + String(registration_address));
client.println("Connection: close");
client.println();
Serial.println("registered");
}
}
//Utility to convert IP address to a string
String ipToString(const IPAddress& ipAddress)
{
return String(ipAddress[0]) + String(".") +\
String(ipAddress[1]) + String(".") +\
String(ipAddress[2]) + String(".") +\
String(ipAddress[3]) ;
}
<!DOCTYPE html>
<html lang="en">
<!--
IoT Server - Lightswitch client
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/
This page is an example of a simple http client for the IoT web service.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<head>
<title>Light Switch</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script>
var onUrl = "http://192.168.0.8:8080/IoT-Server/rest/insecure/send?device=arduino-lightswitch&command=light&value=on";
var offUrl = "http://192.168.0.8:8080/IoT-Server/rest/insecure/send?device=arduino-lightswitch&command=light&value=off";
$(document).ready(function(){
$("#on").click(function(){
$("#off").removeClass("btn-primary");
$("#off").addClass("btn-default");
$("#on").removeClass("btn-default");
$("#on").addClass("btn-primary");
$.get(onUrl);
});
$("#off").click(function(){
$("#on").removeClass("btn-primary");
$("#on").addClass("btn-default");
$("#off").removeClass("btn-default");
$("#off").addClass("btn-primary");
$.get(offUrl);
});
});
</script>
</head>
</head>
<body>
<div class="container">
<div class="panel panel-default" style="width:400px;height:300px;margin:auto;margin-top:50px">
<div class="panel-heading" style="font-size:1.4em">Light Switch</div>
<div class="panel-body" style="text-align:center">
<button class="btn btn-default" id="on" style="width:150px;height:30px;margin:10px;font-size:1.2em;font-weight:bold">On</button>
<br/>
<button class="btn btn-primary" id="off" style="width:150px;height:30px;margin:10px;font-size:1.2em;font-weight:bold">Off</button>
</div>
</div>
</div>
</body>
</html>
# IoT Network Java Web Service - 1.0 #
IoT Server - Lightswitch client
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
## Introduction ##
This project is designed to serve a skeletal platform for a REST Internet-of-Things web service. The goals of the application are as follows:
+ Allow any device capable of HTTP connections to send and receive commands from any other device on the network. This inlcudes micro-controllers, mobile applications, desktop computers or any other device capable of sending GET or POST requests.
+ Provides IP Address independent device lookup, allowing devices to register a unique name and IP address pair with the service when connecting or reconnecting so that other devices may communicate with them via their name regardless of their impermanent IP address.
+ Provide database integration within the IoT environment to allow things like device lookup, command storage, configuration settings etc.
This service was designed to be a foundation for an IoT server project. It provides opportunities for implementing many features to improve simplistic device-to-device implementations. For example:
- integrating command storage and logging, i.e commands sent to devices that are offline will be stored and sent when the device re-connects
- exposure to the web via REST API interfaces allowing communication with the device from outside the local network
- Centralized configuration settings and the option of creating a central control interface. For example, a web GUI to allow the configuration and scheduling of an automatic light controller, and centralized storage of these settings available for look up by all of the controllers on the network.
## Assumptions and Expectations ##
This information is provided for individuals with experience in programming, some knowledge of HTTP communication, RESTful web services, and various programming and development technologies and environments. If you are unfamiliar with any of the concepts mentioned below, there are numerous resources available online to learn. I am willing to assist with minor technical issues or questions about the service but I will refer you to online resources for basic questions about getting started with the technologies mentioned below, or programming in general. I provided links that I hope will be helpful in the sections below.
**Feel free to contact me at alexrhodes@live.com**
## Configuration ##
This section will provide information on configuring and running the project. These instructions are not exhaustive, but provide links to 3rd party, detailed configuration tutorials.
## Requirements ##
The web service provided is written in Java. The project is integrated with the Maven build management system. Dependencies are managed by Maven. The service is designed to run on a Java application server. This project was specifically developed and tested on Apache Tomcat. The service requires a connection to a MySQL or other SQL server. The example client provided is designed to operate on an Arduino micro-controller, and the example control client runs in most web browsers. These example clients can be easily adapted or replaced to suit your needs.
## Set Up Process ##
Within each of the files mentioned in this section, there are comments with information about usage and configuration. Please view these files for more information than what is provided below.
The project should be imported into a Maven compatible Java development environment, such as Eclipse. The database persistence connection information must be updated in the persistence.xml file located in *~project root~/ src / main / resources / META-INF / persistence.xml*
The file will need the URL path to your MySQL connection, as well as the authentication information. The project should be deployed to an application server. There may be additional configuration per your particular environment.
More information (I do not own these links and they may not be current, please let me know if you find a dead link):
+ Maven build managment - http://www.tutorialspoint.com/maven/
+ Java Persistence - http://www.tutorialspoint.com/jpa/
+ Java web service deployment (tomcat) - https://examples.javacodegeeks.com/enterprise-java/jws/jax-ws-web-services-on-tomcat/
+ MySQL server set up and config (Apache XAMPP) - https://blog.udemy.com/xampp-tutorial/
The example client provided under *~project root~/Client Example/Arduino_Lightswitch* is a simple script designed for the Arduino micro-controller that has either a WiFI or Ethernet connection "shield" allowing it to operate as a web client and server. The script will need to be configured with your desired name for the client, the IP address to assign to it, a MAC address to assign, and the Ip Address and port where the web service is operational. This client is simply provided as example use case for this service.
More information (I do not own these links and they may not be current, please let me know if you find a dead link):
+ The Arduino micro-controller - https://www.arduino.cc/en/Guide/Introduction
+ Ethernet shield - https://www.arduino.cc/en/Main/ArduinoEthernetShield
The example control client under *~project root~/Client Example/Light Switch.html* will run in any browser.It will require that the URLs within be updated with the url of your web service and desired commands.
## Usage ##
The service operates two REST API functions at two URLs:
### Device Registration###
**~Context Root~/rest/insecure/register**
This URL allows a device to register it's name and IP address with the web service when it connects. The name and IP address are passed in query parameters of the form:
*name=<device name>&ip=<device ip>*
An example of this URL would be:
http://192.168.0.8:8080/IoT-Server/rest/insecure/register?name=arduino-lightswitch&ip=192.168.0.13
This API call's purpose is to allow a newly connected device to register it's IP address whenever it connects to the network. The purpose of this registration is to allow other devices to target commands to this device without needing to know the device's actual IP address (Because it may change). The only parameter the sending device needs to know is the device's permanent name. In my example client, the device's name is "arduino-lightswitch" and all commands addressed to this device are pointed to it's name. The IP address and actual connection process is handled by the webservice.
### Command Send###
**~Context Root~/rest/insecure/send**
This URL allows a device to send a named command to a device by specifying the target device's name, the command name, and the value of the command. These values are passed as parameters in the form:
*device=<target device>&command=<command name>&value=<command value>*
An example of this URL would be:
http://192.168.0.8:8080/IoT-Server/rest/insecure/send?device=arduino-lightswitch&command=light&value=off
This API call's purpose is to allow a device to send a command to another device. The command name and value is sent to the web service, along with the name of the target device. The service looks up the device's ip address information and handles the connection. The service relays the device's response back to the caller. The commands are sent to the receiving device via GET parameter in the url in the form:
*name=value*
An example URL a device will be called at by the service is:
https://192.168.0.35?light=on
The device is then responsible for parsing and reacting to these GET parameters.
\ No newline at end of file
<!--
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
Thermostat for Echo is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<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>
<groupId>com.alexscottrhodes</groupId>
<artifactId>IoT-Server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Iot Server</name>
<description>A java web service for Internet of Things networks and devices</description>
<dependencies>
<!-- GSON for json parsing -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<!-- Jersey for the REST API-->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19.1</version>
</dependency>
<!-- Persistence for DB communication -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/** A model of a command, sent to a given device. A device may have many commands. Commands are stored only if they are not successfully sent to the device.
* A device can then retrieve commands that were missed while it was offline.
*
* @author Alex Rhodes
*
*/
@Entity
@Table(name="commands")
public class Command {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@JoinColumn
@ManyToOne
private Device targetDevice;
@Column
private String commandName;
@Column
private String commandValue;
@Column
private boolean sent;
@Column
private Date timestamp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Device getTargetDevice() {
return targetDevice;
}
public void setTargetDevice(Device targetDevice) {
this.targetDevice = targetDevice;
}
public String getCommandName() {
return commandName;
}
public void setCommandName(String commandName) {
this.commandName = commandName;
}
public String getCommandValue() {
return commandValue;
}
public void setCommandValue(String commandValue) {
this.commandValue = commandValue;
}
public boolean isSent() {
return sent;
}
public void setSent(boolean sent) {
this.sent = sent;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* A model of a device object
* @author Alex Rhodes
*
*/
@Entity
@Table(name="devices")
@NamedQueries({
@NamedQuery(name="getDeviceByName",query="SELECT d FROM Device d WHERE d.name = :name")
})
public class Device {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column
private String ipAddress;
@Column
private String name;
@JoinColumn
@OneToMany(cascade = CascadeType.ALL)
private List<Command> commands;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Command> getCommands() {
return commands;
}
public void setCommands(List<Command> commands) {
this.commands = commands;
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.model;
/**
* An object to hold information about a given HTTP request interaction with a device, including a boolean for the success
* of the transaction, the HTTP response code, the HTTP message, and if applicable, the device or service's response.
* @author Alex Rhodes
*
*/
public class HttpResult {
private boolean successful;
private int responseCode;
private String response;
private String httpMessage;
public int getResponseCode() {
return responseCode;
}
public void setResponseCode(int responseCode) {
this.responseCode = responseCode;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
public boolean getSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public String getHttpMessage() {
return httpMessage;
}
public void setHttpMessage(String httpMessage) {
this.httpMessage = httpMessage;
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.model;
import java.util.ArrayList;
/**
* An object that stores HttpResult objects to be sent back to the sender when multiple HTTP transactions occur with receivers.
* @author Alex Rhodes
*
*/
public class TransactionResult {
boolean successful;
ArrayList<HttpResult> success = new ArrayList<HttpResult>();
ArrayList<HttpResult> fail = new ArrayList<HttpResult>();
public ArrayList<HttpResult> getSuccess() {
return success;
}
public void setSuccess(ArrayList<HttpResult> success) {
this.success = success;
}
public ArrayList<HttpResult> getFail() {
return fail;
}
public void setFail(ArrayList<HttpResult> fail) {
this.fail = fail;
}
public boolean isSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import com.alexscottrhodes.model.Command;
import com.alexscottrhodes.model.Device;
import com.alexscottrhodes.model.TransactionResult;
import com.alexscottrhodes.service.CommandFunctions;
import com.alexscottrhodes.service.DeviceFunctions;
import com.google.gson.Gson;
/**
* The main endpoint for devices connecting to the IoT network for devices using GET parameters to pass data. The REST calls here do not require any type of authentication.
* @author Alex Rhodes
*
*/
@Path("/insecure")
public class Insecure {
private Gson gson = new Gson();
/**
* A utility URL that returns a 200 response when the webservice is up and running.
* @return a Response of 200 indicating the web service is available
*/
@GET
@Path("/")
@Produces("text/html")
public Response insecure(){
return Response.ok().build();
}
/**
* Method for devices to register their IP address with the service when first establishing a connection to the network.
* @param name a String representing the permanent name of the device that other devices on the network use when targeting it
* @param ipAddress a String of the device's IP address on the IoT network
* @return an HTTP Response indicating success or failure of the decvice's registration.
*/
@GET
@Path("/register")
public Response registerDevice( @QueryParam("name") String name, @QueryParam("ip") String ipAddress){
try{
if(DeviceFunctions.registerDevice(name,ipAddress)){
return Response.ok().build();
}else{
return Response.status(500).entity("There was a problem registering the device").build();
}
}catch(Exception e){
e.printStackTrace();
return Response.status(500).entity("There was a problem registering the device").build();
}
}
/**
* Method for sending a command to a device. The target device, command name and value are passed. The commands are stored in the database. Commands are then sent to the target device.
* If the device can not be reached, the commands are stored. If they device provides a response, this response and the response code is passed to the sending device.
* @param deviceName the Device identifier for the target device
* @param commandName the Command identifier for the command being sent
* @param commandValue the Command value to send
* @return a Response with an HttpTransaction object in JSON format providing successful and failed transaction information and device responses to the command.
*/
@GET
@Path("/send")
public Response sendCommand(@QueryParam("device") String deviceName, @QueryParam("command") String commandName, @QueryParam("value") String commandValue){
try{
Device d = DeviceFunctions.getDeviceByName(deviceName);
if(d == null){
return Response.status(400).entity("Device not found.").build();
}
Command command = new Command();
command.setCommandName(commandName);
command.setCommandValue(commandValue);
command.setTargetDevice(d);
command = CommandFunctions.storeCommand(command);
TransactionResult tr = CommandFunctions.sendCommands(command,d);
String trJson = gson.toJson(tr);
if(tr.isSuccessful()){
return Response.status(200).entity(trJson).build();
}else{
return Response.status(400).entity(trJson).build();
}
}catch(Exception e){
e.printStackTrace();
return Response.status(500).entity("There was a problem sending the commands").build();
}
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.alexscottrhodes.model.Command;
import com.alexscottrhodes.model.Device;
import com.alexscottrhodes.model.HttpResult;
import com.alexscottrhodes.model.TransactionResult;
import com.alexscottrhodes.utility.HttpFunctions;
/**
* Contains functions relating to command objects
*
* @author Alex Rhodes
*
*/
public class CommandFunctions {
private static EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("iot_persistence");
private static EntityManager em;
/**
* Store a new command in the database
* @param c a Command to be stored
* @return a Command that is merged with the persistence context
*/
public static Command storeCommand(Command c){
em = emFactory.createEntityManager();
em.getTransaction().begin();
c = em.merge(c);
em.getTransaction().commit();
return c;
}
/**
* Send a command to the target device. If the command is sent successfully, it is purged from the device's commands,
* otherwise it is stored until it can be successfully sent.
* @param c the Command to send
* @param d a Device to send the command to.
* @return a TransactionResult object containing a list of failed and successful HttpResult objects
*/
public static TransactionResult sendCommands(Command c, Device d){
TransactionResult tr = new TransactionResult();
em = emFactory.createEntityManager();
em.getTransaction().begin();
HttpResult hr = HttpFunctions.sendGet(d, c);
if(hr == null){
return null;
}
if(hr.getSuccessful()){
tr.getSuccess().add(hr);
c = em.find(Command.class, c.getId());
em.remove(c);
}else{
tr.getFail().add(hr);
}
em.getTransaction().commit();
return tr;
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.service;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.alexscottrhodes.model.Device;
/**
* Contains functions relating to IoT devices on the network
*
* @author Alex Rhodes
*
*/
public class DeviceFunctions {
private static EntityManagerFactory emFactory;
private static EntityManager em;
/**
* Register a device with the network. If the device already exists under the unique name, update its IP address information is updated.
* If the device does not exist, a new one is created.
* @param a String of the name a Unique identifier for the device
* @param a String of the ipAddress the IP address for the device
* @return a Boolean indicating a successful update
*/
public static boolean registerDevice(String name, String ipAddress){
emFactory = Persistence.createEntityManagerFactory("iot_persistence");
em = emFactory.createEntityManager();
em.getTransaction().begin();
Device d = new Device();
boolean exists = false;
try{
Query q = em.createNamedQuery("getDeviceByName").setParameter("name", name);
d = (Device) q.getSingleResult();
exists = true;
}catch(Exception e){ //Exception if no result
exists = false;
}
if(exists){
d.setIpAddress(ipAddress);
}else{
d.setName(name);
d.setIpAddress(ipAddress);
}
em.persist(d);
em.flush();
em.getTransaction().commit();
em.close();
emFactory.close();
return true;
}
/**
* Get a device by it's unique name
* @param name a String of the device's unique name
* @return a Device object with the given name
*/
public static Device getDeviceByName(String name){
emFactory = Persistence.createEntityManagerFactory("iot_persistence");
em = emFactory.createEntityManager();
em.getTransaction().begin();
Device d = new Device();
boolean exists = false;
try{
Query q = em.createNamedQuery("getDeviceByName").setParameter("name", name);
d = (Device) q.getSingleResult();
exists = true;
}catch(Exception e){ //Exception if no result
exists = false;
}
em.persist(d);
em.flush();
em.getTransaction().commit();
em.close();
emFactory.close();
if(exists){
return d;
}else{
return null;
}
}
}
/*
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.alexscottrhodes.utility;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import com.alexscottrhodes.model.Command;
import com.alexscottrhodes.model.Device;
import com.alexscottrhodes.model.HttpResult;
/**
* Contains methods for HTTP communication functions
* @author Alex Rhodes
*
*/
public class HttpFunctions {
/**
* Sends a GET command to the device specified with the command parameters specified.
* @param d a Device to send the command to
* @param c a Command to send
* @return an HttpResult object with the connection status and device response or error response.
*/
public static HttpResult sendGet(Device d, Command c){
HttpResult result = new HttpResult();
String query = "?";
query += c.getCommandName() + "=" + c.getCommandValue();
try{
String urlString = d.getIpAddress() + query;
urlString = "http://" + urlString;
URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setConnectTimeout(5000);
int responseCode = 500;
try{
con.connect();
responseCode = con.getResponseCode();
}catch(java.net.ConnectException e){
result.setResponseCode(408);
result.setHttpMessage("The device could not be reached.");
result.setSuccessful(false);
return result;
}
if(responseCode != 200){
result.setResponseCode(responseCode);
result.setHttpMessage(con.getResponseMessage());
result.setSuccessful(false);
return result;
}
BufferedReader inputResponse = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = inputResponse.readLine()) != null) {
response.append(inputLine);
}
inputResponse.close();
result.setResponse(response.toString());
result.setResponseCode(200);
result.setSuccessful(true);
return result;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
}
<!--
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd"
version="1.0">
<persistence-unit name="iot_persistence" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/iot" />
<property name="javax.persistence.jdbc.user" value="public" />
<property name="javax.persistence.jdbc.password" value="my_password" />
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<!--
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>IoT-Server</display-name>
<!-- REST servlet and mapping -->
<servlet>
<servlet-name>IoT Rest</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>IoT Rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
<!--
IoT Server
Copyright (C) 2016 Alex Rhodes
https://www.alexscottrhodes.com
Information about this project including set-up and configuration information can be found here:
https://bitbucket.org/alexscottrhodes/iot-network-java-web-service/overview
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd"
version="1.0">
<persistence-unit name="iot_persistence" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/iot" />
<property name="javax.persistence.jdbc.user" value="public" />
<property name="javax.persistence.jdbc.password" value="my_password" />
</properties>
</persistence-unit>
</persistence>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment