コード例 #1
0
ファイル: request_handler.py プロジェクト: qacafe/agent
    def _process_set(self, req_rec, req):
        """Process an incoming Set and generate a SetResp"""
        resp_rec = usp_record.Record()
        resp = usp.Msg()
        path_to_set_dict = {}
        update_obj_result_list = []
        set_failure_param_err_list = []

        # Populate the Response's Header information
        self._populate_resp_header(req_rec, req, resp_rec, resp,
                                   usp.Header.SET_RESP)

        # Validate the Set Request and populate the dictionaries and lists appropriately
        self._validate_set(req, path_to_set_dict, update_obj_result_list,
                           set_failure_param_err_list)

        # Finished with all validation, process the errors or make the updates
        if len(set_failure_param_err_list) > 0:
            usp_err_msg = utils.UspErrMsg(req.header.msg_id, req_rec.from_id,
                                          self._id)
            err_msg = "Invalid Path Found, Allow Partial Updates = False :: Fail the entire Set"
            resp_rec, resp = usp_err_msg.generate_error(9000, err_msg)
            resp.body.error.param_errs.extend(set_failure_param_err_list)
        else:
            # Process the Updates against the database
            for param_path in path_to_set_dict:
                self._db.update(param_path, path_to_set_dict[param_path])

            resp.body.response.set_resp.updated_obj_results.extend(
                update_obj_result_list)

        return resp_rec, resp
コード例 #2
0
ファイル: utils.py プロジェクト: qacafe/agent
 def __init__(self, msg_id, to_id, from_id):
     """Initialize the USP Message Header"""
     self._msg_id = msg_id
     self._to_id = to_id
     self._from_id = from_id
     self._msg = usp.Msg()
     self._rec = usp_record.Record()
コード例 #3
0
ファイル: request_handler.py プロジェクト: qacafe/agent
    def _process_get(self, req_rec, req):
        """Process an incoming Get and generate a GetResp"""
        resp_rec = usp_record.Record()
        resp = usp.Msg()
        path_result_list = []
        self._logger.info("Processing a Get Request...")

        # Populate the Response's Header information
        self._populate_resp_header(req_rec, req, resp_rec, resp,
                                   usp.Header.GET_RESP)

        # Process the Parameter Paths in the Get Request
        for req_path in req.body.request.get.param_paths:
            path_result = usp.GetResp.RequestedPathResult()
            path_result.requested_path = req_path

            try:
                resolved_path_list = []
                partial_path, param_name = self._split_path(req_path)
                self._logger.debug("Split into [%s] and [%s]", partial_path,
                                   param_name)
                affected_path_list = self._get_affected_paths_for_get(
                    partial_path)

                for affected_path in affected_path_list:
                    self._logger.debug("Requested Path [%s] resolved to: %s",
                                       req_path, affected_path)
                    resolved_path_result = usp.GetResp.ResolvedPathResult()
                    resolved_path_result.resolved_path = affected_path

                    if param_name is None:
                        items = self._db.find_params(affected_path)

                        for item in items:
                            param_path = self._diff_paths(affected_path, item)
                            resolved_path_result.result_params[
                                param_path] = str(self._db.get(item))
                    else:
                        param = affected_path + param_name
                        resolved_path_result.result_params[param_name] = str(
                            self._db.get(param))

                    resolved_path_list.append(resolved_path_result)

                path_result.resolved_path_results.extend(resolved_path_list)
            except agent_db.NoSuchPathError:
                self._logger.warning("Invalid Path encountered: %s", req_path)
                path_result.err_code = 11002
                path_result.err_msg = "Invalid Path: " + req_path + " is not a part of the supported data model"

            path_result_list.append(path_result)

        resp.body.response.get_resp.req_path_results.extend(path_result_list)

        return resp_rec, resp
コード例 #4
0
    def generate_notif_msg(self):
        """Generate an appropriate USP Notification"""
        rec = usp_record.Record()
        notif = usp.Msg()
        self._init_notif(rec, notif)

        notif.body.request.notify.event.obj_path = "Device.LocalAgent."
        notif.body.request.notify.event.event_name = "Periodic!"

        rec.no_session_context.payload = notif.SerializeToString()
        return rec, notif
コード例 #5
0
    def generate_notif_msg(self):
        """Generate an appropriate USP Notification"""
        rec = usp_record.Record()
        notif = usp.Msg()
        self._init_notif(rec, notif)

        notif.body.request.notify.value_change.param_path = self._param
        notif.body.request.notify.value_change.param_value = str(self._value)

        rec.no_session_context.payload = notif.SerializeToString()
        return rec, notif
コード例 #6
0
    def wrap_notif_in_record(self, notif_msg):
        """Wrap the Notification USP Message in a USP Record"""
        notif_record = usp_record.Record()

        notif_record.version = "1.0"
        notif_record.to_id = self._to_id
        notif_record.from_id = self._from_id
        notif_record.payload_security = usp_record.Record.PLAINTEXT
        notif_record.no_session_context.payload = notif_msg.SerializeToString()

        return notif_record
コード例 #7
0
    def _handle_usp_record(self, msg_payload):
        """Deserialize the USP Record in the Incoming Request"""
        req_as_record = usp_record.Record()

        # De-Serialize the payload into a USP Record
        req_as_record.ParseFromString(msg_payload)
        self._logger.debug("Incoming payload parsed as a USP Record via Protocol Buffers")

        if self._debug:
            debug_msg = "Incoming USP Record:\n{}".format(req_as_record)
            self._logger.debug("%s", debug_msg)

        return req_as_record
コード例 #8
0
ファイル: request_handler.py プロジェクト: qacafe/agent
    def _process_operation(self, req_rec, req):
        """Process an incoming Operate and generate a OperateResp"""
        resp_rec = usp_record.Record()
        resp = usp.Msg()
        op_result_list = []
        command = req.body.request.operate.command
        product_class = self._db.get("Device.DeviceInfo.ProductClass")
        self._logger.info("Processing an Operate Request...")

        #TODO: This is hard-coded for the Camera, but needs to be dynamic

        # Populate the Response's Header information
        self._populate_resp_header(req_rec, req, resp_rec, resp,
                                   usp.Header.OPERATE_RESP)

        if product_class == "RPi_Camera" or product_class == "RPiZero_Camera":
            # Validate that the Operate.command is supported
            if command == TAKE_PICTURE_CAMERA_OP:
                op_result = usp.OperateResp.OperationResult()
                op_result.executed_command = req.body.request.operate.command
                out_arg_map = op_result.req_output_args.output_args
                camera = self._service_map[product_class]
                param_map = camera.take_picture()
                for param in param_map:
                    out_arg_map[param] = param_map[param]

                op_result_list.append(op_result)
                resp.body.response.operate_resp.operation_results.extend(
                    op_result_list)
            else:
                # Invalid Command - return an Error
                to_id = req_rec.from_id
                err_msg = "Operate Failure: invalid command - {}".format(
                    command)
                usp_err_msg = utils.UspErrMsg(req.header.msg_id, to_id,
                                              self._id)
                resp_rec, resp = usp_err_msg.generate_error(9000, err_msg)
        else:
            # Unknown agent product class - return an Error
            to_id = req_rec.from_id
            err_msg = "Operate Failure: unknown product class - {}".format(
                product_class)
            usp_err_msg = utils.UspErrMsg(req.header.msg_id, to_id, self._id)
            resp_rec, resp = usp_err_msg.generate_error(9000, err_msg)

        return resp_rec, resp
コード例 #9
0
    def generate_notif_msg(self):
        """Generate an appropriate USP Notification"""
        map_as_str = ""
        rec = usp_record.Record()
        notif = usp.Msg()
        first_entry = True
        self._init_notif(rec, notif)

        # TODO: Replace hard-coded list with data model driven list
        boot_param_list = ["Device.DeviceInfo.ManufacturerOUI",
                           "Device.DeviceInfo.ProductClass",
                           "Device.DeviceInfo.SerialNumber",
                           "Device.LocalAgent.X_ARRIS-COM_IPAddr"]

        notif.body.request.notify.event.obj_path = "Device.LocalAgent."
        notif.body.request.notify.event.event_name = "Boot!"
        notif.body.request.notify.event.params["CommandKey"] = ""
        notif.body.request.notify.event.params["Cause"] = "LocalReboot"

        for path in boot_param_list:
            value = self._db.get(path)

            if first_entry:
                first_entry = False
            else:
                map_as_str += ","

            map_as_str += "\"" + path + "\""
            map_as_str += " : "
            if value is not None:
                map_as_str += "\"" + str(value) + "\""
            else:
                map_as_str += "\"\""
                self._logger.warning("Boot Param [%s] is None", path)

        notif.body.request.notify.event.params["BootParameterMap"] = map_as_str

        rec.no_session_context.payload = notif.SerializeToString()
        return rec, notif
コード例 #10
0
ファイル: request_handler.py プロジェクト: qacafe/agent
    def _process_get_supported_protocol(self, req_rec, req):
        """Process an incoming GetSupportedProtocol and generate a GetSupportedProtocolResp"""
        resp_rec = usp_record.Record()
        resp = usp.Msg()
        self._logger.info("Processing a GetSupportedProtocol Request...")

        # Populate the Response's Header information
        self._populate_resp_header(req_rec, req, resp_rec, resp,
                                   usp.Header.GET_SUPPORTED_PROTO_RESP)

        # Process the supported versions in the GetSupportedProtocol Request

        if not ("1.0" in req.body.request.get_supported_protocol.
                controller_supported_protocol_versions.split(",")):
            to_id = req_rec.from_id
            err_msg = "GetSupportedProtocol Failure: incompatible versions"
            usp_err_msg = utils.UspErrMsg(req.header.msg_id, to_id, self._id)
            resp_rec, resp = usp_err_msg.generate_error(9000, err_msg)
            return resp_rec, resp

        resp.body.response.get_supported_protocol_resp.agent_supported_protocol_versions = "1.0"

        return resp_rec, resp
コード例 #11
0
    def _process_request(self, req_as_record, req_as_msg):
        """Processing the incoming Message and return a Response"""
        to_id = req_as_record.from_id
        resp_record = usp_record.Record()
        err_msg = "Message Failure: Request body does not match Header msg_type"
        usp_err_msg = utils.UspErrMsg(req_as_msg.header.msg_id)
        resp_msg = usp_err_msg.generate_error(9000, err_msg)

        if req_as_msg.header.msg_type == usp_msg.Header.GET:
            # Validate that the Request body matches the Header's msg_type
            if req_as_msg.body.request.WhichOneof("req_type") == "get":
                NUM_GET_MSGS_METRIC.inc()
                resp_msg = self._process_get(req_as_msg)
        elif req_as_msg.header.msg_type == usp_msg.Header.SET:
            # Validate that the Request body matches the Header's msg_type
            if req_as_msg.body.request.WhichOneof("req_type") == "set":
                NUM_SET_MSGS_METRIC.inc()
                resp_msg = self._process_set(req_as_msg)
        elif req_as_msg.header.msg_type == usp_msg.Header.OPERATE:
            # Validate that the Request body matches the Header's msg_type
            if req_as_msg.body.request.WhichOneof("req_type") == "operate":
                NUM_OPERATE_MSGS_METRIC.inc()
                resp_msg = self._process_operation(req_as_msg)
        else:
            err_msg = "Invalid USP Message: unknown command"
            resp_msg = usp_err_msg.generate_error(9000, err_msg)
            NUM_UNKNOWN_MSGS_METRIC.inc()

        # Wrap the USP Message response into a USP Record
        resp_record.version = "1.0"
        resp_record.to_id = to_id
        resp_record.from_id = self._id
        resp_record.payload_security = usp_record.Record.PLAINTEXT
        resp_record.no_session_context.payload = resp_msg.SerializeToString()

        return resp_msg, resp_record
コード例 #12
0
ファイル: request_handler.py プロジェクト: qacafe/agent
    def handle_request(self, record_payload):
        """Handle a Request/Response interaction"""
        req_rec = usp_record.Record()

        # De-Serialize the record
        req_rec.ParseFromString(record_payload)

        req = usp.Msg()

        # De-Serialize the payload
        req.ParseFromString(req_rec.no_session_context.payload)

        self._logger.debug("Incoming payload parsed via Protocol Buffers")

        if self._debug:
            print("Incoming Record:\n{}".format(req_rec))
            print("Incoming Request:\n{}".format(req))

        try:
            # Validate the payload before processing it
            self._validate_request(req_rec, req)
            self._logger.info("Received a [%s] Request",
                              req.body.request.WhichOneof("req_type"))

            resp_rec, resp = self._process_request(req_rec, req)
            if self._debug:
                print("Outgoing Record:\n{}".format(resp_rec))
                print("Outgoing Response:\n{}".format(resp))
        except ProtocolValidationError as err:
            err_msg = "USP Message validation failed: {}".format(err)
            self._logger.error("%s", err_msg)
            raise ProtocolViolationError(err_msg)

        resp_rec.no_session_context.payload = resp.SerializeToString()

        return req_rec, req, resp_rec, resp, resp_rec.SerializeToString()