/*
* "Copyright (c) 2010-11 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Author: Jorge Ortiz (jortiz@cs.berkeley.edu)
* IS4 release version 1.0
*/
package local.rest.resources;
import is4.*;
import local.rest.*;
import local.rest.resources.util.*;
import local.db.*;
import local.metadata.context.*;
import local.rest.smap.*;
import net.sf.json.*;
import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.lang.StringBuffer;
import java.net.URL;
import com.sun.net.httpserver.*;
import javax.naming.InvalidNameException;
import java.io.*;
/**
* Any resource with a devices "folder" will have this folder's requests handled by
* the DevicesResource class. DevicesResource handles requests adding devices and their associated
* publishers (streaming data sources).
*/
public class DevicesResource extends Resource{
protected static transient Logger logger = Logger.getLogger(DevicesResource.class.getPackage().getName());
private static MySqlDriver database = (MySqlDriver) DBAbstractionLayer.database;
private static SmapConnector smapConnector = new SmapConnector();
private static MetadataGraph metadataGraph = MetadataGraph.getInstance();
public final int TYPE = ResourceUtils.DEVICES_RSRC;
public DevicesResource(String path) throws Exception, InvalidNameException {
super(path);
if(!path.endsWith("devices") && !path.endsWith("devices/")){
throw new Exception("Invalid path uri suffix; must end with \"devices\"");
}
//set type
database.setRRType(URI, ResourceUtils.translateType(TYPE).toLowerCase());
}
public void put(HttpExchange exchange, String data, boolean internalCall, JSONObject internalResp){
JSONObject response = new JSONObject();
JSONArray errors = new JSONArray();
try {
logger.info("PUT requested");
JSONObject request = (JSONObject) JSONSerializer.toJSON(data);
String op = request.optString("operation");
if(op != null && !op.equals("") && op.equalsIgnoreCase("create_resource")){
super.put(exchange, data, internalCall, internalResp);
return;
}
JSONObject newIs4Uris = new JSONObject();
boolean anySuccess = addNewDevice(request, errors, newIs4Uris);
if(anySuccess)
response.put("status", "success");
else
response.put("status", "fail");
if(errors.size()>0)
response.put("errors", errors);
if(newIs4Uris != null && !newIs4Uris.toString().equals("{}")){
setFormatting(newIs4Uris);
response.put("new_publishers", newIs4Uris);
}
else{
logger.info("newIs4Uris: " + newIs4Uris);
}
sendResponse(exchange, 200, response.toString(), internalCall, internalResp);
} catch(Exception e){
response.put("status", "fail");
errors.add("Invalid JSON Request");
response.put("errors", errors);
sendResponse(exchange, 200, response.toString(), internalCall, internalResp);
}
}
public void post(HttpExchange exchange, String data, boolean internalCall, JSONObject internalResp){
JSONObject response = new JSONObject();
JSONArray errors = new JSONArray();
try{
JSONObject request = null;
if(data != null && data.length()>0)
request = (JSONObject) JSONSerializer.toJSON(data);
if(exchange.getAttribute("query") != null){
super.query(exchange, data, internalCall, internalResp);
} else {
logger.info("POST " + this.URI + "\nDATA: " + data);
try {
JSONObject newIs4Uris = new JSONObject();
boolean anySuccess = addPublishersToDevice(request, errors, newIs4Uris);
if(anySuccess)
response.put("status", "success");
else
response.put("status", "fail");
if(errors.size()>0)
response.put("errors", errors);
if(newIs4Uris != null && !newIs4Uris.toString().equals("{}")){
//update the properties for each publisher
setFormatting(newIs4Uris);
response.put("new_publishers", newIs4Uris);
}
logger.info("POST addPublisherToDevice Response: " + response.toString());
sendResponse(exchange, 200, response.toString(), internalCall, internalResp);
} catch(Exception e){
response.put("status", "fail");
errors.add("Invalid JSON Request");
response.put("errors", errors);
sendResponse(exchange, 200, response.toString(), internalCall, internalResp);
}
}
} catch (Exception e){
response.put("status", "fail");
if(e instanceof JSONException)
errors.add("Invalid JSON");
sendResponse(exchange, 200, response.toString(), internalCall, internalResp);
logger.log(Level.WARNING, "", e);
}
}
private boolean addNewDevice(JSONObject newDevReq, JSONArray errors, JSONObject newIs4Uris){
try{
if(newIs4Uris == null)
newIs4Uris = new JSONObject();
//Request should contain the device name and either
//an array of publisher ids, an array of smap urls,
//a single publisher id or a single smap_url
String devName = newDevReq.getString("deviceName");
if(devNameIsUnique(devName)){
//optJSONArray return null if there is not value
JSONArray pubids = newDevReq.optJSONArray("publishers");
JSONArray smapurls = newDevReq.optJSONArray("smap_urls");
JSONArray aliases = newDevReq.optJSONArray("aliases");
//optString returns "" if there is no value
String pubid = newDevReq.optString("publisher");
String smapurl = newDevReq.optString("smap_url");
String alias = newDevReq.optString("alias");
//add aliases to alias array is alias array is not defined
if(aliases == null && alias.length()>0){
aliases = new JSONArray();
aliases.add(alias);
}
//populate pubids array if the smapurls is undefined and the pubid is defined
if(pubids == null && pubid.length()>0 && smapurls == null){
pubids = new JSONArray();
pubids.add(pubid);
}
//populate smapurls array if the pubids, pubid,
//and smapurls are not defined, but the smapurl is defined
if(pubids == null && pubid.length()==0 && smapurls==null && smapurl.length()>0){
smapurls = new JSONArray();
smapurls.add(smapurl);
}
//handle all cases
if(pubids != null && pubids.size()>0 && checkPubIds(pubids)){
Resource deviceInstanceResource = new Resource(this.URI + devName + "/");
RESTServer.addResource(deviceInstanceResource);
//add to internal graph
metadataGraph.addNode(this.URI + devName + "/");
handlePubIdsReq(devName, pubids, aliases, errors, newIs4Uris);
return true;
} else if(smapurls != null && smapurls.size()>0){
Resource deviceInstanceResource = new Resource(this.URI + devName + "/");
RESTServer.addResource(deviceInstanceResource);
//add to internal graph
metadataGraph.addNode(this.URI + devName + "/");
handleSmapUrlsReq(devName, smapurls, aliases, errors, newIs4Uris);
return true;
} else {
errors.add("No publishers specified for device; Must include publisher id(s) or smap url(s) in request");
}
} else {
errors.add("Device name must be unique");
return false;
}
} catch(Exception e){
if(e instanceof JSONException)
errors.add("Missing field: \"deviceName\"");
}
return false;
}
public static boolean addSmapPublishersToDevice(String is4DeviceUri, JSONObject newDevReq, JSONArray errors, JSONObject newIs4Uris){
try{
if(newIs4Uris == null)
newIs4Uris = new JSONObject();
String devName = newDevReq.getString("deviceName");
if(database.getRRType(is4DeviceUri).equalsIgnoreCase(ResourceUtils.DEVICE_RSRC_STR)) {
logger.info("Adding publishers to: " + devName);
//optJSONArray return null if there is not value
JSONArray smapurls = newDevReq.optJSONArray("smap_urls");
JSONArray aliases = newDevReq.optJSONArray("aliases");
//optString returns "" if there is no value
String smapurl = newDevReq.optString("smap_url");
String alias = newDevReq.optString("alias");
//add aliases to alias array is alias array is not defined
if(aliases == null && alias.length()>0){
aliases = new JSONArray();
aliases.add(alias);
}
//populate smapurls array if the pubids, pubid,
//and smapurls are not defined, but the smapurl is defined
if(smapurls==null && smapurl.length()>0){
smapurls = new JSONArray();
smapurls.add(smapurl);
}
//handle all cases
if(smapurls != null && smapurls.size()>0){
handleSmapUrlsReqStat(is4DeviceUri, devName, smapurls, aliases, errors, newIs4Uris);
return true;
} else {
errors.add("No publishers specified for device; Must include smap url(s) in request");
}
return false;
} else {
errors.add("No device " + is4DeviceUri + " to add publishers into.");
return false;
}
} catch(Exception e){
if(e instanceof JSONException)
errors.add("Missing field: \"deviceName\"");
}
return false;
}
private boolean addPublishersToDevice(JSONObject newDevReq, JSONArray errors, JSONObject newIs4Uris){
try{
if(newIs4Uris == null)
newIs4Uris = new JSONObject();
//Request should contain the device name and either
//an array of publisher ids, an array of smap urls,
//a single publisher id or a single smap_url
String devName = newDevReq.getString("deviceName");
if(!devNameIsUnique(devName)){
logger.info("Adding publishers to: " + devName);
//optJSONArray return null if there is not value
JSONArray pubids = newDevReq.optJSONArray("publishers");
JSONArray smapurls = newDevReq.optJSONArray("smap_urls");
JSONArray aliases = newDevReq.optJSONArray("aliases");
//optString returns "" if there is no value
String pubid = newDevReq.optString("publisher");
String smapurl = newDevReq.optString("smap_url");
String alias = newDevReq.optString("alias");
//add aliases to alias array is alias array is not defined
if(aliases == null && alias.length()>0){
aliases = new JSONArray();
aliases.add(alias);
}
//populate pubids array if the smapurls is undefined and the pubid is defined
if(pubids == null && pubid.length()>0 && smapurls == null){
pubids = new JSONArray();
pubids.add(pubid);
}
//populate smapurls array if the pubids, pubid,
//and smapurls are not defined, but the smapurl is defined
if(pubids == null && pubid.length()==0 && smapurls==null && smapurl.length()>0){
smapurls = new JSONArray();
smapurls.add(smapurl);
}
//handle all cases
if(pubids != null && pubids.size()>0 && checkPubIds(pubids)){
handlePubIdsReq(devName, pubids, aliases, errors, newIs4Uris);
return true;
} else if(smapurls != null && smapurls.size()>0){
handleSmapUrlsReq(devName, smapurls, aliases, errors, newIs4Uris);
return true;
} else {
errors.add("No publishers specified for device; Must include publisher id(s) or smap url(s) in request");
}
} else {
errors.add("No device " + this.URI + devName + " to add publishers into.");
return false;
}
} catch(Exception e){
if(e instanceof JSONException)
errors.add("Missing field: \"deviceName\"");
}
return false;
}
private void handlePubIdsReq(String deviceName, JSONArray pubids, JSONArray aliases, JSONArray errors, JSONObject newIs4Uris){
try {
if(newIs4Uris == null)
newIs4Uris = new JSONObject();
//create device resource with device name
DevicesResource newDevice = new DevicesResource(this.URI + "/" + deviceName + "/");
RESTServer.addResource(newDevice);
//add to internal graph
metadataGraph.addNode(this.URI + "/" + deviceName + "/");
for(int i=0; i<pubids.size(); i++){
UUID thisPubIdUUID = null;
String thisAssocSmapUrl = null;
if((thisPubIdUUID = convertToUUID((String)pubids.get(i))) != null){
if((thisAssocSmapUrl=database.isSmapPublisher(thisPubIdUUID)) != null){
//pubid is valid uuid and has an associated publisher
//NOTES: make the bind exclusive? not yet, but consider
PublisherResource thisPublisher = null;
String pubPath = null;
if (i<aliases.size() && (aliases.get(i) != null)){
pubPath = this.URI + "/" + deviceName + "/" + (String)aliases.get(i) + "/";
} else {
pubPath = this.URI + "/" + deviceName + "/" + thisPubIdUUID.toString() + "/";
}
thisPublisher = new PublisherResource(pubPath, thisPubIdUUID);
RESTServer.addResource(thisPublisher);
//adding to list of newly created Is4 resources
newIs4Uris.put(thisPubIdUUID.toString(), pubPath);
//bind the device to this context
database.addDeviceEntry(deviceName, pubPath, thisPubIdUUID);
//add to internal graph
metadataGraph.addNode(pubPath);
} else {
//Unknown publisher
errors.add("Unknown publisher: " + pubids.get(i));
}
} else {
errors.add("Invalid format: " + (String)pubids.get(i));
}
}
} catch (Exception e){
logger.log(Level.WARNING, "", e);
}
}
/**
* Make sure at least one pubid is valid.
*/
private boolean checkPubIds(JSONArray pubids){
//make sure at least one pubid is valid
String smapurl = null;
for(int i=0; i<pubids.size(); i++){
try {
UUID pubuuid = UUID.fromString((String)pubids.get(i));
if((smapurl = database.isSmapPublisher(pubuuid)) != null)
return true;
} catch(Exception e) {}
}
return false;
}
private boolean devNameIsUnique(String devName){
JSONArray myChildren = database.rrGetChildren(URI);
Vector<String> myChildrenVec = new Vector<String>(myChildren);
for(int i=0; i<myChildrenVec.size(); i++)
System.out.println(i +"\t" + myChildrenVec.elementAt(i));
//System.out.println(!myChildrenVec.contains(devName));
return !myChildrenVec.contains(devName);
}
private static boolean devNameIsUniqueStat(String is4DeviceUri, String devName){
logger.info("is4DeviceUri: " + is4DeviceUri + ", devName: " + devName);
//get the parent of this Device Uri
//String parentUri = is4DeviceUri.substring(0, is4DeviceUri.lastIndexOf(devName));
JSONArray myChildren = database.rrGetChildren(is4DeviceUri);
Vector<String> myChildrenVec = new Vector<String>(myChildren);
for(int i=0; i<myChildrenVec.size(); i++)
System.out.println(i +"\t" + myChildrenVec.elementAt(i));
//System.out.println(!myChildrenVec.contains(devName));
return !myChildrenVec.contains(devName);
}
private void handleSmapUrlsReq(String deviceName, JSONArray smapurls, JSONArray aliases, JSONArray errors, JSONObject newIs4Uris){
try {
JSONObject r = resolveAllSmapUris(deviceName, smapurls, errors);
if(r != null){
logger.info("Resolved all smap urls: " + r.toString());
newIs4Uris.accumulateAll(r);
}
newIs4Uris.accumulateAll(regSmapUrls(deviceName, smapurls, aliases, errors, true, null));
} catch (Exception e){
logger.log(Level.WARNING, "",e);
}
}
private static void handleSmapUrlsReqStat(String is4DevUri, String deviceName, JSONArray smapurls, JSONArray aliases, JSONArray errors, JSONObject newIs4Uris){
try {
JSONObject r = resolveAllSmapUrisStat(is4DevUri, deviceName, smapurls, errors);
if(r != null){
logger.info("Resolved all smap urls: " + r.toString());
newIs4Uris.accumulateAll(r);
}
newIs4Uris.accumulateAll(regSmapUrlsStat(is4DevUri, deviceName, smapurls, aliases, errors, true, null));
} catch (Exception e){
logger.log(Level.WARNING, "",e);
}
}
/**
* Takes each smap url in the JSONArray and creates a publisher for it. The smap urls
* in the array cannot contain stars.
* @param smapUrls Full urls to a smap source
* Example: http://local.cs.berkeley.edu:8005/basement-1/elt-B/data/A/sensor/displacement_pf/reading
*
* @param aliases A human-readable name for the resource that references this publisher
*
* @param errors A json array that is populated with errors, while processing, if there are any
*
* @param installReport true, if you want to install a report for each smapUrl, false otherwise
*
* @return A JSONObject where the attributes are publisher ids for the newly created publishers and the associated
* values are the newly create Is4 Uris.
*/
public static JSONObject regSmapUrlsStat(String is4DeviceUri, String deviceName, JSONArray smapurls, JSONArray aliases, JSONArray errors, boolean installReport,
String bulkReportId){
JSONObject is4PubsAdded = new JSONObject();
try{
for(int i=0; i<smapurls.size(); i++){
String thisAssocSmapUrl = (String) smapurls.get(i);
if(!thisAssocSmapUrl.contains("*")){
UUID thisPubIdUUID = null;
Registrar registrar = Registrar.registrarInstance();
if((thisPubIdUUID=database.isPublisher(thisAssocSmapUrl, true)) == null){
//register the publisher
String newPubId = registrar.registerDevice(thisAssocSmapUrl);
try{
thisPubIdUUID = UUID.fromString(newPubId);
} catch(Exception e){
logger.log(Level.WARNING, "", e);
}
}
PublisherResource thisPublisher = null;
String pubPath = null;
String slash = "";
String newAlias = null;
if(!is4DeviceUri.endsWith("/"))
slash = "/";
if (aliases != null && i<aliases.size() && (aliases.get(i) != null)){
//System.out.println("############### i= " + i + "size= " + aliases.size());
newAlias = (String) aliases.get(i);
pubPath = is4DeviceUri + slash + (String)aliases.get(i) + "/";
} else {
//System.out.println("###############Constructing PUB_PATH with pubid:" + thisPubIdUUID.toString());
newAlias = generateNewAlias(is4DeviceUri, thisAssocSmapUrl);
if(newAlias != null){
pubPath = is4DeviceUri + slash + newAlias + "/";
} else {
newAlias = thisPubIdUUID.toString();
pubPath = is4DeviceUri + slash + thisPubIdUUID.toString() + "/";
}
}
logger.info("PubPath: " + pubPath);
if(installReport){
logger.info("Installing Report for publisher: (" + pubPath + ", " +
thisPubIdUUID.toString() + ")");
//Install smap report
String reportId = SmapConnector.installReport(thisAssocSmapUrl, thisPubIdUUID, pubPath);
if(reportId != null){
logger.info("PUB_PATH: " + pubPath);
thisPublisher = new PublisherResource(pubPath, thisPubIdUUID);
RESTServer.addResource(thisPublisher);
//add to JSONObject
is4PubsAdded.put(thisPubIdUUID.toString(), pubPath);
//add to smap publishers table
database.addPublisher(thisPubIdUUID, newAlias, thisAssocSmapUrl, pubPath, reportId);
//bind the device to this context
database.addDeviceEntry(deviceName, pubPath, thisPubIdUUID);
//add to internal graph
metadataGraph.addNode(pubPath);
} else {
//if registration failed, unregister this publisher
registrar.unregisterDevice(thisPubIdUUID.toString());
}
} else {
if(bulkReportId != null) {
logger.info("PUB_PATH: " + pubPath);
thisPublisher = new PublisherResource(pubPath, thisPubIdUUID);
RESTServer.addResource(thisPublisher);
//add to JSONObject
is4PubsAdded.put(thisPubIdUUID.toString(), pubPath);
//add to smap publishers table
database.addBulkPublisher(thisPubIdUUID, newAlias, thisAssocSmapUrl, pubPath, bulkReportId);
//bind the device to this context
database.addDeviceEntry(deviceName, pubPath, thisPubIdUUID);
//add to internal graph
metadataGraph.addNode(pubPath);
} else {
logger.warning("Bulk Report Id is NULL for " + pubPath);
}
}
}
}
} catch (Exception e){
logger.log(Level.WARNING, "", e);
}
return is4PubsAdded;
}
/**
* Takes each smap url in the JSONArray and creates a publisher for it. The smap urls
* in the array cannot contain stars.
* @param smapUrls Full urls to a smap source
* Example: http://local.cs.berkeley.edu:8005/basement-1/elt-B/data/A/sensor/displacement_pf/reading
*
* @param aliases A human-readable name for the resource that references this publisher
*
* @param errors A json array that is populated with errors, while processing, if there are any
*
* @param installReport true, if you want to install a report for each smapUrl, false otherwise
*
* @return A JSONObject where the attributes are publisher ids for the newly created publishers and the associated
* values are the newly create Is4 Uris.
*/
public JSONObject regSmapUrls(String deviceName, JSONArray smapurls, JSONArray aliases, JSONArray errors, boolean installReport,
String bulkReportId){
JSONObject is4PubsAdded = new JSONObject();
try{
for(int i=0; i<smapurls.size(); i++){
String thisAssocSmapUrl = (String) smapurls.get(i);
if(!thisAssocSmapUrl.contains("*")){
UUID thisPubIdUUID = null;
Registrar registrar = Registrar.registrarInstance();
if((thisPubIdUUID=database.isPublisher(thisAssocSmapUrl, true)) == null){
//register the publisher
String newPubId = registrar.registerDevice(thisAssocSmapUrl);
try{
thisPubIdUUID = UUID.fromString(newPubId);
} catch(Exception e){
logger.log(Level.WARNING, "", e);
}
}
PublisherResource thisPublisher = null;
String pubPath = null;
String slash = "";
String newAlias = null;
if(!this.URI.endsWith("/"))
slash = "/";
if (aliases != null && i<aliases.size() && (aliases.get(i) != null)){
//System.out.println("############### i= " + i + "size= " + aliases.size());
newAlias = (String) aliases.get(i);
pubPath = this.URI + slash + deviceName + "/" + (String)aliases.get(i) + "/";
} else {
//System.out.println("###############Constructing PUB_PATH with pubid:" + thisPubIdUUID.toString());
newAlias = generateNewAlias(thisAssocSmapUrl);
if(newAlias != null){
pubPath = this.URI + slash + deviceName + "/" + newAlias + "/";
} else {
newAlias = thisPubIdUUID.toString();
pubPath = this.URI + slash + deviceName + "/" + thisPubIdUUID.toString() + "/";
}
}
logger.info("PubPath: " + pubPath);
if(installReport){
logger.info("Installing Report for publisher: (" + pubPath + ", " +
thisPubIdUUID.toString() + ")");
//Install smap report
String reportId = smapConnector.installReport(thisAssocSmapUrl, thisPubIdUUID, pubPath);
if(reportId != null){
logger.info("PUB_PATH: " + pubPath);
//add to smap publishers table
database.addPublisher(thisPubIdUUID, newAlias, thisAssocSmapUrl, pubPath, reportId);
//create publisher resource
thisPublisher = new PublisherResource(pubPath, thisPubIdUUID);
RESTServer.addResource(thisPublisher);
//add to JSONObject
is4PubsAdded.put(thisPubIdUUID.toString(), pubPath);
//bind the device to this context
database.addDeviceEntry(deviceName, pubPath, thisPubIdUUID);
//add to internal graph
metadataGraph.addNode(pubPath);
} else {
//if registration failed, unregister this publisher
registrar.unregisterDevice(thisPubIdUUID.toString());
}
} else {
if(bulkReportId != null) {
logger.info("PUB_PATH: " + pubPath);
thisPublisher = new PublisherResource(pubPath, thisPubIdUUID);
RESTServer.addResource(thisPublisher);
//add to JSONObject
is4PubsAdded.put(thisPubIdUUID.toString(), pubPath);
//add to smap publishers table
database.addBulkPublisher(thisPubIdUUID, newAlias, thisAssocSmapUrl, pubPath, bulkReportId);
//bind the device to this context
database.addDeviceEntry(deviceName, pubPath, thisPubIdUUID);
//add to internal graph
metadataGraph.addNode(pubPath);
} else {
logger.warning("Bulk Report Id is NULL for " + pubPath);
}
}
}
}
} catch (Exception e){
logger.log(Level.WARNING, "", e);
}
return is4PubsAdded;
}
private static String generateNewAlias(String is4DeviceUri, String smapUrlStr){
String alias = null;
try{
//1. Extract the uri from the url
URL smapURL = new URL(smapUrlStr);
String smapUri = smapURL.getPath();
String testName = "";
String endPath = "";
if(smapUri.contains("data")){
//get the sense-point
String sensePointName = null;
//2. Check if this is a "sensor" resource or a "meter" resource (it should be)
if(smapUri.contains("sensor")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+5, smapUri.indexOf("sensor")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("sensor")+6, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_sensor_";
} else if(smapUri.contains("meter")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+5, smapUri.indexOf("meter")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("meter")+5, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_meter_";
} else if (smapUri.contains("control")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+7, smapUri.indexOf("control")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("control")+7, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_control_";
} else if (smapUri.contains("status")){
} else if(smapUri.contains("reporting")){
} else if(smapUri.contains("context")){
}
}
//extract the channel name
if(!endPath.equals("") && endPath.contains("/")){
StringTokenizer tok = new StringTokenizer(endPath, "/");
String channelName = tok.nextToken();
testName = testName + channelName;
if(devNameIsUniqueStat(is4DeviceUri,testName))
alias = testName;
} else {
int count =0;
String streamName = "stream_" + count;
while(!devNameIsUniqueStat(is4DeviceUri, streamName)){
count +=1;
streamName = "stream_" + count;
}
alias = streamName;
}
//3. If it's either, add a unique integer at the end of sensor/meter string and
// set that as the alias
//4. If it's neither a sensor/meter resource, just give it the pubid as the name
} catch(Exception e){
logger.log(Level.WARNING, "", e);
}
logger.info("New Alias: " + alias);
return alias;
}
private String generateNewAlias(String smapUrlStr){
String alias = null;
try{
//1. Extract the uri from the url
URL smapURL = new URL(smapUrlStr);
String smapUri = smapURL.getPath();
String testName = "";
String endPath = "";
if(smapUri.contains("data")){
//get the sense-point
String sensePointName = null;
//2. Check if this is a "sensor" resource or a "meter" resource (it should be)
if(smapUri.contains("sensor")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+5, smapUri.indexOf("sensor")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("sensor")+6, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_sensor_";
} else if(smapUri.contains("meter")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+5, smapUri.indexOf("meter")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("meter")+5, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_meter_";
} else if (smapUri.contains("control")){
sensePointName = smapUri.substring(smapUri.indexOf("data")+7, smapUri.indexOf("control")-1);
logger.info("Sensepoint: " + sensePointName);
endPath = smapUri.substring(smapUri.indexOf("control")+7, smapUri.length());
logger.info("Endpath: " + endPath);
testName = sensePointName + "_control_";
} else if (smapUri.contains("status")){
} else if(smapUri.contains("reporting")){
} else if(smapUri.contains("context")){
}
}
//extract the channel name
if(!endPath.equals("") && endPath.contains("/")){
StringTokenizer tok = new StringTokenizer(endPath, "/");
String channelName = tok.nextToken();
testName = testName + channelName;
if(devNameIsUnique(testName))
alias = testName;
} else {
int count =0;
String streamName = "stream_" + count;
while(!devNameIsUnique(streamName)){
count +=1;
streamName = "stream_" + count;
}
alias = streamName;
}
//3. If it's either, add a unique integer at the end of sensor/meter string and
// set that as the alias
//4. If it's neither a sensor/meter resource, just give it the pubid as the name
} catch(Exception e){
logger.log(Level.WARNING, "", e);
}
logger.info("New Alias: " + alias);
return alias;
}
/**
* Resolves all the smap urls that contains stars. Updates the input JSONArray by removing
* all the starred urls. These are handled through the "/is4/pub/smap/demux" resource.
* When a bulk smap report is POSTed to this resource it is demultiplexed and tagged according
* to the corresponding publisher.
*/
private static JSONObject resolveAllSmapUrisStat(String is4DeviceUri, String deviceName, JSONArray smapurls, JSONArray errors){
Vector<String> strsToRemove = new Vector<String>(smapurls.size());
Vector<String> starredUrlsVec = new Vector<String>();
Vector<String> muxStreamMsgsVec = new Vector<String>();
Vector<Vector<String>> resolvedUrls = new Vector<Vector<String>>();
int i;
for(i=0; i<smapurls.size(); i++){
String thisSmapUrlStr = (String) smapurls.get(i);
if(thisSmapUrlStr.contains("*")){
strsToRemove.add(thisSmapUrlStr);
try {
String muxStreamMsg = SmapConnector.smapServerGet(thisSmapUrlStr);
URL smapURLObj = new URL(thisSmapUrlStr);
String smapHost = smapURLObj.getHost();
int port = (smapURLObj.getPort()<0)?80:smapURLObj.getPort();
String uriStr = smapURLObj.getPath();
if(muxStreamMsg != null){
JSONObject muxStreamMsgJObj = (JSONObject) JSONSerializer.toJSON(muxStreamMsg);
//populate the starred uri vector and the muxstream vector
starredUrlsVec.add(thisSmapUrlStr);
muxStreamMsgsVec.add(muxStreamMsg);
JSONObject resSmapUris = SmapConnector.resolveSmapUri(uriStr, muxStreamMsgJObj);
Iterator keys = resSmapUris.keys();
Vector<String> theseResVec = new Vector<String>();
while(keys.hasNext()){
String resSmapUrl = "http://" + smapHost + ":" + port + ((String) keys.next());
theseResVec.add(resSmapUrl);
}
resolvedUrls.add(theseResVec);
} else {
errors.add("Could not contact: " + thisSmapUrlStr);
}
}catch(Exception e){
logger.log(Level.WARNING, "",e);
}
}
}
//remove all starred smap urls from inputted array
for(i=0; i<strsToRemove.size(); i++){
smapurls.remove(((String)strsToRemove.elementAt(i)));
}
JSONObject newIs4Uris = new JSONObject();
//then install bulk report for that url
for(i=0; i<starredUrlsVec.size(); i++){
String reportId = SmapConnector.installBulkReport(starredUrlsVec.elementAt(i), muxStreamMsgsVec.elementAt(i));
if(reportId != null) {
Vector<String> resUrls = resolvedUrls.elementAt(i);
//create a publisher for each smap url that the starred url resolved to --
JSONArray uriList = new JSONArray();
JSONArray aliases = new JSONArray();
uriList.addAll(resUrls);
//but do not install reports for them since we already installed a bulk report for all of them.
newIs4Uris = regSmapUrlsStat(is4DeviceUri, deviceName, uriList, aliases, errors, false, reportId);
}
}
return newIs4Uris;
}
/**
* Resolves all the smap urls that contains stars. Updates the input JSONArray by removing
* all the starred urls. These are handled through the "/is4/pub/smap/demux" resource.
* When a bulk smap report is POSTed to this resource it is demultiplexed and tagged according
* to the corresponding publisher.
*/
private JSONObject resolveAllSmapUris(String deviceName, JSONArray smapurls, JSONArray errors){
Vector<String> strsToRemove = new Vector<String>(smapurls.size());
Vector<String> starredUrlsVec = new Vector<String>();
Vector<String> muxStreamMsgsVec = new Vector<String>();
Vector<Vector<String>> resolvedUrls = new Vector<Vector<String>>();
int i;
for(i=0; i<smapurls.size(); i++){
String thisSmapUrlStr = (String) smapurls.get(i);
if(thisSmapUrlStr.contains("*")){
strsToRemove.add(thisSmapUrlStr);
try {
String muxStreamMsg = SmapConnector.smapServerGet(thisSmapUrlStr);
URL smapURLObj = new URL(thisSmapUrlStr);
String smapHost = smapURLObj.getHost();
int port = (smapURLObj.getPort()<0)?80:smapURLObj.getPort();
String uriStr = smapURLObj.getPath();
if(muxStreamMsg != null){
JSONObject muxStreamMsgJObj = (JSONObject) JSONSerializer.toJSON(muxStreamMsg);
//populate the starred uri vector and the muxstream vector
starredUrlsVec.add(thisSmapUrlStr);
muxStreamMsgsVec.add(muxStreamMsg);
JSONObject resSmapUris = SmapConnector.resolveSmapUri(uriStr, muxStreamMsgJObj);
Iterator keys = resSmapUris.keys();
Vector<String> theseResVec = new Vector<String>();
while(keys.hasNext()){
String resSmapUrl = "http://" + smapHost + ":" + port + ((String) keys.next());
theseResVec.add(resSmapUrl);
}
resolvedUrls.add(theseResVec);
} else {
errors.add("Could not contact: " + thisSmapUrlStr);
}
}catch(Exception e){
logger.log(Level.WARNING, "",e);
}
}
}
//remove all starred smap urls from inputted array
for(i=0; i<strsToRemove.size(); i++){
smapurls.remove(((String)strsToRemove.elementAt(i)));
}
JSONObject newIs4Uris = new JSONObject();
//then install bulk report for that url
for(i=0; i<starredUrlsVec.size(); i++){
String reportId = SmapConnector.installBulkReport(starredUrlsVec.elementAt(i), muxStreamMsgsVec.elementAt(i));
if(reportId != null) {
Vector<String> resUrls = resolvedUrls.elementAt(i);
//create a publisher for each smap url that the starred url resolved to --
JSONArray uriList = new JSONArray();
JSONArray aliases = new JSONArray();
uriList.addAll(resUrls);
//but do not install reports for them since we already installed a bulk report for all of them.
newIs4Uris = regSmapUrls(deviceName, uriList, aliases, errors, false, reportId);
}
}
return newIs4Uris;
}
private void setFormatting(JSONObject newIs4Uris){
try{
//update the properties for each publisher
Iterator keys = newIs4Uris.keys();
while(keys.hasNext()){
String thisPubid = (String) keys.next();
UUID thisPubidUUID = UUID.fromString(thisPubid);
String smapUrlStr = database.getSmapUrl(thisPubidUUID);
if(smapUrlStr.contains("reading")){
//replace /reading with /formatting and fetch formatting information
smapUrlStr = smapUrlStr.replace("reading", "formatting");
String formatStr = SmapConnector.smapServerGet(smapUrlStr);
if(formatStr != null && !formatStr.equals("")){
//get current properties and update them in the database
String thisIs4UriStr = newIs4Uris.getString(thisPubid);
JSONObject propsJObj = database.rrGetProperties(thisIs4UriStr);
propsJObj.put("formatting", formatStr);
logger.info("Updating properties for: " + thisIs4UriStr);
//update the properties for this resource in the database
//database.rrPutProperties(thisIs4UriStr, propsJObj);
updateProperties(propsJObj);
}
}
}
}catch(Exception e){
logger.warning("Error updating properties for newly added sMAP publishers");
}
}
private UUID convertToUUID(String pubid){
UUID pubid_uuid = null;
try {
if(pubid != null)
pubid_uuid = UUID.fromString(pubid);
} catch(Exception e){
}
return pubid_uuid;
}
private void removeDevice(JSONObject remDevReq, JSONArray errors){
try{
} catch(Exception e){
}
}
}