com.ibm.internal.iotf.devicemgmt.handler.DeviceUpdateRequestHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of watson-iot Show documentation
Show all versions of watson-iot Show documentation
IBM Watson IoT client library to simplify device/gateway/application interactions with the IoT Platform
/**
*****************************************************************************
Copyright (c) 2015-16 IBM Corporation and other Contributors.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Mike Tran - Initial Contribution
Sathiskumar Palaniappan - Added resource model to update based on resource
*****************************************************************************
*
*/
package com.ibm.internal.iotf.devicemgmt.handler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ibm.internal.iotf.devicemgmt.ManagedClient;
import com.ibm.internal.iotf.devicemgmt.DMServerTopic;
import com.ibm.internal.iotf.devicemgmt.ResponseCode;
import com.ibm.iotf.devicemgmt.resource.Resource;
import com.ibm.iotf.util.LoggerUtility;
/**
*
*
Update device attributes
*
Watson IoT Platform can send this request to a device to update values of one or more device attributes.
* Supported update targets are location, metadata, device information and firmware.
* Topic
*
iotdm-1/device/update
*
Message format
*
Request:
*
{
*
"d": {
*
"value": { }
*
},
*
"reqId": "string"
*
}
*
"value" is the new value of the device attribute.
*
It is a complex field matching the device model.
*
Only writeable fields should be updated as a result of this operation.
*
Values can be updated in:
*
* - location (see Update location section for details)
*
- metadata (Optional)
*
- deviceInfo (Optional)
*
- mgmt.firmware (see Firmware update process for details)
*
*
Response:
*
{
*
"rc": number,
*
"message": "string",
*
"d": {
*
"fields": [
*
"string"
*
]
*
},
*
"reqId": "string"
*
}
*
"message" field can be specified if "rc" is not 200.
*
If any field value could not be retrieved,
*
"rc" should be set to 404 (if not found) or 500 (any other reason).
*
"fields" array should contain the name of each field that could not be updated.
*
*/
public class DeviceUpdateRequestHandler extends DMRequestHandler {
private static final String CLASS_NAME = DeviceUpdateRequestHandler.class.getName();
private static final ExecutorService executor = Executors.newCachedThreadPool();
public DeviceUpdateRequestHandler(ManagedClient dmClient) {
setDMClient(dmClient);
}
/**
* Returns the update topic
*/
@Override
protected String getTopic() {
DMServerTopic topic = this.getDMClient().getDMServerTopic();
return topic.getDeviceUpdateTopic();
}
/**
* This method handles all the update requests from IBM Watson IoT Platform
*/
@Override
public void handleRequest(JsonObject jsonRequest) {
final String METHOD = "handleRequest";
List fireRequiredResources = new ArrayList();
JsonArray fields;
ResponseCode rc = ResponseCode.DM_UPDATE_SUCCESS;
JsonObject response = new JsonObject();
JsonObject d = (JsonObject)jsonRequest.get("d");
if (d != null) {
fields = (JsonArray)d.get("fields");
if (fields != null) {
/**
* update the fields in actual device object
*/
JsonArray resFields = new JsonArray();
for (int i=0; i < fields.size(); i++) {
JsonObject obj = (JsonObject)fields.get(i);
if (obj.get("field") != null) {
String key = obj.get("field").getAsString();
JsonObject value = (JsonObject)obj.get("value");
boolean success = false;
try {
Resource resource = getDMClient().getDeviceData().getResource(key);
if(resource != null) {
success = updateField(resource, value);
fireRequiredResources.add(resource);
}
} catch(Exception e) {
LoggerUtility.log(Level.SEVERE, CLASS_NAME, METHOD,
"Exception in updating field "+key +
" value "+value, e);
if(e.getMessage() != null)
response.add("message", new JsonPrimitive(e.getMessage()));
}
if(success == false) {
resFields.add(new JsonPrimitive(key));
rc = ResponseCode.DM_NOT_FOUND;
}
}
}
if(resFields.size() != 0) {
JsonObject json = new JsonObject();
json.add("fields", resFields);
response.add("d", json);
}
}
}
response.add("rc", new JsonPrimitive(rc.getCode()) );
response.add("reqId", jsonRequest.get("reqId"));
respond(response);
// Lets fire the property change event now - this will notify the
// device code if they are listening to
Task task = this.new Task(fireRequiredResources);
executor.execute(task);
}
/**
* Update resource with new value
*
* @param resource resource to be updated
* @param value - the new value
* @return - true if the update is successful, false if not
*/
private boolean updateField(Resource resource, JsonObject value) {
if(resource != null) {
// Update the properties but do not fire the change event
resource.update(value, false);
return true;
}
return false;
}
/**
* A task that fires the modified event on all the
* resources that are updated
*/
private class Task implements Runnable {
private List fireRequiredResources;
private Task(List fireRequiredResources) {
this.fireRequiredResources = fireRequiredResources;
}
@Override
public void run() {
for(int i = 0; i < fireRequiredResources.size(); i++) {
Resource resource = fireRequiredResources.get(i);
resource.notifyExternalListeners();
}
}
}
}