Merge pull request #735 from Savidude/master

Auto renewal of auth token for RaspberryPi agent
merge-requests/1/head
Rasika Perera 8 years ago committed by GitHub
commit d7b8e32744

@ -110,8 +110,8 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
@Produces("application/json")
public Response getRaspberryPiTemperatureStats(@PathParam("deviceId") String deviceId,
@QueryParam("from") long from, @QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String fromDate = String.valueOf(from*1000);
String toDate = String.valueOf(to*1000);
String query = "meta_deviceId:" + deviceId + " AND meta_deviceType:" +
RaspberrypiConstants.DEVICE_TYPE + " AND meta_time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = RaspberrypiConstants.TEMPERATURE_EVENT_TABLE;
@ -121,7 +121,7 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("time", SortType.ASC);
SortByField sortByField = new SortByField("meta_time", SortType.ASC);
sortByFields.add(sortByField);
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
@ -221,7 +221,7 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
String refreshToken = accessTokenInfo.getRefreshToken();
ZipUtil ziputil = new ZipUtil();
return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType,
deviceId, deviceName, accessToken, refreshToken);
deviceId, deviceName, accessToken, refreshToken, apiApplicationKey.toString());
}
private static String shortUUID() {

@ -18,9 +18,12 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.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.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
@ -61,7 +64,7 @@ public class ZipUtil {
public ZipArchive createZipFile(String owner, String tenantDomain, String deviceType,
String deviceId, String deviceName, String token,
String refreshToken) throws DeviceManagementException {
String refreshToken, String apiApplicationKey) throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String templateSketchPath = sketchFolder + File.separator + deviceType;
@ -96,6 +99,7 @@ public class ZipUtil {
}
}
}
String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey);
Map<String, String> contextParams = new HashMap<>();
contextParams.put("SERVER_NAME", APIUtil.getTenantDomainOftheUser());
@ -106,6 +110,7 @@ public class ZipUtil {
contextParams.put("HTTP_EP", httpServerEP);
contextParams.put("APIM_EP", httpsServerEP);
contextParams.put("MQTT_EP", mqttEndpoint);
contextParams.put("API_APPLICATION_KEY", base64EncodedApplicationKey);
contextParams.put("DEVICE_TOKEN", token);
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);
@ -119,6 +124,15 @@ public class ZipUtil {
}
}
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();

@ -20,14 +20,12 @@ owner=${DEVICE_OWNER}
deviceId=${DEVICE_ID}
device-name=${DEVICE_NAME}
controller-context=/raspberrypi/controller
mqtt-sub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId}
mqtt-pub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId}/publisher
https-ep=${HTTPS_EP}
http-ep=${HTTP_EP}
apim-ep=${APIM_EP}
mqtt-ep=${MQTT_EP}
xmpp-ep=${XMPP_EP}
auth-method=token
application-key=${API_APPLICATION_KEY}
auth-token=${DEVICE_TOKEN}
refresh-token=${DEVICE_REFRESH_TOKEN}
push-interval=15

@ -182,9 +182,6 @@ def connectAndPushData():
rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value
PUSH_DATA = iotUtils.DEVICE_INFO.format(currentTime, rPiTemperature)
print '~~~~~~~~~~~~~~~~~~~~~~~~ Publishing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~'
print ('PUBLISHED DATA: ' + PUSH_DATA)
print ('PUBLISHED TOPIC: ' + mqttConnector.TOPIC_TO_PUBLISH)
mqttConnector.publish(PUSH_DATA)
# print '~~~~~~~~~~~~~~~~~~~~~~~~ End Of Publishing ~~~~~~~~~~~~~~~~~~~~~~~~~'

@ -56,11 +56,10 @@ SERVER_NAME = configParser.get('Device-Configurations', 'server-name')
DEVICE_OWNER = configParser.get('Device-Configurations', 'owner')
DEVICE_ID = configParser.get('Device-Configurations', 'deviceId')
MQTT_EP = configParser.get('Device-Configurations', 'mqtt-ep')
XMPP_EP = configParser.get('Device-Configurations', 'xmpp-ep')
AUTH_TOKEN = configParser.get('Device-Configurations', 'auth-token')
REFRESH_TOKEN = configParser.get('Device-Configurations', 'refresh-token')
APPLICATION_KEY = configParser.get('Device-Configurations', 'application-key')
CONTROLLER_CONTEXT = configParser.get('Device-Configurations', 'controller-context')
MQTT_SUB_TOPIC = configParser.get('Device-Configurations', 'mqtt-sub-topic').format(owner = DEVICE_OWNER, deviceId = DEVICE_ID)
MQTT_PUB_TOPIC = configParser.get('Device-Configurations', 'mqtt-pub-topic').format(owner = DEVICE_OWNER, deviceId = DEVICE_ID)
DEVICE_INFO = '{{"event":{{"metaData":{{"owner":"' + DEVICE_OWNER + '","type":"raspberrypi","deviceId":"' + DEVICE_ID + '","time":{}}},"payloadData":{{"temperature":{:.2f}}}}}}}'
# '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","temperature":'

@ -23,16 +23,29 @@
import time
import iotUtils
import paho.mqtt.client as mqtt
from token_updater import RefreshToken
agent_connected = False
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("MQTT_LISTENER: Connected with result code " + str(rc))
if rc == 0:
global agent_connected
agent_connected = True
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
print ("MQTT_LISTENER: Subscribing with topic " + TOPIC_TO_SUBSCRIBE)
client.subscribe(TOPIC_TO_SUBSCRIBE)
elif rc == 4:
token = RefreshToken()
response = token.updateTokens()
newAccessToken = response['access_token']
client.username_pw_set(newAccessToken, password="")
else:
global agent_connected
agent_connected = False
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
print ("MQTT_LISTENER: Subscribing with topic " + TOPIC_TO_SUBSCRIBE)
client.subscribe(TOPIC_TO_SUBSCRIBE)
print("MQTT_LISTENER: Connected with result code " + str(rc))
@ -72,12 +85,28 @@ def on_publish(client, userdata, mid):
# The callback for when a PUBLISH message to the server when door is open or close
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def publish(msg):
global mqttClient
mqttClient.publish(TOPIC_TO_PUBLISH, msg)
if agent_connected:
print '~~~~~~~~~~~~~~~~~~~~~~~~ Publishing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~'
print ('PUBLISHED DATA: ' + msg)
print ('PUBLISHED TOPIC: ' + TOPIC_TO_PUBLISH)
global mqttClient
mqttClient.publish(TOPIC_TO_PUBLISH, msg)
def on_subscribe(client, userdata, mid, granted_qos):
print "Successfully subscribed to " + TOPIC_TO_SUBSCRIBE
def on_disconnect(client, userdata, rc):
global agent_connected
agent_connected = False
print ("Agent disconnected from broker")
print("Obtaining new access token")
token = RefreshToken()
response = token.updateTokens()
newAccessToken = response['access_token']
client.username_pw_set(newAccessToken, password="")
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# The Main method of the server script
# This method is invoked from RaspberryStats.py on a new thread
@ -106,6 +135,7 @@ def main():
mqttClient.on_message = on_message
mqttClient.on_publish = on_publish
mqttClient.on_subscribe = on_subscribe
mqttClient.on_disconnect = on_disconnect
mqttClient.username_pw_set(iotUtils.AUTH_TOKEN, password = "")
while True:
@ -132,4 +162,3 @@ def main():
if __name__ == '__main__':
iotUtils.setUpGPIOPins()
main()

@ -0,0 +1,53 @@
import json
import urllib
import iotUtils
import requests
applicationKey = None
refreshToken = None
filename = "deviceConfig.properties"
class RefreshToken():
def post(self, url, payload, appKey):
headers = { 'Authorization' : 'Basic ' + appKey, 'Content-Type' : 'application/x-www-form-urlencoded' }
baseUrl = iotUtils.HTTP_EP + url
response = requests.post(baseUrl, params=payload, headers=headers);
return response
def read_server_conf(self):
with open(filename, 'r') as outfile:
conf_file = outfile.readlines()
return conf_file
def updateFile(self, response):
newRefreshToken = response['refresh_token']
newAccessToken = response['access_token']
with open(filename, 'r+') as f:
lines = f.readlines()
f.seek(0)
f.truncate()
for line in lines:
if line.__contains__("auth-token="):
line = "auth-token=" + newAccessToken + "\n"
if line.__contains__("refresh-token="):
line = "refresh-token=" + newRefreshToken + "\n"
f.write(line)
def updateTokens(self,):
global applicationKey
global refreshToken
refreshToken = iotUtils.REFRESH_TOKEN
applicationKey = iotUtils.APPLICATION_KEY
params = urllib.urlencode({"grant_type": "refresh_token", "refresh_token": refreshToken,
"scope": "Enroll device"})
data = self.post("/token", params, applicationKey)
response = json.loads(data)
self.updateFile(response)
return response
Loading…
Cancel
Save