component provides pal.control.RestAPI requires net.TCPSocket, data.json.JSONParser parser, data.IntUtil iu, data.StringUtil stringUtil, io.Output out {
char serverIP[]
int serverPort
RestAPI:RestAPI(char ip[], int port)
{
serverIP = ip
serverPort = port
}
String[] readHeaders(TCPSocket socket)
{
String headers[]
char buf[]
char last4[] = new char[4]
while (last4 != "\r\n\r\n")
{
char b[] = socket.recv(1)
buf = new char[](buf, b)
last4[0] = last4[1]
last4[1] = last4[2]
last4[2] = last4[3]
last4[3] = b[0]
}
headers = stringUtil.explode(buf, "\r\n")
return headers
}
char[] getHeaderValue(String headers[], char field[])
{
for (int i = 0; i < headers.arrayLength; i++)
{
String tokens[] = stringUtil.explode(headers[i].string, ":")
if (tokens.arrayLength >= 1 && stringUtil.lowercase(tokens[0].string) == field)
{
int ndx = stringUtil.find(headers[i].string, ":") + 1
return stringUtil.trim(stringUtil.subString(headers[i].string, ndx, headers[i].string.arrayLength - ndx))
}
}
return null
}
char[] get(char resource[])
{
char request[] = "GET $resource HTTP/1.0\r\n\r\n"
TCPSocket s = new TCPSocket()
if (s.connect(serverIP, serverPort))
{
s.send(request)
String headers[] = readHeaders(s)
char returnContent[]
if (getHeaderValue(headers, "content-length") != null)
{
int size = iu.intFromString(getHeaderValue(headers, "content-length"))
returnContent = s.recv(size)
}
s.disconnect()
return returnContent
}
return null
}
char[] post(char resource[], char contentType[], byte content[])
{
char request[] = "POST $resource HTTP/1.0\r\n"
request = new char[](request, "content-type: $contentType\r\n")
request = new char[](request, "content-length: $(content.arrayLength)\r\n")
request = new char[](request, "\r\n")
TCPSocket s = new TCPSocket()
if (s.connect(serverIP, serverPort))
{
s.send(request)
s.send(content)
String headers[] = readHeaders(s)
char returnContent[]
if (getHeaderValue(headers, "content-length") != null)
{
int size = iu.intFromString(getHeaderValue(headers, "content-length"))
returnContent = s.recv(size)
}
s.disconnect()
return returnContent
}
return null
}
//function to get a list of all available configurations of components for the target system
String[] RestAPI:getConfigs()
{
char response[] = get("/meta/get_all_configs")
JSONElement doc = parser.parseDocument(response)
JSONElement arr = parser.getValue(doc, "configs")
String configs[]
for (int i = 0; i < arr.children.arrayLength; i++)
{
configs = new String[](configs, new String(arr.children[i].value))
}
return configs
}
char[] RestAPI:getConfig()
{
char response[] = get("/meta/get_config")
JSONElement doc = parser.parseDocument(response)
response = parser.getValue(doc, "config").value
return response
}
//function to adapt the system to the chosen configuration of components
bool RestAPI:setConfig(char config[])
{
post("/meta/set_config", "text/json", "{\"config\": \"$config\"}")
return true
}
DateTime dateFromString(char str[])
{
DateTime result = new DateTime()
String tokens[] = stringUtil.explode(str, "-: ")
result.year = iu.intFromString(tokens[0].string)
result.month = iu.intFromString(tokens[1].string)
result.day = iu.intFromString(tokens[2].string)
result.hour = iu.intFromString(tokens[3].string)
result.minute = iu.intFromString(tokens[4].string)
result.second = iu.intFromString(tokens[5].string)
return result
}
//function to get the latest perception data
PerceptionData RestAPI:getPerception()
{
char response[] = get("/meta/get_perception")
JSONElement doc = parser.parseDocument(response)
PerceptionData pd = new PerceptionData()
JSONElement metrics = parser.getValue(doc, "metrics")
if (metrics != null)
{
for (int i = 0; i < metrics.children.arrayLength; i++)
{
JSONElement jmetric = metrics.children[i]
Metric metric = new Metric()
metric.name = parser.getValue(jmetric, "name").value
metric.sourceComponent = parser.getValue(jmetric, "source").value
metric.totalValue = iu.intFromString(parser.getValue(jmetric, "value").value)
metric.totalCount = iu.intFromString(parser.getValue(jmetric, "count").value)
metric.preferHigh = parser.getValue(jmetric, "preferHigh").value == "true"
metric.timeFirst = dateFromString(parser.getValue(jmetric, "startTime").value)
metric.timeLast = dateFromString(parser.getValue(jmetric, "endTime").value)
pd.metrics = new Metric[](pd.metrics, metric)
}
}
JSONElement events = parser.getValue(doc, "events")
if (events != null)
{
for (int i = 0; i < events.children.arrayLength; i++)
{
JSONElement jevent = events.children[i]
Event e = new Event()
e.name = parser.getValue(jevent, "name").value
e.sourceComponent = parser.getValue(jevent, "source").value
e.totalValue = iu.intFromString(parser.getValue(jevent, "value").value)
e.totalCount = iu.intFromString(parser.getValue(jevent, "count").value)
e.timeFirst = dateFromString(parser.getValue(jevent, "startTime").value)
e.timeLast = dateFromString(parser.getValue(jevent, "endTime").value)
pd.events = new Event[](pd.events, e)
}
}
JSONElement trace = parser.getValue(doc, "trace")
if (trace != null)
{
for (int i = 0; i < trace.children.arrayLength; i++)
{
JSONElement jtrace = trace.children[i]
Trace t = new Trace()
t.content = parser.getValue(jtrace, "content").value
pd.trace = new Trace[](pd.trace, t)
}
}
return pd
}
bool RestAPI:addComponent(char str[])
{
post("/meta/add_component", "text", str)
return true
}
bool RestAPI:remComponent(char str[])
{
post("/meta/rem_component", "text", str)
return true
}
char[] RestAPI:updComponent(char str[])
{
return post("/meta/upd_component", "text", str)
}
char[] RestAPI:updArch(String intfs[])
{
char content[] = "["
for (int i = 0; i < intfs.arrayLength; i ++)
{
if (i > 0)
content = new char[](content, ",", "\"", intfs[i].string, "\"")
else
content = new char[](content, "\"", intfs[i].string, "\"")
}
content = new char[](content, "]")
return post("/meta/upd_arch", "text/json", content)
}
bool RestAPI:addIntercept(char intf[], char cmp[])
{
post("/meta/add_intercept", "text/json", "{\"interface\": \"$intf\", \"interceptComponent\": \"$cmp\"}")
return true
}
bool RestAPI:remIntercept(char intf[], char cmp[])
{
post("/meta/rem_intercept", "text/json", "{\"interface\": \"$intf\", \"interceptComponent\": \"$cmp\"}")
return true
}
char[] RestAPI:getSystemPath()
{
char response[] = get("/meta/get_system_path")
return response
}
InterceptInfo[] RestAPI:getIntercepts()
{
InterceptInfo result[]
char response[] = get("/meta/get_intercepts")
JSONElement doc = parser.parseDocument(response)
JSONElement lst = parser.getValue(doc, "intercepts")
if (lst.children.arrayLength != 0)
{
result = new InterceptInfo[lst.children.arrayLength]
for (int i = 0; i < lst.children.arrayLength; i++)
{
JSONElement item = lst.children[i]
result[i] = new InterceptInfo(parser.getValue(item, "rule").value, parser.getValue(item, "impl").value)
}
}
return result
}
}