HomeForumSourceResearchGuide
Sign in to contribute to source. how it works
Component pal.control.RestAPI by barry
expand copy to clipboardexpand
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)
				}
			}
		
		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
		}

}
Revision history
To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n pal.control.RestAPI -m "reason for update" -u yourUsername
Version 3 by barry
Version 2 by barry
Version 1 (this version) by barry
Notes for this version: Standard Library Initialisation