def _validate_payload(self, payload: dict, template: central_models.TemplateV1, is_component: bool): name_miss = [] for telemetry_name, telemetry in payload.items(): schema = template.get_schema( name=telemetry_name, identifier=self.component_name, is_component=is_component, ) if not schema: name_miss.append(telemetry_name) else: self._process_telemetry(telemetry_name, schema, telemetry) if name_miss: if is_component: details = strings.invalid_field_name_component_mismatch_template( name_miss, template.component_schema_names) else: details = strings.invalid_field_name_mismatch_template( name_miss, template.schema_names, ) self._add_central_issue(severity=Severity.warning, details=details)
def test_parse_message_bad_field_name_should_fail(self): # setup device_template = self._get_template() properties = MessageProperties(content_encoding=self.encoding, content_type=self.content_type) message = Message( body=json.dumps(self.bad_field_name).encode(), properties=properties, annotations={ common_parser.DEVICE_ID_IDENTIFIER: self.device_id.encode() }, ) args = CommonParserArguments() parser = self._create_parser(device_template=device_template, message=message, args=args) # act parsed_msg = parser.parse_message() # verify # parsing should attempt to place raw payload into result even if parsing fails assert parsed_msg["event"]["payload"] == self.bad_field_name # field name contains '-' character error expected_details_1 = strings.invalid_field_name( list(self.bad_field_name.keys())) _validate_issues(parser, Severity.error, 2, 1, [expected_details_1]) # field name not present in template warning expected_details_2 = strings.invalid_field_name_mismatch_template( list(self.bad_field_name.keys()), device_template.schema_names) _validate_issues(parser, Severity.warning, 2, 1, [expected_details_2])
def _validate_payload_against_entities(self, payload: dict, name, minimum_severity): name_miss = [] issues_handler = IssueHandler() if not self._is_component(payload): # update is not part of a component check under interfaces schema = self._template.get_schema(name=name) if not schema: name_miss.append(name) details = strings.invalid_field_name_mismatch_template( name_miss, self._template.schema_names) interfaces_with_specified_property = self._template._get_interface_list_property( name) if len(interfaces_with_specified_property) > 1: details = strings.duplicate_property_name( name, interfaces_with_specified_property) issues_handler.add_central_issue( severity=Severity.warning, details=details, message=None, device_id=self._device_id, template_id=self._template.id, ) else: # Property update is part of a component perform additional validations under component list. component_property_updates = [ property_name for property_name in payload if property_name != PNP_DTDLV2_COMPONENT_MARKER ] for property_name in component_property_updates: schema = self._template.get_schema(name=property_name, identifier=name, is_component=True) if not schema: name_miss.append(property_name) details = strings.invalid_field_name_component_mismatch_template( name_miss, self._template.component_schema_names) if name_miss: issues_handler.add_central_issue( severity=Severity.warning, details=details, message=None, device_id=self._device_id, template_id=self._template.id, ) return issues_handler.get_issues_with_minimum_severity( minimum_severity)
def _validate_payload_against_interfaces(self, payload: dict, name, minimum_severity): name_miss = [] issues_handler = IssueHandler() interface_name = name.replace(CENTRAL_PNP_INTERFACE_PREFIX, "") if self._is_interface(interface_name): # if the payload is an interface then iterate thru the properties under the interface for property_name in payload: schema = self._template.get_schema( name=property_name, interface_name=interface_name) if not schema: name_miss.append(property_name) else: # if the payload is a property then process the payload as a single unit. schema = self._template.get_schema(name=name) if not schema: name_miss.append(name) interfaces_with_specified_property = self._template._get_interface_list_property( name) if len(interfaces_with_specified_property) > 1: details = strings.duplicate_property_name( name, interfaces_with_specified_property) issues_handler.add_central_issue( severity=Severity.warning, details=details, message=None, device_id=self._device_id, template_id=self._template.id, ) if name_miss: details = strings.invalid_field_name_mismatch_template( name_miss, self._template.schema_names) issues_handler.add_central_issue( severity=Severity.warning, details=details, message=None, device_id=self._device_id, template_id=self._template.id, ) return issues_handler.get_issues_with_minimum_severity( minimum_severity)
def _validate_payload_against_interfaces( self, payload: dict, template: Template, ): name_miss = [] for telemetry_name, telemetry in payload.items(): schema = template.get_schema(name=telemetry_name, interface_name=self.interface_name) if not schema: name_miss.append(telemetry_name) else: self._process_telemetry(telemetry_name, schema, telemetry) if name_miss: details = strings.invalid_field_name_mismatch_template( name_miss, template.schema_names) self._add_central_issue(severity=Severity.warning, details=details)
def xtest_validate_against_template_should_fail(self): # setup device_template = self._get_template() properties = MessageProperties(content_encoding=self.encoding, content_type=self.content_type) message = Message( body=json.dumps(self.bad_dcm_payload).encode(), properties=properties, annotations={ common_parser.DEVICE_ID_IDENTIFIER: self.device_id.encode() }, application_properties=_encode_app_props(self.app_properties), ) args = CommonParserArguments(properties=["all"]) parser = self._create_parser(device_template=device_template, message=message, args=args) # act parsed_msg = parser.parse_message() schema = parser._extract_template_schemas_from_template( device_template) schema = parser._extract_template_schemas_from_template( device_template) # verify assert parsed_msg["event"]["payload"] == self.bad_dcm_payload assert parsed_msg["event"]["origin"] == self.device_id device_identifier = str(common_parser.DEVICE_ID_IDENTIFIER, "utf8") assert parsed_msg["event"]["annotations"][ device_identifier] == self.device_id properties = parsed_msg["event"]["properties"] assert properties["system"]["content_encoding"] == self.encoding assert properties["system"]["content_type"] == self.content_type assert properties["application"] == self.app_properties expected_details = strings.invalid_field_name_mismatch_template( list(self.bad_dcm_payload.keys()), list(schema.keys())) _validate_issues(parser, Severity.warning, 1, 1, [expected_details])
def _validate_payload_against_schema( self, payload: dict, template_schemas: dict, ): template_schema_names = template_schemas.keys() name_miss = [] for name, value in payload.items(): schema = template_schemas.get(name) if not schema: name_miss.append(name) is_dict = isinstance(schema, dict) if is_dict and not self._validate_types_match(value, schema): expected_type = str(schema.get("schema")) details = strings.invalid_primitive_schema_mismatch_template( name, expected_type, value) self._add_central_issue(severity=Severity.error, details=details) if name_miss: details = strings.invalid_field_name_mismatch_template( name_miss, list(template_schema_names)) self._add_central_issue(severity=Severity.warning, details=details)