def post_node_config(self, server_id, node_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法将处理Forwarder发来的请求(HTTP POST),要求更新某个Node的当前配置。 新的配置以Json格式在HTTP POST的正文中。 方法将在已知的Node列表中寻找node_id符合的Node,并发送请求更新它的配置。 :param basestring server_id: URL中的<server_id>部分。 :param basestring node_id: URL中的<node_id>部分。 """ # 检查URL中的server_id是否和自身的ID相符 if server_id != self.config.server_id: return generate_500("Cannot find server with server_id='%s'" % server_id) # 在自身已知的Server列表里查找URL中给出的目标Node node = self.find_node_by_id(node_id) if node is None: return generate_500("Cannot find node with node_id='%s' from this server" % node_id) # 向那个Node发送请求 request_url = str("http://%s:%d/node/nodeconfig/%s" % (node.addr, node.port, node.id)) try: greq = grequests.post(request_url, data=request.body.read()) response = greq.send() except RequestException as e: return generate_500("Error on sending config to node.", e) # 向Forwarder返回请求的结果 return response.text
def get_sensor_data(self, server_id, node_id, sensor_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法将处理Forwarder发来的请求,要求获得某个传感器的传感器值。 方法将把请求转发给相应的Node,并把获得的响应转发回Forwarder。 目标传感器的值(SensorData)以Json形式在响应中返回。 """ # 检查URL中的server_id是否和自身的ID相符 if server_id != self.config.server_id: return generate_500("Cannot find server with server_id='%s'" % server_id) # 在自身已知的Server列表里查找URL中给出的目标Node node = self.find_node_by_id(node_id) if node is None: return generate_500("Cannot find node with node_id='%s' from this server" % node_id) # 向那个Node发送请求 request_url = str("http://%s:%d/node/sensordata/%s/%s" % (node.addr, node.port, node_id, sensor_id)) try: greq = grequests.get(request_url) response = greq.send() except RequestException as e: return generate_500("Error on sending config to node.", e) # 向Forwarder返回请求的结果 return response.text
def get_sensor_data(self, node_id, sensor_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Server发来的请求,要求返回传感器的当前传感值。 方法将以Json形式返回传感器数据。 如果请求错误或出现异常,返回HTTP 500。 :param basestring node_id: URL中的<node_id>部分。 :param basestring sensor_id: URL中的<sensor_id>部分。 """ # 检查URL中的node_id是否和自身ID匹配 if node_id != self.config.node_id: return generate_500("Cannot find node with node_id='%s'" % node_id) # 在Node自身的sensor_threads中查找sensor_id相符的SensorThread对象 for x in self.sensor_threads: if sensor_id == x.sensor_id: sensor_thread = x break else: return generate_500("Cannot find sensor with sensor_id='%s'" % sensor_id) # 从该SensorThread对象获取传感器数据并返回 return sensor_thread.get_json_dumps_sensor_data()
def get_warning_data(self, node_id, sensor_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Server发来的请求,要求返回某个传感器被过滤列表(filters)过滤后仍保留的警报数据。 如果当前那个传感器的传感器值(SensorData)不符合任何filter的条件,则返回它。 否则,如果那个传感器的值被filters中的filter过滤,则返回空的HTTP 200。 如果请求错误或出现异常,返回HTTP 500。 """ # 检查URL中的node_id是否和自身ID匹配 if node_id != self.config.node_id: return generate_500("Cannot find node with node_id='%s'" % node_id) # 在Node自身的sensor_thread中查找sensor_id相符的SensorThread对象 for x in self.sensor_threads: if sensor_id == x.sensor_id: sensor_thread = x break else: return generate_500("Cannot find sensor with sensor_id='%s'" % node_id) # 从该SensorThread对象读传感器数据(SensorData),并过滤 sensor_data = sensor_thread.get_data() if not self.filter_sensor_data(sensor_data): return sensor_data.get_json_dumps() else: return # 空的HTTP 200
def post_server_config(self, server_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法将处理Forwarder发来的请求(HTTP POST),要求更新Server的当前配置。 方法将试图解析POST正文中的新配置,并试图给Server自身应用这个配置。 如果中途出现错误,将返回HTTP 500错误,并在响应正文中附上错误的信息和产生的异常。 如果没有出现错误,将返回HTTP 200正常响应,并在响应正文中附上更新后的配置,以供检查。 :param basestring server_id: URL中的<server_id>部分。 """ # 检查URL中的server_id是否和自身的ID相符 if server_id != self.config.server_id: return generate_500("Cannot find node with server_id='%s'" % server_id) # 尝试解析POST正文中的ServerConfig try: new_config = parse_server_config_from_string(request.body.read()) except ValueError as e: return generate_500("Error on parsing new config.", e) # 尝试应用新的配置 try: self.apply_config(new_config) except Exception as e: return generate_500("CAUTION: Error on applying new config.", e) # 返回更新后的配置 return self.config.get_json_string()
def server_method(self, request_method, server_id, other_ids=None): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理由客户端发送的、目标为Server的各个请求。 接到请求后,根据请求的目标ServerID在自己已知的Server列表中查找。 如果找到,将请求转发给那个Server。 如果找不到,返回HTTP 500。 :param request_method: URL中的<request_method>部分,是请求的操作类型。 :param server_id: URL中的<server_id>部分,是请求的目标Server的ID。 :param other_ids: URL中的<other_ids:path>部分,即URL结尾的其他所有部分。将原样转发给目标Server。 """ # 1. 在自身已知的Server列表中查找URL中给出的目标Server server = self.find_server_by_id(server_id) if server is None: return generate_500("Can't find server with server_id=%s in this forwarder." % server_id) # 2. 根据请求URL构造要转发的新URL if other_ids is None: request_url = "http://%s:%d/server/%s/%s" % (server.addr, server.port, request_method, server_id) else: request_url = "http://%s:%d/server/%s/%s/%s" % (server.addr, server.port, request_method, server_id, other_ids) # 3. 转发新的请求给Server try: if request.method == "POST": greq = grequests.post(request_url, data=request.body.read()) else: greq = grequests.get(request_url) response = greq.send() except RequestException as e: return generate_500("Error on curling to server.", e) # 4. 将从Server获得的响应转发回客户端,包括错误 http_code = response.status_code if http_code == 500: return generate_500("Curling to server get 500. Response: %s", response.text) elif http_code == 200: return response.text else: return generate_500("Got unknown HTTP code: %d response: %s" % (http_code, response.text))
def post_sensor_data(self): """ 处理POST /server/sensordata,即Node主动发送的传感器值。 由于需求变更,本方法现在没有作用。 参见Git commit记录:699b6bc7aefe64eab56f5d9727ec341e001d0e4a """ request_url = str("http://%s:%d/forwarder/sensordata" % (self.config.forwarder_addr, self.config.forwarder_port)) try: greq = grequests.post(request_url, data=request.body.read()) response = greq.send() except RequestException as e: return generate_500("Error on send sensordata to forwarder.", e) return # HTTP 200
def get_server_config(self, server_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Forwarder发来的请求,要求返回Server的当前配置。 方法将在HTTP GET的响应(HTTP 200)中返回Json格式的、本Server的配置。 :param basestring server_id: URL中的<server_id>部分 """ # 检查URL中的server_id是否和自身的ID相符,如不符则返回HTTP 500 if server_id == self.config.server_id: return self.config.get_json_string() else: return generate_500("Cannot find server with server_id='%s'" % server_id)
def post_forwarder_config(self): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法将处理客户端发来的请求(HTTP POST),要求更新Forwarder的当前配置。 方法将试图解析POST正文中的新配置,并试图给Forwarder自身应用这个配置。 如果中途出现错误,将返回HTTP 500错误,并在响应正文中附上错误的信息和产生的异常。 如果没有出现错误,将返回HTTP 200正常响应,并在响应正文中附上更新后的配置,以供检查。 """ # 尝试解析POST正文中的ForwarderConfig try: new_config = parse_forwarder_config_from_string(request.body.read()) except ValueError as e: return generate_500("Error on parsing new config.", e) # 尝试应用新的配置 try: self.apply_config(new_config) except Exception as e: return generate_500("CAUTION: Error on applying new config.", e) # 返回更新后的配置 return self.config.get_json_string()
def get_node_config(self, node_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Server发来的请求,要求返回Node的当前配置。 方法将在HTTP GET的响应(HTTP 200)中返回Json格式的、本Node的配置。 :param basestring node_id: URL中的<node_id>部分。 """ # 检查URL中的node_id是否和自身ID匹配 if node_id != self.config.node_id: return generate_500("Cannot find node with node_id='%s'" % node_id) # 返回当前的配置Json return self.config.get_json_string()
def get_keep_node(self, node_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Node发来的心跳请求。请求的目的是证明Node依然存活,可以连通。 如果某个Node长时间没有发送心跳请求(30s),认为它已经无法连接,它将被从Node列表中删除。 :param node_id: URL中的<node_id>部分,即发送心跳的Node的ID。 """ # 在已知列表里查找这个Node node = self.find_node_by_id(node_id) if node is None: return generate_500("Cannot find node with node_id='%s' from this server" % node_id) # 刷新Node的最后存活时间 self.refresh_node_alive(node_id) return
def get_keep_server(self, server_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理Server发来的心跳请求。请求的目的是证明Server依然存活,可以连通。 如果某个Server长时间没有发送心跳请求(30s),认为它已经无法连接,它将被从Server列表中删除。 :param server_id: URL中的<server_id>部分,即发送心跳的Server的ID。 """ # 在已知列表里查找这个Server server = self.find_server_by_id(server_id) if server is None: return generate_500("Cannot find server with server_id=%s from this forwarder" % server_id) # 刷新Server的最后存活时间 self.refresh_server_alive(server_id) return
def get_known_nodes(self, server_id): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法将处理Forwarder发来的请求,返回Server当前已知的Node列表。 列表将以Json格式返回,返回的内容是NodeInfo的list。 """ # 检查URL中的server_id是否和自身的ID相符 if server_id != self.config.server_id: return generate_500("Cannot find server with server_id='%s'" % server_id) result = [] for n in self.known_nodes: # 调用每个NodeInfo的get_dict方法,将NodeInfo的信息转换为字典,以供返回 result.append(n.get_dict()) return dumps(result)
def post_unreg_server(self): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理由Server发送的解除注册请求(HTTP POST)。 请求的正文包含Server的配置(ServerConfig)。 收到请求后,本Forwarder在已知的Server列表中删除这个Server。 """ # 从请求的POST正文中解析Server的配置(ServerConfig) body = request.body.read() try: server_config = parse_server_config_from_string(body) except ValueError as e: return generate_500("Error on parsing server config.", e) # 从已知Server列表中删除这个Server server_id = server_config.server_id self.remove_known_server(server_id) return
def post_unreg_node(self): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理由Node发送的解除注册请求(HTTP POST)。 请求的正文包含Node的配置(NodeConfig)。 收到请求后,本Server在已知的Node列表中删除这个Node。 """ # 从请求的POST正文中解析Node的配置(NodeConfig) body = request.body.read() try: node_config = parse_node_config_from_string(body) except ValueError as e: return generate_500("Error on parsing node config.", e) # 从已知Node列表中删除这个Node node_id = node_config.node_id self.remove_known_node(node_id) return
def post_reg_node(self): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理由Node发送的注册请求(HTTP POST)。 请求的正文包含Node的配置(NodeConfig)。 收到请求后,本Server在已知的Node列表中添加这个Node。 """ # 从请求的POST正文中解析Node的配置(NodeConfig) body = request.body.read() try: node_config = parse_node_config_from_string(body) except ValueError as e: return generate_500("Error on parsing node config.", e) # 添加Node node_addr = request.environ.get("REMOTE_ADDR") node_port = node_config.node_port node_id = node_config.node_id node_desc = node_config.node_desc self.add_known_node(node_addr, node_port, node_id, node_desc, node_config) return
def post_reg_server(self): """ 处理HTTP URL,参见start_bottle方法的注释。 本方法处理由Server发送的注册请求(HTTP POST)。 请求的正文包含Server的配置(ServerConfig)。 收到请求后,本Forwarder在已知的Server列表中添加这个Server。 """ # 从请求的POST正文中解析Server的配置(ServerConfig) body = request.body.read() try: server_config = parse_server_config_from_string(body) except ValueError as e: return generate_500("Error on parsing server config.", e) # 添加Server server_addr = request.environ.get("REMOTE_ADDR") server_port = server_config.server_port server_id = server_config.server_id server_desc = server_config.server_desc self.add_known_server(server_addr, server_port, server_id, server_desc, server_config) return