Example #1
0
    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
Example #2
0
    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
Example #3
0
    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()
Example #4
0
    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
Example #5
0
    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()
Example #6
0
    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))
Example #7
0
 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
Example #8
0
    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)
Example #9
0
    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()
Example #10
0
    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()
Example #11
0
    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
Example #12
0
    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
Example #13
0
    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)
Example #14
0
    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
Example #15
0
    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
Example #16
0
    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
Example #17
0
    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