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)
				}
			}
		
		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)
		}
	
	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 (this version) by barry
Notes for this version: Removes legacy functionality
Version 2 by barry
Version 1 by barry