mirror of
https://repository.entgra.net/community/device-mgt-plugins.git
synced 2025-09-16 23:42:15 +00:00
Merge pull request #735 from Savidude/master
Auto renewal of auth token for RaspberryPi agent
This commit is contained in:
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
|
||||
|
||||
@ -181,10 +181,7 @@ def connectAndPushData():
|
||||
currentTime = calendar.timegm(time.gmtime())
|
||||
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:
|
||||
@ -131,5 +161,4 @@ def main():
|
||||
|
||||
if __name__ == '__main__':
|
||||
iotUtils.setUpGPIOPins()
|
||||
main()
|
||||
|
||||
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…
Reference in New Issue
Block a user