From 314bdf9b1971eb366cdb1bc85b5d9cea89576145 Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 18 May 2023 11:58:07 +0100 Subject: [PATCH 01/15] Using xmltodict to generate json --- 103120/examples/request1.json | 92 ++++++++ 103120/utils/validate.py | 94 +++++++++ 103120/utils/xml_to_json.py | 12 ++ 103280/TS_103_280.schema.json | 387 ++++++++++++++++++++++++++++++++++ 4 files changed, 585 insertions(+) create mode 100644 103120/examples/request1.json create mode 100644 103120/utils/validate.py create mode 100644 103120/utils/xml_to_json.py create mode 100644 103280/TS_103_280.schema.json diff --git a/103120/examples/request1.json b/103120/examples/request1.json new file mode 100644 index 00000000..a73501e8 --- /dev/null +++ b/103120/examples/request1.json @@ -0,0 +1,92 @@ +{ + "HI1Message": { + "@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", + "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", + "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", + "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", + "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", + "Header": { + "SenderIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR01" + }, + "ReceiverIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR02" + }, + "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", + "Timestamp": "2015-09-01T12:00:00.000000Z", + "Version": { + "ETSIVersion": "V1.13.1", + "NationalProfileOwner": "XX", + "NationalProfileVersion": "v1.0" + } + }, + "Payload": { + "RequestPayload": { + "ActionRequests": { + "ActionRequest": [ + { + "ActionIdentifier": "0", + "CREATE": { + "HI1Object": { + "@xsi:type": "auth:AuthorisationObject", + "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "auth:AuthorisationReference": "W000001", + "auth:AuthorisationTimespan": { + "auth:StartTime": "2015-09-01T12:00:00Z", + "auth:EndTime": "2015-12-01T12:00:00Z" + } + } + } + }, + { + "ActionIdentifier": "1", + "CREATE": { + "HI1Object": { + "@xsi:type": "task:LITaskObject", + "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "AssociatedObjects": { + "AssociatedObject": "7dbbc880-8750-4d3c-abe7-ea4a17646045" + }, + "task:Reference": "LIID1", + "task:TargetIdentifier": { + "task:TargetIdentifierValues": { + "task:TargetIdentifierValue": { + "task:FormatType": { + "task:FormatOwner": "ETSI", + "task:FormatName": "InternationalE164" + }, + "task:Value": "442079460223" + } + } + }, + "task:DeliveryType": { + "common:Owner": "ETSI", + "common:Name": "TaskDeliveryType", + "common:Value": "IRIandCC" + }, + "task:DeliveryDetails": { + "task:DeliveryDestination": { + "task:DeliveryAddress": { + "task:IPv4Address": "192.0.2.0" + } + } + }, + "task:CSPID": { + "CountryCode": "XX", + "UniqueIdentifier": "RECVER01" + } + } + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/103120/utils/validate.py b/103120/utils/validate.py new file mode 100644 index 00000000..a290ed31 --- /dev/null +++ b/103120/utils/validate.py @@ -0,0 +1,94 @@ +import sys +from jsonschema import validate, RefResolver, Draft202012Validator +import json +from pathlib import Path +import logging +import argparse + + + +# filename = sys.argv[1] + +# def load_json (path): +# with open(path) as f: +# s = json.load(f) +# return s + +# schema_store = {} + +# json_instance = load_json(filename) +# print (json_instance) + +# etsi_schema = load_json('response.schema.json') +# ext_schema = load_json('extended.schema.json') +# ext_ent_schema = load_json("extended_entities.schema.json") +# schema_store = { +# etsi_schema['$id'] : etsi_schema, +# ext_schema['$id'] : ext_schema, +# ext_ent_schema['$id'] : ext_ent_schema +# } + +# resolver = RefResolver(None, referrer=None, store=schema_store) + +# print (etsi_schema) + +# v = Draft202012Validator(ext_schema, resolver=resolver) +# v.validate(json_instance) + +# validate(json_instance, ext_schema) +# print ("OK") + +def handle_uri(u): + print(u) + +def load_json(path : str): + with open(path) as f: + return json.load(f) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-s','--schemadir', action="append", help="Directory containing supporting schema files to use for validation") + parser.add_argument('-v', '--verbose', action="count", help="Verbose logging (can be specified multiple times)") + parser.add_argument('schema', help="Primary schema to validate against") + parser.add_argument('filename', help="JSON instance document to validate") + + args = parser.parse_args() + + match args.verbose: + case v if v and v >= 2: + logging.basicConfig(level=logging.DEBUG) + case 1: + logging.basicConfig(level=logging.INFO) + case _: + logging.basicConfig(level=logging.WARNING) + + logging.debug(f"Arguments: {args}") + + instance_doc = load_json(args.filename) + main_schema = load_json(args.schema) + schema_dict = { main_schema['$id'] : main_schema } + + if args.schemadir: + schema_paths = [] + for d in args.schemadir: + schema_paths += [f for f in Path(d).rglob("*.schema.json")] + logging.info(f"Schema files loaded: {schema_paths}") + + schemas_json = [json.load(p.open()) for p in schema_paths] + schema_dict = schema_dict | { s['$id'] : s for s in schemas_json } + + logging.info(f"Schema IDs loaded: {[k for k in schema_dict.keys()]}") + + logging.debug (f"Instance doc: {instance_doc}") + logging.debug (f"Main schema: {main_schema}") + + resolver = RefResolver(None, + referrer=None, + store=schema_dict) + + v = Draft202012Validator(main_schema, resolver=resolver) + + v.validate(instance_doc) + + logging.info("Done") \ No newline at end of file diff --git a/103120/utils/xml_to_json.py b/103120/utils/xml_to_json.py new file mode 100644 index 00000000..0615a035 --- /dev/null +++ b/103120/utils/xml_to_json.py @@ -0,0 +1,12 @@ +import xmltodict +from pprint import pprint +import json + +with open('../examples/request1.xml') as f: + s = f.read() + +d = xmltodict.parse(s) +pprint (d) + +with open('../examples/request.json', 'w') as f2: + f2.write(json.dumps(d)) \ No newline at end of file diff --git a/103280/TS_103_280.schema.json b/103280/TS_103_280.schema.json new file mode 100644 index 00000000..523a1a51 --- /dev/null +++ b/103280/TS_103_280.schema.json @@ -0,0 +1,387 @@ +{ + "$id" : "http://etsi.org/temp/280", + "$schema" : "https://json-schema.org/draft/2020-12/schema", + "title" : "ETSI TS 103 280 (temp)", + "description" : "A stubbed version of TS 103 280 definitions (need a CR to 280 for this)", + "$defs": { + "ShortString": { + "type": "string", + "maxLength": 255 + }, + "LongString": { + "type": "string", + "maxLength": 65535 + }, + "LIID": { + "type": "string", + "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" + }, + "UTCDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + }, + "UTCMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" + }, + "QualifiedDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "QualifiedMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "InternationalE164": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "IMSI": { + "type": "string", + "pattern": "^[0-9]{6,15}$" + }, + "IMEI": { + "type": "string", + "pattern": "^[0-9]{14}$" + }, + "IMEICheckDigit": { + "type": "string", + "pattern": "^[0-9]{15}$" + }, + "IMEISV": { + "type": "string", + "pattern": "^[0-9]{16}$" + }, + "IPv4Address": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" + }, + "IPv4CIDR": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" + }, + "IPv6Address": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" + }, + "IPv6CIDR": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" + }, + "TCPPort": { + "type": "integer", + "exclusiveMinimum": 1, + "maximum": 65535 + }, + "UDPPort": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "MACAddress": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" + }, + "EmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" + } + ] + }, + "UUID": { + "type": "string", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" + }, + "ISOCountryCode": { + "type": "string", + "pattern": "^[A-Z]{2}$" + }, + "SIPURI": { + "type": "string", + "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "TELURI": { + "type": "string", + "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "WGS84LatitudeDecimal": { + "type": "string", + "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" + }, + "WGS84LongitudeDecimal": { + "type": "string", + "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" + }, + "WGS84LatitudeAngular": { + "type": "string", + "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" + }, + "WGS84LongitudeAngular": { + "type": "string", + "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" + }, + "SUPIIMSI": { + "$ref": "#/$defs/IMSI" + }, + "SUPINAI": { + "$ref": "#/$defs/NAI" + }, + "SUCI": { + "type": "string", + "pattern": "^([a-fA-F0-9]{2})*$" + }, + "PEIIMEI": { + "$ref": "#/$defs/IMEI" + }, + "PEIIMEICheckDigit": { + "$ref": "#/$defs/IMEICheckDigit" + }, + "PEIIMEISV": { + "$ref": "#/$defs/IMEISV" + }, + "GPSIMSISDN": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "GPSINAI": { + "$ref": "#/$defs/NAI" + }, + "NAI": { + "type": "string" + }, + "LDID": { + "type": "string", + "pattern": "^([A-Z]{2}-.+-.+)$" + }, + "InternationalizedEmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^.+@.+$" + } + ] + }, + "EUI64": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" + }, + "CGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" + }, + "ECGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" + }, + "NCGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" + }, + "ICCID": { + "type": "string", + "pattern": "^[0-9]{19,20}$" + }, + "IPAddress": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4Address": { + "$ref": "#/$defs/IPv4Address" + } + }, + "required": [ + "IPv4Address" + ] + }, + { + "type": "object", + "properties": { + "IPv6Address": { + "$ref": "#/$defs/IPv6Address" + } + }, + "required": [ + "IPv6Address" + ] + } + ] + }, + "IPCIDR": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4CIDR": { + "$ref": "#/$defs/IPv4CIDR" + } + }, + "required": [ + "IPv4CIDR" + ] + }, + { + "type": "object", + "properties": { + "IPv6CIDR": { + "$ref": "#/$defs/IPv6CIDR" + } + }, + "required": [ + "IPv6CIDR" + ] + } + ] + }, + "TCPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/TCPPort" + }, + "end": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "UDPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/UDPPort" + }, + "end": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "Port": { + "oneOf": [ + { + "type": "object", + "properties": { + "TCPPort": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "TCPPort" + ] + }, + { + "type": "object", + "properties": { + "UDPPort": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "UDPPort" + ] + } + ] + }, + "PortRange": { + "oneOf": [ + { + "type": "object", + "properties": { + "TCPPortRange": { + "$ref": "#/$defs/TCPPortRange" + } + }, + "required": [ + "TCPPortRange" + ] + }, + { + "type": "object", + "properties": { + "UDPPortRange": { + "$ref": "#/$defs/UDPPortRange" + } + }, + "required": [ + "UDPPortRange" + ] + } + ] + }, + "IPAddressPort": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "port": { + "$ref": "#/$defs/Port" + } + }, + "required": [ + "address", + "port" + ] + }, + "IPAddressPortRange": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "portRange": { + "$ref": "#/$defs/PortRange" + } + }, + "required": [ + "address", + "portRange" + ] + }, + "WGS84CoordinateDecimal": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeDecimal" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeDecimal" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "WGS84CoordinateAngular": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeAngular" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeAngular" + } + }, + "required": [ + "latitude", + "longitude" + ] + } + } +} \ No newline at end of file -- GitLab From fc63aa7835cc3848a26943d85ec6e580b492278a Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 18 May 2023 16:04:08 +0100 Subject: [PATCH 02/15] Getting a bit further --- utils/translate/ChoiceMapping.py | 42 ++++++ utils/translate/ComplexTypeMapping.py | 11 ++ utils/translate/SequenceMapping.py | 80 ++++++++++++ utils/translate/SimpleTypeMapping.py | 18 +++ utils/translate/TypeMapping.py | 70 ++++++++++ utils/translate/XSDNativeSimpleTypeMapping.py | 72 +++++++++++ utils/translate/__init__.py | 64 +++++++++ utils/translate_spec.py | 122 ++++++++++++++++++ utils/ts103120_config.json | 14 ++ utils/validate.py | 94 ++++++++++++++ utils/xml_to_json.py | 42 ++++++ 11 files changed, 629 insertions(+) create mode 100644 utils/translate/ChoiceMapping.py create mode 100644 utils/translate/ComplexTypeMapping.py create mode 100644 utils/translate/SequenceMapping.py create mode 100644 utils/translate/SimpleTypeMapping.py create mode 100644 utils/translate/TypeMapping.py create mode 100644 utils/translate/XSDNativeSimpleTypeMapping.py create mode 100644 utils/translate/__init__.py create mode 100644 utils/translate_spec.py create mode 100644 utils/ts103120_config.json create mode 100644 utils/validate.py create mode 100644 utils/xml_to_json.py diff --git a/utils/translate/ChoiceMapping.py b/utils/translate/ChoiceMapping.py new file mode 100644 index 00000000..fecadf80 --- /dev/null +++ b/utils/translate/ChoiceMapping.py @@ -0,0 +1,42 @@ +import logging + +from xmlschema.validators.simple_types import * +from xmlschema.validators.complex_types import * +from xmlschema.validators.groups import * +from xmlschema.validators.facets import * + +from .TypeMapping import TypeMapping +from .ComplexTypeMapping import ComplexTypeMapping + +log = logging.getLogger() + +class ChoiceMapping(ComplexTypeMapping): + @classmethod + def process_choice(cls, choice: XsdGroup, current_ns : str): + if choice.model != 'choice': + raise Exception(f"Wrong group type: {c.model}") + oneOf = [] + for c in choice.iter_model(): + if not (type(c) is XsdElement): + raise Exception (f"Non-element {c} encountered in choice {choice}") + t = TypeMapping.get_type_from_elem(c, current_ns) + oneOf.append({ + "type" : "object", + "properties" : { + c.local_name : t + }, + "required" : [c.local_name] + }) + return oneOf + + def map(self, xst : BaseXsdType): + log.debug(f"Attempting mapping of {xst} to choice") + j = super().map(xst) + if j is None: + log.debug("Not a complex type, giving up") + return None + content = xst.content + if (content.model != 'choice'): + log.debug("Not a choice, giving up") + return None + return { 'oneOf' : ChoiceMapping.process_choice(content, xst.namespaces[''])} diff --git a/utils/translate/ComplexTypeMapping.py b/utils/translate/ComplexTypeMapping.py new file mode 100644 index 00000000..e1819090 --- /dev/null +++ b/utils/translate/ComplexTypeMapping.py @@ -0,0 +1,11 @@ +from xmlschema.validators.complex_types import * + +from .TypeMapping import TypeMapping + +class ComplexTypeMapping(TypeMapping): + def map(self, xst: BaseXsdType): + if not (type(xst) is XsdComplexType): + return None + return { + "type" : "object" + } diff --git a/utils/translate/SequenceMapping.py b/utils/translate/SequenceMapping.py new file mode 100644 index 00000000..91db5ea9 --- /dev/null +++ b/utils/translate/SequenceMapping.py @@ -0,0 +1,80 @@ +import logging + +from xmlschema.validators.simple_types import * +from xmlschema.validators.complex_types import * +from xmlschema.validators.groups import * +from xmlschema.validators.facets import * + +from .TypeMapping import TypeMapping +from .ChoiceMapping import ChoiceMapping +from .ComplexTypeMapping import ComplexTypeMapping + +log = logging.getLogger() + + +class SequenceMapping(ComplexTypeMapping): + def map(self, xst: BaseXsdType): + log.debug(f"Attempting mapping of {xst} to sequence") + j = super().map(xst) + if j is None: + log.debug("Not a complex type, giving up") + return None + content = xst.content + if (content.model != 'sequence'): + log.debug("Not a sequence, giving up") + return None + mapped_type = { + 'type' : 'object', + 'properties' : {}, + 'required' : [] + } + + # Not going to try and do all of this automatically for now + # Only make insert the xsiType parameter + if (xst.base_type): + # mapped_type['__DESCENDENT_OF__'] = TypeMapping.get_ref_for(xst.base_type, xst.namespaces['']) + mapped_type['properties']['@xsi:type'] = { + "type" : "string", + "enum" : xst.name + } + mapped_type['required'].append('@xsi:type') + # if xst.abstract: + # mapped_type['__ABSTRACT__'] = True + # pass + + inner_choice = None + for c in list(content.iter_model()): + log.debug(f"Processing model item {c}") + if type(c) is XsdElement: + if c.effective_max_occurs != 1: + mapped_type['properties'][c.local_name] = { + "type" : "array", + "items" : TypeMapping.get_type_from_elem(c, xst.namespaces['']) + } + if c.effective_max_occurs: + mapped_type['properties'][c.local_name]['maxItems'] = c.effective_max_occurs + if c.effective_min_occurs > 0: + mapped_type['properties'][c.local_name]['minItems'] = c.effective_min_occurs + else: + mapped_type['properties'][c.local_name] = TypeMapping.get_type_from_elem(c, xst.namespaces['']) + if c.effective_min_occurs == 1: + mapped_type['required'].append(c.local_name) + elif type(c) is XsdGroup: + if inner_choice: + raise Exception (f"Second group '{c.local_name}' encountered in {xst}") + if c.model != "choice": + raise Exception (f"Don't know what to do with inner group {c} in {xst} - not a choice") + inner_choice = ChoiceMapping.process_choice(c, xst.namespaces['']) + elif type(c) is XsdAnyElement: + mapped_type = {} + else: + raise Exception(f"Unknown element type {c}") + if (inner_choice): + return { + 'allOf' : [ + mapped_type, + {'oneOf' : inner_choice} + ] + } + else: + return mapped_type diff --git a/utils/translate/SimpleTypeMapping.py b/utils/translate/SimpleTypeMapping.py new file mode 100644 index 00000000..2e60f9ca --- /dev/null +++ b/utils/translate/SimpleTypeMapping.py @@ -0,0 +1,18 @@ +import logging + +from xmlschema.validators.complex_types import * +from xmlschema.validators.simple_types import XsdAtomicRestriction + +from .TypeMapping import TypeMapping + +log = logging.getLogger() + +class SimpleTypeMapping(TypeMapping): + def map(self, xst: BaseXsdType): + log.debug(f"Attempting mapping of {xst} to simple type") + if not (type(xst) is XsdAtomicRestriction): + log.debug("Type is not an XsdAtomicRestriction, giving up") + return None + return { + "$ref" : xst.base_type.name + } \ No newline at end of file diff --git a/utils/translate/TypeMapping.py b/utils/translate/TypeMapping.py new file mode 100644 index 00000000..b796e66b --- /dev/null +++ b/utils/translate/TypeMapping.py @@ -0,0 +1,70 @@ +import logging +from abc import ABC, abstractmethod + +from xmlschema.validators.simple_types import * +from xmlschema.validators.complex_types import * +from xmlschema.validators.groups import * +from xmlschema.validators.facets import * + +log = logging.getLogger() + +class TypeMapping(ABC): + ns_to_id_map = {} + + XSD_NS = "http://www.w3.org/2001/XMLSchema" + + XSD_TYPE_MAP = { + "string" : { "type" : "string" }, + "normalizedString" : { "type" : "string", "pattern" : "^[^\r\n\t]*$"}, + "dateTime" : { "type" : "string"}, + "token" : { "type" : "string", "pattern" : "^[^\r\n\t]*$"}, + "anyURI" : { "type" : "string" }, + + "integer" : { "type" : "integer"}, + "nonNegativeInteger" : { "type" : "integer", "minimum" : 0}, + "positiveInteger" : { "type" : "integer", "minimum" : 1}, + + "boolean" : { "type" : "boolean" }, + + "hexBinary" : { "type" : "string", "pattern" : "^([a-fA-F0-9]{2})*$"}, + "base64Binary" : { "type" : "string", "pattern" : "^[-A-Za-z0-9+/]*={0,3}$"}, + + "anyType" : {} + } + + @abstractmethod + def map(self, xst : BaseXsdType): + return None + + @classmethod + def extract_namespace(cls, qname: str): + match = re.search(r'^\{([^\{\}]+)\}(([^\{\}]+))$', qname) + if match is None: + return None + return match.group(1) + + @classmethod + def get_ref_for(cls, xsd_type: XsdType, current_ns : str): + ns = cls.extract_namespace(xsd_type.name) + if ns == current_ns: + return { "$ref" : f"#/$defs/{xsd_type.local_name}" } + else: + mapped_id = cls.ns_to_id_map[ns] + return { "$ref" : f"{mapped_id}#/$defs/{xsd_type.local_name}"} + + @classmethod + def get_type_from_elem(cls, elem: XsdElement, current_ns : str): + ns = cls.extract_namespace(elem.type.name) + if (ns == TypeMapping.XSD_NS): + # this should be an XSD primitive type + return dict(TypeMapping.XSD_TYPE_MAP[elem.type.local_name]) + else: + return cls.get_ref_for(elem.type, current_ns) + + + + + + + + diff --git a/utils/translate/XSDNativeSimpleTypeMapping.py b/utils/translate/XSDNativeSimpleTypeMapping.py new file mode 100644 index 00000000..772ac10b --- /dev/null +++ b/utils/translate/XSDNativeSimpleTypeMapping.py @@ -0,0 +1,72 @@ +import logging + +from xmlschema.validators.simple_types import * +from xmlschema.validators.complex_types import * +from xmlschema.validators.groups import * +from xmlschema.validators.facets import * + +from .TypeMapping import TypeMapping +from .SimpleTypeMapping import SimpleTypeMapping + +log = logging.getLogger() + +class XSDNativeSimpleTypeMapping(SimpleTypeMapping): + + def map(self, xst: BaseXsdType): + log.debug(f"Attempting mapping of {xst} to XSD native type") + j = super().map(xst) + if j is None: + log.debug("Not a simple type, giving up") + return None + + mapped_type = TypeMapping.XSD_TYPE_MAP.get(xst.base_type.local_name) + parent_type = None + + if mapped_type is None: + ns = TypeMapping.extract_namespace(xst.base_type.name) + if ns == XSDNativeSimpleTypeMapping.XSD_NS: + print (xst) + print (xst.base_type) + raise Exception (f"No mapping for xs:{xst.base_type.local_name}") + if len(xst.facets) == 0: + mapped_type = TypeMapping.get_ref_for(xst.base_type, xst.namespaces['']) + else: + parent_type = TypeMapping.get_ref_for(xst.base_type, xst.namespaces['']) + mapped_type = TypeMapping.XSD_TYPE_MAP.get(xst.root_type.local_name) + if mapped_type is None: + raise Exception (f"Could not find mapping for root type xs:{xst.root_type.local_name}") + + mapped_type = dict(mapped_type) + + for k, v in xst.facets.items(): + log.debug(f"Mapping facet {v}") + if type(v) is XsdMaxLengthFacet: + mapped_type['maxLength'] = v.value + continue + if type(v) is XsdMinLengthFacet: + mapped_type['minLength'] = v.value + continue + if type(v) is XsdPatternFacets: + if len(v.regexps) > 1: + raise Exception (f"Multiple patterns given in facet {v} of {xst}") + p = v.regexps[0] + if (not p.startswith('^')) and (not p.endswith('$')): + p = f"^{p}$" + mapped_type['pattern'] = p + continue + if type (v) is XsdMinInclusiveFacet: + mapped_type['minimum'] = v.value + continue + if type (v) is XsdMaxInclusiveFacet: + mapped_type['maximum'] = v.value + continue + if type (v) is XsdMinExclusiveFacet: + mapped_type['exclusiveMinimum'] = v.value + continue + if type (v) is XsdMaxExclusiveFacet: + mapped_type['exclusiveMaximum'] = v.value + continue + raise Exception (f"Unhandled facet {v}") + if parent_type: + return { 'allOf' : [parent_type, mapped_type] } + return mapped_type diff --git a/utils/translate/__init__.py b/utils/translate/__init__.py new file mode 100644 index 00000000..983aa205 --- /dev/null +++ b/utils/translate/__init__.py @@ -0,0 +1,64 @@ +import logging + +from pathlib import Path +from xmlschema import * + +from .TypeMapping import * +from .XSDNativeSimpleTypeMapping import XSDNativeSimpleTypeMapping +from .ChoiceMapping import ChoiceMapping +from .SequenceMapping import SequenceMapping + + +log = logging.getLogger() + +mappings = [ + XSDNativeSimpleTypeMapping(), + ChoiceMapping(), + SequenceMapping(), +] + +def translate_schema (schema_path: str, ns_to_id_map: dict, schema_locations = []): + js = { + "$id" : "?", + "$defs" : {} + } + + logging.info(f"Translating schema {schema_path}") + xs = XMLSchema(schema_path, validation='lax', locations=schema_locations) + logging.info(f"Schema namespace: {xs.target_namespace}" ) + + schema_id = ns_to_id_map[xs.target_namespace] + js['$id'] = schema_id + + TypeMapping.ns_to_id_map = ns_to_id_map + + elementList = [] + for elementName, element in xs.elements.items(): + logging.info(f"Processing element {elementName} : {element}") + elementList.append(TypeMapping.get_ref_for(element.type, element.namespaces[''])) + if len(elementList) == 1: + js['$ref'] = elementList[0]['$ref'] + elif len(elementList) > 1: + js['oneOf'] = elementList + + descendent_types = {} + for type_name, xsd_type in xs.types.items(): + logging.info(f"Processing {type_name} : {xsd_type}") + + j = None + for mapping in mappings: + log.debug("\n----------------------------------------") + j = mapping.map(xsd_type) + if j is None: + continue + else: + break + if j is None: + raise Exception(f"Unmapped type {type_name} ({xsd_type})") + js["$defs"][xsd_type.local_name] = j + logging.debug (f"Mapped {type_name} to {j}") + + print (descendent_types) + return js + + diff --git a/utils/translate_spec.py b/utils/translate_spec.py new file mode 100644 index 00000000..8f890934 --- /dev/null +++ b/utils/translate_spec.py @@ -0,0 +1,122 @@ +import json +import os +import logging +from pathlib import Path +import sys + +from xmlschema import * + +from translate import * + +import jsonschema + +logging.basicConfig(level = logging.INFO) + +def build_schema_locations (paths): + schema_locations = [] + for schemaFile in paths: + try: + xs = XMLSchema(schemaFile, validation='skip') + schema_locations.append((xs.target_namespace, str(Path(schemaFile).resolve()))) + logging.debug (" [ {0} -> {1} ]".format(xs.target_namespace, schemaFile)) + except XMLSchemaParseError as ex: + logging.debug (" [ {0} failed to parse: {1} ]".format(schemaFile, ex)) + return schema_locations + +def get_json(filename): + with open(filename) as f: + j = json.load(f) + return j + +def convert_ns_to_id (ns): + if ns.startswith('http://uri.etsi.org'): + c = ns.split("/") + return f"ts_1{c[3]}{'_' + c[7] if len(c) > 7 else ''}_{c[5]}_{c[6]}" + else: + return ns.replace("http://","").replace("/","_") + +def convert_xsd_to_filename (xsd): + f = Path(xsd) + return f.name.replace('.xsd', '.schema.json') + +if __name__ == "__main__": + if len(sys.argv) < 2: + logging.error ("Usage: translate_spec.py path_to_config_file") + exit(-1) + + config = get_json(sys.argv[1]) + + schema_paths = config['schemas'] + logging.info("Bulding schema locations...") + schema_locations = build_schema_locations(schema_paths) + logging.debug(schema_locations) + + # ns_to_id_map = { + # schema[0]: schema[0].split('/')[-1].lower() + ".json" + # for schema in schema_locations if '03120' in schema[0] + # } | { + # 'http://uri.etsi.org/03280/common/2017/07' : 'etsi103280.json', + # 'http://www.w3.org/2000/09/xmldsig#' : 'xmldsig.json', + # } + logging.info("Constructing XSD NS to JSON Schema ID mapping...") + ns_to_id_map = { schema[0] : convert_ns_to_id(schema[0]) for schema in schema_locations} + logging.debug(ns_to_id_map) + + # # js = translate_schema("103280/TS_103_280.xsd", "103120.json") + # # print(json.dumps(js, indent=2)) + + output_path = Path(config['output']) + if not output_path.exists(): + logging.info("Creating output directory") + os.mkdir(str(output_path)) + + logging.info("Translating schemas...") + json_schemas = {} + for schema_tuple in schema_locations: + logging.info(f" Translating {schema_tuple}") + if 'xmldsig' in (schema_tuple[1]): + # TODO - work out what to do here + logging.info(" Skipping XML Dsig...") + continue + js = translate_schema(schema_tuple[1], ns_to_id_map, schema_locations) + if ns_to_id_map[schema_tuple[0]] == 'core.json': + js['$defs']['HI1Message']['properties'].pop('Signature') + js_path = output_path / convert_xsd_to_filename(schema_tuple[1]) + + # TODO - work out how to do this substitution automatically + # and build the graph of acceptable descendent types + if "Core" in schema_tuple[1]: + js["$defs"]['ConcreteHI1Object'] = { + 'oneOf' : [ + {'$ref' : 'ts_103120_Authorisation_2020_09#/$defs/AuthorisationObject'}, + {'$ref' : 'ts_103120_Task_2020_09#/$defs/LITaskObject'}, + {'$ref' : 'ts_103120_Task_2020_09#/$defs/LDTaskObject'}, + {'$ref' : 'ts_103120_Document_2020_09#/$defs/DocumentObject'}, + {'$ref' : 'ts_103120_Notification_2016_02#/$defs/NotificationObject'}, + {'$ref' : 'ts_103120_Delivery_2019_10#/$defs/DeliveryObject'}, + {'$ref' : 'ts_103120_TrafficPolicy_2022_07#/$defs/TrafficPolicyObject'}, + ] + } + + json_string = json.dumps(js, indent=2) + + if "Core" in schema_tuple[1]: + json_string = json_string.replace('"$ref": "#/$defs/HI1Object"', '"$ref": "#/$defs/ConcreteHI1Object"') + + with open(str(js_path), 'w') as f: + f.write(json_string) + json_schemas[js['$id']] = json.loads(json_string) + + # else: + # json_schemas = {} + # json_path = Path('json/') + # for json_file in json_path.glob("*.json"): + # json_schemas[json_file.name] = get_json(json_file) + + # resolver = jsonschema.RefResolver("", "", json_schemas) + + # instance = get_json("120.json") + # schema = json_schemas['core.json'] + # jsonschema.validate(instance, schema, resolver=resolver) + + # print(json.dumps(js, indent=2)) diff --git a/utils/ts103120_config.json b/utils/ts103120_config.json new file mode 100644 index 00000000..08aadb87 --- /dev/null +++ b/utils/ts103120_config.json @@ -0,0 +1,14 @@ +{ + "schemas" : [ "../103120/schema/ts_103120_Authorisation.xsd", + "../103120/schema/ts_103120_Common.xsd", + "../103120/schema/ts_103120_Core.xsd", + "../103120/schema/ts_103120_Delivery.xsd", + "../103120/schema/ts_103120_Document.xsd", + "../103120/schema/ts_103120_Notification.xsd", + "../103120/schema/ts_103120_Task.xsd", + "../103120/schema/ts_103120_TrafficPolicy.xsd", + "../103280/TS_103_280.xsd", + "../testing/deps/xmldsig/xmldsig-core-schema.xsd" + ], + "output" : "../103120/schema/json/" +} \ No newline at end of file diff --git a/utils/validate.py b/utils/validate.py new file mode 100644 index 00000000..a290ed31 --- /dev/null +++ b/utils/validate.py @@ -0,0 +1,94 @@ +import sys +from jsonschema import validate, RefResolver, Draft202012Validator +import json +from pathlib import Path +import logging +import argparse + + + +# filename = sys.argv[1] + +# def load_json (path): +# with open(path) as f: +# s = json.load(f) +# return s + +# schema_store = {} + +# json_instance = load_json(filename) +# print (json_instance) + +# etsi_schema = load_json('response.schema.json') +# ext_schema = load_json('extended.schema.json') +# ext_ent_schema = load_json("extended_entities.schema.json") +# schema_store = { +# etsi_schema['$id'] : etsi_schema, +# ext_schema['$id'] : ext_schema, +# ext_ent_schema['$id'] : ext_ent_schema +# } + +# resolver = RefResolver(None, referrer=None, store=schema_store) + +# print (etsi_schema) + +# v = Draft202012Validator(ext_schema, resolver=resolver) +# v.validate(json_instance) + +# validate(json_instance, ext_schema) +# print ("OK") + +def handle_uri(u): + print(u) + +def load_json(path : str): + with open(path) as f: + return json.load(f) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-s','--schemadir', action="append", help="Directory containing supporting schema files to use for validation") + parser.add_argument('-v', '--verbose', action="count", help="Verbose logging (can be specified multiple times)") + parser.add_argument('schema', help="Primary schema to validate against") + parser.add_argument('filename', help="JSON instance document to validate") + + args = parser.parse_args() + + match args.verbose: + case v if v and v >= 2: + logging.basicConfig(level=logging.DEBUG) + case 1: + logging.basicConfig(level=logging.INFO) + case _: + logging.basicConfig(level=logging.WARNING) + + logging.debug(f"Arguments: {args}") + + instance_doc = load_json(args.filename) + main_schema = load_json(args.schema) + schema_dict = { main_schema['$id'] : main_schema } + + if args.schemadir: + schema_paths = [] + for d in args.schemadir: + schema_paths += [f for f in Path(d).rglob("*.schema.json")] + logging.info(f"Schema files loaded: {schema_paths}") + + schemas_json = [json.load(p.open()) for p in schema_paths] + schema_dict = schema_dict | { s['$id'] : s for s in schemas_json } + + logging.info(f"Schema IDs loaded: {[k for k in schema_dict.keys()]}") + + logging.debug (f"Instance doc: {instance_doc}") + logging.debug (f"Main schema: {main_schema}") + + resolver = RefResolver(None, + referrer=None, + store=schema_dict) + + v = Draft202012Validator(main_schema, resolver=resolver) + + v.validate(instance_doc) + + logging.info("Done") \ No newline at end of file diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py new file mode 100644 index 00000000..2655bd73 --- /dev/null +++ b/utils/xml_to_json.py @@ -0,0 +1,42 @@ +import xmltodict +import sys +from pprint import pprint +import json +from pathlib import Path + + +def extract_prefixes (d): + return { k.split(':')[1]: d[k] for k in d.keys() if k.startswith("@xmlns:") } + +def removePrefixes (o, prefixes): + if not isinstance(o, dict): return + replacements = [] + for k,v in o.items(): + if isinstance(v, dict): + removePrefixes(v, prefixes) + if isinstance(v, list): + for i in v: + removePrefixes(i, prefixes) + if ":" in k: + prefix = k.split(':')[0] + if (prefix) in prefixes: + new_key = k.split(':')[1] + replacements.append( (k, new_key) ) + for r in replacements: + print(r) + o[r[1]] = o.pop(r[0]) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print ("Usage: xml_to_json.py filename") + + p = Path(sys.argv[1]) + s = p.read_text() + print(s) + + d = xmltodict.parse(s)['HI1Message'] + + prefixes = extract_prefixes(d) + removePrefixes(d, prefixes) + + print(d) -- GitLab From 140cfeaa6e59e735a914366e1af196f5ff3e2e4a Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 18 May 2023 16:04:56 +0100 Subject: [PATCH 03/15] Adding new stuff --- 103120/examples/fragment.json | 11 + 103120/examples/fragment.schema.json | 4 + 103120/examples/request1b.json | 43 ++ 103120/examples/request1c.json | 33 + 103120/examples/request1d.json | 47 ++ 103120/schema/json/TS_103_280.schema.json | 389 ++++++++++ .../json/ts_103120_Authorisation.schema.json | 148 ++++ .../schema/json/ts_103120_Common.schema.json | 164 +++++ 103120/schema/json/ts_103120_Core.schema.json | 589 +++++++++++++++ .../json/ts_103120_Delivery.schema.json | 209 ++++++ .../json/ts_103120_Document.schema.json | 148 ++++ .../json/ts_103120_Notification.schema.json | 103 +++ 103120/schema/json/ts_103120_Task.schema.json | 599 +++++++++++++++ .../json/ts_103120_TrafficPolicy.schema.json | 198 +++++ 103120/utils/validate.py | 94 --- 103120/utils/xml_to_json.py | 12 - 103280/TS_103_280.schema.json | 686 +++++++++--------- 17 files changed, 3029 insertions(+), 448 deletions(-) create mode 100644 103120/examples/fragment.json create mode 100644 103120/examples/fragment.schema.json create mode 100644 103120/examples/request1b.json create mode 100644 103120/examples/request1c.json create mode 100644 103120/examples/request1d.json create mode 100644 103120/schema/json/TS_103_280.schema.json create mode 100644 103120/schema/json/ts_103120_Authorisation.schema.json create mode 100644 103120/schema/json/ts_103120_Common.schema.json create mode 100644 103120/schema/json/ts_103120_Core.schema.json create mode 100644 103120/schema/json/ts_103120_Delivery.schema.json create mode 100644 103120/schema/json/ts_103120_Document.schema.json create mode 100644 103120/schema/json/ts_103120_Notification.schema.json create mode 100644 103120/schema/json/ts_103120_Task.schema.json create mode 100644 103120/schema/json/ts_103120_TrafficPolicy.schema.json delete mode 100644 103120/utils/validate.py delete mode 100644 103120/utils/xml_to_json.py diff --git a/103120/examples/fragment.json b/103120/examples/fragment.json new file mode 100644 index 00000000..98a6bfc4 --- /dev/null +++ b/103120/examples/fragment.json @@ -0,0 +1,11 @@ +{ + "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject", + "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", + "CountryCode": "GB", + "OwnerIdentifier": "ACTOR01", + "AuthorisationReference": "W000001", + "AuthorisationTimespan": { + "StartTime": "2015-09-01T12:00:00Z", + "EndTime": "2015-12-01T12:00:00Z" + } +} \ No newline at end of file diff --git a/103120/examples/fragment.schema.json b/103120/examples/fragment.schema.json new file mode 100644 index 00000000..80124bc0 --- /dev/null +++ b/103120/examples/fragment.schema.json @@ -0,0 +1,4 @@ +{ + "$id": "ts_103120_Authorisation_2020_09", + "$ref" : "ts_103120_Authorisation_2020_09#/$defs/AuthorisationObject" +} \ No newline at end of file diff --git a/103120/examples/request1b.json b/103120/examples/request1b.json new file mode 100644 index 00000000..82b1a1e4 --- /dev/null +++ b/103120/examples/request1b.json @@ -0,0 +1,43 @@ +{ + "Header": { + "SenderIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR01" + }, + "ReceiverIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR02" + }, + "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", + "Timestamp": "2015-09-01T12:00:00.000000Z", + "Version": { + "ETSIVersion": "V1.13.1", + "NationalProfileOwner": "XX", + "NationalProfileVersion": "v1.0" + } + }, + "Payload": { + "RequestPayload": { + "ActionRequests": { + "ActionRequest": [ + { + "ActionIdentifier": 0, + "CREATE": { + "HI1Object": { + "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject", + "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "AuthorisationReference": "W000001", + "AuthorisationTimespan": { + "StartTime": "2015-09-01T12:00:00Z", + "EndTime": "2015-12-01T12:00:00Z" + } + } + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/103120/examples/request1c.json b/103120/examples/request1c.json new file mode 100644 index 00000000..645f706c --- /dev/null +++ b/103120/examples/request1c.json @@ -0,0 +1,33 @@ +{ + "Header": { + "SenderIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR01" + }, + "ReceiverIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR02" + }, + "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", + "Timestamp": "2015-09-01T12:00:00.000000Z", + "Version": { + "ETSIVersion": "V1.13.1", + "NationalProfileOwner": "XX", + "NationalProfileVersion": "v1.0" + } + }, + "Payload": { + "RequestPayload": { + "ActionRequests": { + "ActionRequest": [ + { + "ActionIdentifier": 1, + "GET": { + "Identifier" : "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e" + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/103120/examples/request1d.json b/103120/examples/request1d.json new file mode 100644 index 00000000..bf34f7f0 --- /dev/null +++ b/103120/examples/request1d.json @@ -0,0 +1,47 @@ +{ + "Header" : { + "SenderIdentifier" : { + "CountryCode" : "XX", + "UniqueIdentifier" : "ACTOR01" + }, + "ReceiverIdentifier" : { + "CountryCode" : "YY", + "UniqueIdentifier" : "ACTOR02" + }, + "TransactionIdentifier" : "c4a09046-61da-485b-83f2-ca12caebf40b", + "Timestamp" : "2022-06-10T15:50:00.000000Z", + "Version" : { + "ETSIVersion" : "V1.11.2", + "NationalProfileOwner" : "NA", + "NationalProfileVersion" : "NA" + } + }, + "Payload" : { + "ResponsePayload" : { + "ActionResponses" : { + "ActionResponse" : [{ + "ActionIdentifier" : 0, + "CREATEResponse" : { + "Identifier" : "f25dec16-927c-433b-959c-1886182cac58", + "HI1Object" : { + "xsiType" : "{http://uri.etsi.org/03120/common/2020/09/Task}LITaskObject", + "ObjectIdentifier" : "d980e335-d17a-471f-bb40-cddf4457fd6b", + "Reference" : "LIID", + "TargetIdentifier" : { + "TargetIdentifierValues" : { + "TargetIdentifierValue" : [ { + "FormatType" : { + "FormatOwner" : "ETSI", + "FormatName" : "InternationalE164" + }, + "Value" : "447700900123" + } ] + } + } + } + } + }] + } + } + } +} diff --git a/103120/schema/json/TS_103_280.schema.json b/103120/schema/json/TS_103_280.schema.json new file mode 100644 index 00000000..474b3ee7 --- /dev/null +++ b/103120/schema/json/TS_103_280.schema.json @@ -0,0 +1,389 @@ +{ + "$id": "ts_103280_2017_07", + "$defs": { + "ShortString": { + "type": "string", + "maxLength": 255 + }, + "LongString": { + "type": "string", + "maxLength": 65535 + }, + "LIID": { + "type": "string", + "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" + }, + "UTCDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + }, + "UTCMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" + }, + "QualifiedDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "QualifiedMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "InternationalE164": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "IMSI": { + "type": "string", + "pattern": "^[0-9]{6,15}$" + }, + "IMEI": { + "type": "string", + "pattern": "^[0-9]{14}$" + }, + "IMEICheckDigit": { + "type": "string", + "pattern": "^[0-9]{15}$" + }, + "IMEISV": { + "type": "string", + "pattern": "^[0-9]{16}$" + }, + "IPv4Address": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" + }, + "IPv4CIDR": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" + }, + "IPv6Address": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" + }, + "IPv6CIDR": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" + }, + "TCPPort": { + "type": "integer", + "exclusiveMinimum": 1, + "maximum": 65535 + }, + "UDPPort": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "MACAddress": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" + }, + "EmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" + } + ] + }, + "UUID": { + "type": "string", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" + }, + "ISOCountryCode": { + "type": "string", + "pattern": "^[A-Z]{2}$" + }, + "SIPURI": { + "type": "string", + "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "TELURI": { + "type": "string", + "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "WGS84LatitudeDecimal": { + "type": "string", + "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" + }, + "WGS84LongitudeDecimal": { + "type": "string", + "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" + }, + "WGS84LatitudeAngular": { + "type": "string", + "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" + }, + "WGS84LongitudeAngular": { + "type": "string", + "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" + }, + "SUPIIMSI": { + "$ref": "#/$defs/IMSI" + }, + "SUPINAI": { + "$ref": "#/$defs/NAI" + }, + "SUCI": { + "type": "string", + "pattern": "^([a-fA-F0-9]{2})*$" + }, + "PEIIMEI": { + "$ref": "#/$defs/IMEI" + }, + "PEIIMEICheckDigit": { + "$ref": "#/$defs/IMEICheckDigit" + }, + "PEIIMEISV": { + "$ref": "#/$defs/IMEISV" + }, + "GPSIMSISDN": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "GPSINAI": { + "$ref": "#/$defs/NAI" + }, + "NAI": { + "type": "string" + }, + "LDID": { + "type": "string", + "pattern": "^([A-Z]{2}-.+-.+)$" + }, + "InternationalizedEmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^.+@.+$" + } + ] + }, + "EUI64": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" + }, + "CGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" + }, + "ECGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" + }, + "NCGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" + }, + "ICCID": { + "type": "string", + "pattern": "^[0-9]{19,20}$" + }, + "IPProtocol": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "IPAddress": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4Address": { + "$ref": "#/$defs/IPv4Address" + } + }, + "required": [ + "IPv4Address" + ] + }, + { + "type": "object", + "properties": { + "IPv6Address": { + "$ref": "#/$defs/IPv6Address" + } + }, + "required": [ + "IPv6Address" + ] + } + ] + }, + "IPCIDR": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4CIDR": { + "$ref": "#/$defs/IPv4CIDR" + } + }, + "required": [ + "IPv4CIDR" + ] + }, + { + "type": "object", + "properties": { + "IPv6CIDR": { + "$ref": "#/$defs/IPv6CIDR" + } + }, + "required": [ + "IPv6CIDR" + ] + } + ] + }, + "TCPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/TCPPort" + }, + "end": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "UDPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/UDPPort" + }, + "end": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "Port": { + "oneOf": [ + { + "type": "object", + "properties": { + "TCPPort": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "TCPPort" + ] + }, + { + "type": "object", + "properties": { + "UDPPort": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "UDPPort" + ] + } + ] + }, + "PortRange": { + "oneOf": [ + { + "type": "object", + "properties": { + "TCPPortRange": { + "$ref": "#/$defs/TCPPortRange" + } + }, + "required": [ + "TCPPortRange" + ] + }, + { + "type": "object", + "properties": { + "UDPPortRange": { + "$ref": "#/$defs/UDPPortRange" + } + }, + "required": [ + "UDPPortRange" + ] + } + ] + }, + "IPAddressPort": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "port": { + "$ref": "#/$defs/Port" + } + }, + "required": [ + "address", + "port" + ] + }, + "IPAddressPortRange": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "portRange": { + "$ref": "#/$defs/PortRange" + } + }, + "required": [ + "address", + "portRange" + ] + }, + "WGS84CoordinateDecimal": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeDecimal" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeDecimal" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "WGS84CoordinateAngular": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeAngular" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeAngular" + } + }, + "required": [ + "latitude", + "longitude" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Authorisation.schema.json b/103120/schema/json/ts_103120_Authorisation.schema.json new file mode 100644 index 00000000..a6f81629 --- /dev/null +++ b/103120/schema/json/ts_103120_Authorisation.schema.json @@ -0,0 +1,148 @@ +{ + "$id": "ts_103120_Authorisation_2020_09", + "$defs": { + "AuthorisationObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "AuthorisationReference": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AuthorisationLegalType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "AuthorisationPriority": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "AuthorisationStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "AuthorisationDesiredStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "AuthorisationTimespan": { + "$ref": "#/$defs/AuthorisationTimespan" + }, + "AuthorisationCSPID": { + "$ref": "#/$defs/AuthorisationCSPID" + }, + "AuthorisationCreationTimestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "AuthorisationServedTimestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "AuthorisationTerminationTimestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "AuthorisationApprovalDetails": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" + } + }, + "AuthorisationInvalidReason": { + "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" + }, + "AuthorisationFlags": { + "$ref": "#/$defs/AuthorisationFlags" + }, + "AuthorisationManualInformation": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "NationalAuthorisationParameters": { + "$ref": "#/$defs/NationalAuthorisationParameters" + }, + "AuthorisationJurisdiction": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AuthorisationTypeOfCase": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "AuthorisationLegalEntity": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "AuthorisationFlags": { + "type": "object", + "properties": { + "AuthorisationFlag": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + } + }, + "required": [] + }, + "AuthorisationTimespan": { + "type": "object", + "properties": { + "StartTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "EndTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "required": [] + }, + "AuthorisationCSPID": { + "type": "object", + "properties": { + "CSPID": { + "type": "array", + "items": { + "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" + }, + "minItems": 1 + } + }, + "required": [] + }, + "NationalAuthorisationParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Common.schema.json b/103120/schema/json/ts_103120_Common.schema.json new file mode 100644 index 00000000..2149684d --- /dev/null +++ b/103120/schema/json/ts_103120_Common.schema.json @@ -0,0 +1,164 @@ +{ + "$id": "ts_103120_Common_2016_02", + "$defs": { + "ETSIVersion": { + "allOf": [ + { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^V\\d+\\.\\d+\\.\\d+$" + } + ] + }, + "DictionaryEntry": { + "type": "object", + "properties": { + "Owner": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Name": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Value": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [ + "Owner", + "Name", + "Value" + ] + }, + "ApprovalDetails": { + "type": "object", + "properties": { + "ApprovalType": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApprovalDescription": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApprovalReference": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApproverDetails": { + "$ref": "#/$defs/ApproverDetails" + }, + "ApprovalTimestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "ApprovalIsEmergency": { + "type": "boolean" + }, + "ApprovalDigitalSignature": { + "$ref": "#/$defs/ApprovalDigitalSignature" + }, + "ApprovalNationalDetails": { + "$ref": "#/$defs/ApprovalNationalDetails" + } + }, + "required": [] + }, + "ApproverDetails": { + "type": "object", + "properties": { + "ApproverName": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApproverRole": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApproverIdentity": { + "$ref": "#/$defs/ApproverIdentity" + }, + "ApproverContactDetails": { + "type": "array", + "items": { + "$ref": "#/$defs/ApproverContactDetails" + } + } + }, + "required": [] + }, + "ApproverIdentity": { + "oneOf": [ + { + "type": "object", + "properties": { + "NationalApproverIdentity": { + "$ref": "#/$defs/NationalApproverIdentity" + } + }, + "required": [ + "NationalApproverIdentity" + ] + } + ] + }, + "ApproverContactDetails": { + "type": "object", + "properties": { + "ApproverAlternateName": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ApproverEmailAddress": { + "$ref": "ts_103280_2017_07#/$defs/InternationalizedEmailAddress" + }, + "ApproverPhoneNumber": { + "$ref": "ts_103280_2017_07#/$defs/InternationalE164" + } + }, + "required": [] + }, + "NationalApproverIdentity": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "ApprovalDigitalSignature": { + "oneOf": [ + { + "type": "object", + "properties": { + "NationalDigitalSignature": { + "$ref": "#/$defs/NationalDigitalSignature" + } + }, + "required": [ + "NationalDigitalSignature" + ] + } + ] + }, + "ApprovalNationalDetails": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "NationalDigitalSignature": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Core.schema.json b/103120/schema/json/ts_103120_Core.schema.json new file mode 100644 index 00000000..ee2852b8 --- /dev/null +++ b/103120/schema/json/ts_103120_Core.schema.json @@ -0,0 +1,589 @@ +{ + "$id": "ts_103120_Core_2019_10", + "$defs": { + "ObjectIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/UUID" + }, + "HI1Message": { + "type": "object", + "properties": { + "Header": { + "$ref": "#/$defs/MessageHeader" + }, + "Payload": { + "$ref": "#/$defs/MessagePayload" + }, + "Signature": { + "$ref": "www.w3.org_2000_09_xmldsig##/$defs/SignatureType" + } + }, + "required": [ + "Header", + "Payload" + ] + }, + "MessageHeader": { + "type": "object", + "properties": { + "SenderIdentifier": { + "$ref": "#/$defs/EndpointID" + }, + "ReceiverIdentifier": { + "$ref": "#/$defs/EndpointID" + }, + "TransactionIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/UUID" + }, + "Timestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedMicrosecondDateTime" + }, + "Version": { + "$ref": "#/$defs/Version" + } + }, + "required": [ + "SenderIdentifier", + "ReceiverIdentifier", + "TransactionIdentifier", + "Timestamp", + "Version" + ] + }, + "Version": { + "type": "object", + "properties": { + "ETSIVersion": { + "$ref": "ts_103120_Common_2016_02#/$defs/ETSIVersion" + }, + "NationalProfileOwner": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "NationalProfileVersion": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [ + "ETSIVersion", + "NationalProfileOwner", + "NationalProfileVersion" + ] + }, + "EndpointID": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "UniqueIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "CountryCode", + "UniqueIdentifier" + ] + }, + "MessagePayload": { + "oneOf": [ + { + "type": "object", + "properties": { + "RequestPayload": { + "$ref": "#/$defs/RequestPayload" + } + }, + "required": [ + "RequestPayload" + ] + }, + { + "type": "object", + "properties": { + "ResponsePayload": { + "$ref": "#/$defs/ResponsePayload" + } + }, + "required": [ + "ResponsePayload" + ] + } + ] + }, + "RequestPayload": { + "type": "object", + "properties": { + "ActionRequests": { + "$ref": "#/$defs/ActionRequests" + } + }, + "required": [ + "ActionRequests" + ] + }, + "ActionRequests": { + "type": "object", + "properties": { + "ActionRequest": { + "type": "array", + "items": { + "$ref": "#/$defs/ActionRequest" + }, + "minItems": 1 + } + }, + "required": [] + }, + "ResponsePayload": { + "oneOf": [ + { + "type": "object", + "properties": { + "ActionResponses": { + "$ref": "#/$defs/ActionResponses" + } + }, + "required": [ + "ActionResponses" + ] + }, + { + "type": "object", + "properties": { + "ErrorInformation": { + "$ref": "#/$defs/ActionUnsuccesfulInformation" + } + }, + "required": [ + "ErrorInformation" + ] + } + ] + }, + "ActionResponses": { + "type": "object", + "properties": { + "ActionResponse": { + "type": "array", + "items": { + "$ref": "#/$defs/ActionResponse" + }, + "minItems": 1 + } + }, + "required": [] + }, + "ActionRequest": { + "allOf": [ + { + "type": "object", + "properties": { + "ActionIdentifier": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "ActionIdentifier" + ] + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "GET": { + "$ref": "#/$defs/GETRequest" + } + }, + "required": [ + "GET" + ] + }, + { + "type": "object", + "properties": { + "CREATE": { + "$ref": "#/$defs/CREATERequest" + } + }, + "required": [ + "CREATE" + ] + }, + { + "type": "object", + "properties": { + "UPDATE": { + "$ref": "#/$defs/UPDATERequest" + } + }, + "required": [ + "UPDATE" + ] + }, + { + "type": "object", + "properties": { + "LIST": { + "$ref": "#/$defs/LISTRequest" + } + }, + "required": [ + "LIST" + ] + }, + { + "type": "object", + "properties": { + "DELIVER": { + "$ref": "#/$defs/DELIVERRequest" + } + }, + "required": [ + "DELIVER" + ] + } + ] + } + ] + }, + "ActionResponse": { + "allOf": [ + { + "type": "object", + "properties": { + "ActionIdentifier": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "ActionIdentifier" + ] + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "GETResponse": { + "$ref": "#/$defs/GETResponse" + } + }, + "required": [ + "GETResponse" + ] + }, + { + "type": "object", + "properties": { + "CREATEResponse": { + "$ref": "#/$defs/CREATEResponse" + } + }, + "required": [ + "CREATEResponse" + ] + }, + { + "type": "object", + "properties": { + "UPDATEResponse": { + "$ref": "#/$defs/UPDATEResponse" + } + }, + "required": [ + "UPDATEResponse" + ] + }, + { + "type": "object", + "properties": { + "LISTResponse": { + "$ref": "#/$defs/LISTResponse" + } + }, + "required": [ + "LISTResponse" + ] + }, + { + "type": "object", + "properties": { + "ErrorInformation": { + "$ref": "#/$defs/ActionUnsuccesfulInformation" + } + }, + "required": [ + "ErrorInformation" + ] + }, + { + "type": "object", + "properties": { + "DELIVERResponse": { + "$ref": "#/$defs/DELIVERResponse" + } + }, + "required": [ + "DELIVERResponse" + ] + } + ] + } + ] + }, + "GETRequest": { + "type": "object", + "properties": { + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + } + }, + "required": [ + "Identifier" + ] + }, + "GETResponse": { + "type": "object", + "properties": { + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "HI1Object" + ] + }, + "CREATERequest": { + "type": "object", + "properties": { + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "HI1Object" + ] + }, + "CREATEResponse": { + "type": "object", + "properties": { + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + }, + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "Identifier" + ] + }, + "UPDATERequest": { + "type": "object", + "properties": { + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "HI1Object" + ] + }, + "UPDATEResponse": { + "type": "object", + "properties": { + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + }, + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "Identifier" + ] + }, + "LISTRequest": { + "type": "object", + "properties": { + "ObjectType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "required": [] + }, + "LISTResponse": { + "type": "object", + "properties": { + "ListResponseRecord": { + "type": "array", + "items": { + "$ref": "#/$defs/ListResponseRecord" + } + } + }, + "required": [] + }, + "ListResponseRecord": { + "type": "object", + "properties": { + "ObjectType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "required": [ + "ObjectType", + "Identifier", + "Generation" + ] + }, + "ActionUnsuccesfulInformation": { + "type": "object", + "properties": { + "ErrorCode": { + "type": "integer", + "minimum": 0 + }, + "ErrorDescription": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "ErrorCode", + "ErrorDescription" + ] + }, + "DELIVERRequest": { + "type": "object", + "properties": { + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + }, + "HI1Object": { + "$ref": "#/$defs/ConcreteHI1Object" + } + }, + "required": [ + "Identifier", + "HI1Object" + ] + }, + "DELIVERResponse": { + "type": "object", + "properties": { + "Identifier": { + "$ref": "#/$defs/ObjectIdentifier" + } + }, + "required": [ + "Identifier" + ] + }, + "HI1Object": { + "type": "object", + "properties": { + "ObjectIdentifier": { + "$ref": "#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "#/$defs/NationalHandlingParameters" + } + }, + "required": [ + "ObjectIdentifier" + ] + }, + "AssociatedObjects": { + "type": "object", + "properties": { + "AssociatedObject": { + "type": "array", + "items": { + "$ref": "#/$defs/ObjectIdentifier" + } + } + }, + "required": [] + }, + "NationalHandlingParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "ConcreteHI1Object": { + "oneOf": [ + { + "$ref": "ts_103120_Authorisation_2020_09#/$defs/AuthorisationObject" + }, + { + "$ref": "ts_103120_Task_2020_09#/$defs/LITaskObject" + }, + { + "$ref": "ts_103120_Task_2020_09#/$defs/LDTaskObject" + }, + { + "$ref": "ts_103120_Document_2020_09#/$defs/DocumentObject" + }, + { + "$ref": "ts_103120_Notification_2016_02#/$defs/NotificationObject" + }, + { + "$ref": "ts_103120_Delivery_2019_10#/$defs/DeliveryObject" + }, + { + "$ref": "ts_103120_TrafficPolicy_2022_07#/$defs/TrafficPolicyObject" + } + ] + } + }, + "$ref": "#/$defs/HI1Message" +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Delivery.schema.json b/103120/schema/json/ts_103120_Delivery.schema.json new file mode 100644 index 00000000..07ca697f --- /dev/null +++ b/103120/schema/json/ts_103120_Delivery.schema.json @@ -0,0 +1,209 @@ +{ + "$id": "ts_103120_Delivery_2019_10", + "$defs": { + "DeliveryObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2019/10/Delivery}DeliveryObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "Reference": { + "$ref": "#/$defs/Reference" + }, + "DeliveryID": { + "$ref": "ts_103280_2017_07#/$defs/UUID" + }, + "SequenceNumber": { + "type": "integer", + "minimum": 0 + }, + "LastSequence": { + "type": "boolean" + }, + "Manifest": { + "$ref": "#/$defs/Manifest" + }, + "Delivery": { + "$ref": "#/$defs/Delivery" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "Reference": { + "oneOf": [ + { + "type": "object", + "properties": { + "LDID": { + "$ref": "ts_103280_2017_07#/$defs/LDID" + } + }, + "required": [ + "LDID" + ] + }, + { + "type": "object", + "properties": { + "LIID": { + "$ref": "ts_103280_2017_07#/$defs/LIID" + } + }, + "required": [ + "LIID" + ] + } + ] + }, + "Manifest": { + "oneOf": [ + { + "type": "object", + "properties": { + "Specification": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + }, + "required": [ + "Specification" + ] + }, + { + "type": "object", + "properties": { + "ExternalSchema": { + "$ref": "#/$defs/ExternalSchema" + } + }, + "required": [ + "ExternalSchema" + ] + } + ] + }, + "ExternalSchema": { + "type": "object", + "properties": { + "ManifestID": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "ManifestContents": { + "$ref": "#/$defs/ManifestContents" + } + }, + "required": [] + }, + "ManifestContents": { + "oneOf": [ + { + "type": "object", + "properties": { + "BinaryData": { + "$ref": "#/$defs/EmbeddedBinaryData" + } + }, + "required": [ + "BinaryData" + ] + }, + { + "type": "object", + "properties": { + "XMLSchema": { + "$ref": "#/$defs/SchemaContent" + } + }, + "required": [ + "XMLSchema" + ] + } + ] + }, + "SchemaContent": { + "type": "object", + "properties": { + "schema": {} + }, + "required": [ + "schema" + ] + }, + "Delivery": { + "oneOf": [ + { + "type": "object", + "properties": { + "BinaryData": { + "$ref": "#/$defs/EmbeddedBinaryData" + } + }, + "required": [ + "BinaryData" + ] + }, + { + "type": "object", + "properties": { + "XMLData": { + "$ref": "#/$defs/EmbeddedXMLData" + } + }, + "required": [ + "XMLData" + ] + } + ] + }, + "EmbeddedBinaryData": { + "type": "object", + "properties": { + "Data": { + "type": "string", + "pattern": "^[-A-Za-z0-9+/]*={0,3}$" + }, + "ContentType": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Checksum": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "ChecksumType": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [ + "Data" + ] + }, + "EmbeddedXMLData": {} + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Document.schema.json b/103120/schema/json/ts_103120_Document.schema.json new file mode 100644 index 00000000..fc85e137 --- /dev/null +++ b/103120/schema/json/ts_103120_Document.schema.json @@ -0,0 +1,148 @@ +{ + "$id": "ts_103120_Document_2020_09", + "$defs": { + "DocumentObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2020/09/Document}DocumentObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "DocumentReference": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "DocumentName": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "DocumentStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DocumentDesiredStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DocumentTimespan": { + "$ref": "#/$defs/DocumentTimespan" + }, + "DocumentType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DocumentProperties": { + "$ref": "#/$defs/DocumentProperties" + }, + "DocumentBody": { + "$ref": "#/$defs/DocumentBody" + }, + "DocumentSignature": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" + } + }, + "DocumentInvalidReason": { + "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" + }, + "NationalDocumentParameters": { + "$ref": "#/$defs/NationalDocumentParameters" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "DocumentTimespan": { + "type": "object", + "properties": { + "StartTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "EndTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "required": [] + }, + "DocumentProperties": { + "type": "object", + "properties": { + "DocumentProperty": { + "type": "array", + "items": { + "$ref": "#/$defs/DocumentProperty" + } + } + }, + "required": [] + }, + "DocumentProperty": { + "type": "object", + "properties": { + "PropertyType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "PropertyValue": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "PropertyType", + "PropertyValue" + ] + }, + "DocumentBody": { + "type": "object", + "properties": { + "Contents": { + "type": "string", + "pattern": "^[-A-Za-z0-9+/]*={0,3}$" + }, + "ContentType": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Checksum": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "ChecksumType": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [] + }, + "NationalDocumentParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Notification.schema.json b/103120/schema/json/ts_103120_Notification.schema.json new file mode 100644 index 00000000..dffab1a6 --- /dev/null +++ b/103120/schema/json/ts_103120_Notification.schema.json @@ -0,0 +1,103 @@ +{ + "$id": "ts_103120_Notification_2016_02", + "$defs": { + "NotificationObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2016/02/Notification}NotificationObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "NotificationDetails": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "NotificationType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "NewNotification": { + "type": "boolean" + }, + "NotificationTimestamp": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "StatusOfAssociatedObjects": { + "$ref": "#/$defs/ListOfAssociatedObjectStatus" + }, + "NationalNotificationParameters": { + "$ref": "#/$defs/NationalNotificationParameters" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "ListOfAssociatedObjectStatus": { + "type": "object", + "properties": { + "AssociatedObjectStatus": { + "type": "array", + "items": { + "$ref": "#/$defs/AssociatedObjectStatus" + }, + "minItems": 1 + } + }, + "required": [] + }, + "AssociatedObjectStatus": { + "type": "object", + "properties": { + "AssociatedObject": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "Status": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "Details": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "AssociatedObject", + "Status" + ] + }, + "NationalNotificationParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Task.schema.json b/103120/schema/json/ts_103120_Task.schema.json new file mode 100644 index 00000000..d19e1ee6 --- /dev/null +++ b/103120/schema/json/ts_103120_Task.schema.json @@ -0,0 +1,599 @@ +{ + "$id": "ts_103120_Task_2020_09", + "$defs": { + "LITaskObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2020/09/Task}LITaskObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "Reference": { + "$ref": "ts_103280_2017_07#/$defs/LIID" + }, + "Status": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DesiredStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "Timespan": { + "$ref": "#/$defs/TaskTimespan" + }, + "TargetIdentifier": { + "$ref": "#/$defs/TargetIdentifier" + }, + "DeliveryType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DeliveryDetails": { + "$ref": "#/$defs/TaskDeliveryDetails" + }, + "ApprovalDetails": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" + } + }, + "CSPID": { + "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" + }, + "HandlingProfile": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "InvalidReason": { + "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" + }, + "Flags": { + "$ref": "#/$defs/TaskFlags" + }, + "NationalLITaskingParameters": { + "$ref": "#/$defs/NationalLITaskingParameters" + }, + "ListOfTrafficPolicyReferences": { + "$ref": "#/$defs/ListOfTrafficPolicyReferences" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "TaskTimespan": { + "type": "object", + "properties": { + "StartTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "EndTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "TerminationTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "ProvisioningTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "DeprovisioningTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "required": [] + }, + "TargetIdentifier": { + "type": "object", + "properties": { + "TargetIdentifierValues": { + "$ref": "#/$defs/TargetIdentifierValues" + }, + "ServiceType": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + }, + "required": [] + }, + "TargetIdentifierValues": { + "type": "object", + "properties": { + "TargetIdentifierValue": { + "type": "array", + "items": { + "$ref": "#/$defs/TargetIdentifierValue" + }, + "minItems": 1 + } + }, + "required": [] + }, + "TargetIdentifierValue": { + "type": "object", + "properties": { + "FormatType": { + "$ref": "#/$defs/FormatType" + }, + "Value": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "FormatType", + "Value" + ] + }, + "FormatType": { + "type": "object", + "properties": { + "FormatOwner": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "FormatName": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [ + "FormatOwner", + "FormatName" + ] + }, + "TaskDeliveryDetails": { + "type": "object", + "properties": { + "DeliveryDestination": { + "type": "array", + "items": { + "$ref": "#/$defs/DeliveryDestination" + }, + "minItems": 1 + } + }, + "required": [] + }, + "DeliveryDestination": { + "type": "object", + "properties": { + "DeliveryAddress": { + "$ref": "#/$defs/DeliveryAddress" + }, + "EncryptionDetails": { + "$ref": "#/$defs/NationalEncryptionDetails" + }, + "IRIorCC": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "HandoverFormat": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "DeliveryProfile": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "NationalDeliveryParameters": { + "$ref": "#/$defs/NationalDeliveryParameters" + } + }, + "required": [] + }, + "DeliveryAddress": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4Address": { + "$ref": "ts_103280_2017_07#/$defs/IPv4Address" + } + }, + "required": [ + "IPv4Address" + ] + }, + { + "type": "object", + "properties": { + "IPv6Address": { + "$ref": "ts_103280_2017_07#/$defs/IPv6Address" + } + }, + "required": [ + "IPv6Address" + ] + }, + { + "type": "object", + "properties": { + "IPAddressPort": { + "$ref": "ts_103280_2017_07#/$defs/IPAddressPort" + } + }, + "required": [ + "IPAddressPort" + ] + }, + { + "type": "object", + "properties": { + "IPAddressPortRange": { + "$ref": "ts_103280_2017_07#/$defs/IPAddressPortRange" + } + }, + "required": [ + "IPAddressPortRange" + ] + }, + { + "type": "object", + "properties": { + "E164Number": { + "$ref": "ts_103280_2017_07#/$defs/InternationalE164" + } + }, + "required": [ + "E164Number" + ] + }, + { + "type": "object", + "properties": { + "FTPAddress": { + "type": "string" + } + }, + "required": [ + "FTPAddress" + ] + }, + { + "type": "object", + "properties": { + "URL": { + "type": "string" + } + }, + "required": [ + "URL" + ] + }, + { + "type": "object", + "properties": { + "FQDN": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "FQDN" + ] + }, + { + "type": "object", + "properties": { + "EmailAddress": { + "$ref": "ts_103280_2017_07#/$defs/EmailAddress" + } + }, + "required": [ + "EmailAddress" + ] + }, + { + "type": "object", + "properties": { + "EndpointID": { + "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" + } + }, + "required": [ + "EndpointID" + ] + }, + { + "type": "object", + "properties": { + "DeliveryInformationID": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "DeliveryInformationID" + ] + } + ] + }, + "TaskFlags": { + "type": "object", + "properties": { + "TaskFlag": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + } + }, + "required": [] + }, + "NationalLITaskingParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "NationalDeliveryParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "NationalEncryptionDetails": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "LDTaskObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2020/09/Task}LDTaskObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "Reference": { + "$ref": "ts_103280_2017_07#/$defs/LDID" + }, + "Status": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "StatusReason": { + "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" + }, + "DesiredStatus": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "RequestDetails": { + "$ref": "#/$defs/RequestDetails" + }, + "DeliveryDetails": { + "$ref": "#/$defs/LDDeliveryDetails" + }, + "ApprovalDetails": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" + } + }, + "CSPID": { + "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" + }, + "HandlingProfile": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "Flags": { + "$ref": "#/$defs/LDTaskFlags" + }, + "NationalLDTaskingParameters": { + "$ref": "#/$defs/NationalLDTaskingParameters" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "RequestDetails": { + "type": "object", + "properties": { + "Type": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "StartTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "EndTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "ObservedTime": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "ObservedTimes": { + "type": "array", + "items": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + } + }, + "RequestValues": { + "$ref": "#/$defs/RequestValues" + }, + "Subtype": { + "$ref": "#/$defs/RequestSubtype" + } + }, + "required": [] + }, + "RequestValues": { + "type": "object", + "properties": { + "RequestValue": { + "type": "array", + "items": { + "$ref": "#/$defs/RequestValue" + }, + "minItems": 1 + } + }, + "required": [] + }, + "RequestValue": { + "type": "object", + "properties": { + "FormatType": { + "$ref": "#/$defs/FormatType" + }, + "Value": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + } + }, + "required": [ + "FormatType", + "Value" + ] + }, + "RequestSubtype": { + "type": "object", + "properties": { + "RequestSubtype": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "minItems": 1 + } + }, + "required": [] + }, + "LDDeliveryDetails": { + "type": "object", + "properties": { + "LDDeliveryDestination": { + "type": "array", + "items": { + "$ref": "#/$defs/LDDeliveryDestination" + }, + "minItems": 1 + } + }, + "required": [] + }, + "LDDeliveryDestination": { + "type": "object", + "properties": { + "DeliveryAddress": { + "$ref": "#/$defs/DeliveryAddress" + }, + "EncryptionDetails": { + "$ref": "#/$defs/NationalEncryptionDetails" + }, + "LDHandoverFormat": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "LDDeliveryProfile": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "NationalDeliveryParameters": { + "$ref": "#/$defs/NationalDeliveryParameters" + } + }, + "required": [] + }, + "LDTaskFlags": { + "type": "object", + "properties": { + "LDTaskFlag": { + "type": "array", + "items": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + } + }, + "required": [] + }, + "NationalLDTaskingParameters": { + "type": "object", + "properties": { + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + } + }, + "required": [ + "CountryCode" + ] + }, + "ListOfTrafficPolicyReferences": { + "type": "object", + "properties": { + "TrafficPolicyReference": { + "type": "array", + "items": { + "$ref": "#/$defs/TrafficPolicyReference" + }, + "minItems": 1 + } + }, + "required": [] + }, + "TrafficPolicyReference": { + "type": "object", + "properties": { + "Order": { + "type": "integer", + "minimum": 1 + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + } + }, + "required": [] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_TrafficPolicy.schema.json b/103120/schema/json/ts_103120_TrafficPolicy.schema.json new file mode 100644 index 00000000..53fe978d --- /dev/null +++ b/103120/schema/json/ts_103120_TrafficPolicy.schema.json @@ -0,0 +1,198 @@ +{ + "$id": "ts_103120_TrafficPolicy_2022_07", + "$defs": { + "TrafficPolicyObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2022/07/TrafficPolicy}TrafficPolicyObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "TrafficPolicyName": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "TrafficRules": { + "$ref": "#/$defs/ListOfTrafficRuleReferences" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "ListOfTrafficRuleReferences": { + "type": "object", + "properties": { + "TrafficRuleReference": { + "type": "array", + "items": { + "$ref": "#/$defs/TrafficRuleReference" + }, + "minItems": 1 + } + }, + "required": [] + }, + "TrafficRuleReference": { + "type": "object", + "properties": { + "Order": { + "type": "integer", + "minimum": 1 + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + } + }, + "required": [ + "Order", + "ObjectIdentifier" + ] + }, + "TrafficRuleObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": "{http://uri.etsi.org/03120/common/2022/07/TrafficPolicy}TrafficRuleObject" + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "Criteria": { + "$ref": "#/$defs/ListOfTrafficCriteria" + }, + "Action": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier" + ] + }, + "ListOfTrafficCriteria": { + "type": "object", + "properties": { + "Criteria": { + "type": "array", + "items": { + "$ref": "#/$defs/TrafficCriteria" + }, + "minItems": 1 + } + }, + "required": [] + }, + "TrafficCriteria": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPPolicyCriteria": { + "$ref": "#/$defs/IPPolicyCriteria" + } + }, + "required": [ + "IPPolicyCriteria" + ] + }, + { + "type": "object", + "properties": { + "MobileAccessPolicyCriteria": { + "$ref": "#/$defs/MobileAccessPolicyCriteria" + } + }, + "required": [ + "MobileAccessPolicyCriteria" + ] + } + ] + }, + "IPPolicyCriteria": { + "type": "object", + "properties": { + "IPProtocol": { + "type": "integer", + "minimum": 0 + }, + "SourceIPRange": { + "$ref": "ts_103280_2017_07#/$defs/IPCIDR" + }, + "SourcePortRange": { + "$ref": "ts_103280_2017_07#/$defs/PortRange" + }, + "DestinationIPRange": { + "$ref": "ts_103280_2017_07#/$defs/IPCIDR" + }, + "DestinationPortRange": { + "$ref": "ts_103280_2017_07#/$defs/PortRange" + }, + "BothDirections": { + "type": "boolean" + } + }, + "required": [] + }, + "MobileAccessPolicyCriteria": { + "type": "object", + "properties": { + "APN": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "DNN": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + } + }, + "required": [] + } + } +} \ No newline at end of file diff --git a/103120/utils/validate.py b/103120/utils/validate.py deleted file mode 100644 index a290ed31..00000000 --- a/103120/utils/validate.py +++ /dev/null @@ -1,94 +0,0 @@ -import sys -from jsonschema import validate, RefResolver, Draft202012Validator -import json -from pathlib import Path -import logging -import argparse - - - -# filename = sys.argv[1] - -# def load_json (path): -# with open(path) as f: -# s = json.load(f) -# return s - -# schema_store = {} - -# json_instance = load_json(filename) -# print (json_instance) - -# etsi_schema = load_json('response.schema.json') -# ext_schema = load_json('extended.schema.json') -# ext_ent_schema = load_json("extended_entities.schema.json") -# schema_store = { -# etsi_schema['$id'] : etsi_schema, -# ext_schema['$id'] : ext_schema, -# ext_ent_schema['$id'] : ext_ent_schema -# } - -# resolver = RefResolver(None, referrer=None, store=schema_store) - -# print (etsi_schema) - -# v = Draft202012Validator(ext_schema, resolver=resolver) -# v.validate(json_instance) - -# validate(json_instance, ext_schema) -# print ("OK") - -def handle_uri(u): - print(u) - -def load_json(path : str): - with open(path) as f: - return json.load(f) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - - parser.add_argument('-s','--schemadir', action="append", help="Directory containing supporting schema files to use for validation") - parser.add_argument('-v', '--verbose', action="count", help="Verbose logging (can be specified multiple times)") - parser.add_argument('schema', help="Primary schema to validate against") - parser.add_argument('filename', help="JSON instance document to validate") - - args = parser.parse_args() - - match args.verbose: - case v if v and v >= 2: - logging.basicConfig(level=logging.DEBUG) - case 1: - logging.basicConfig(level=logging.INFO) - case _: - logging.basicConfig(level=logging.WARNING) - - logging.debug(f"Arguments: {args}") - - instance_doc = load_json(args.filename) - main_schema = load_json(args.schema) - schema_dict = { main_schema['$id'] : main_schema } - - if args.schemadir: - schema_paths = [] - for d in args.schemadir: - schema_paths += [f for f in Path(d).rglob("*.schema.json")] - logging.info(f"Schema files loaded: {schema_paths}") - - schemas_json = [json.load(p.open()) for p in schema_paths] - schema_dict = schema_dict | { s['$id'] : s for s in schemas_json } - - logging.info(f"Schema IDs loaded: {[k for k in schema_dict.keys()]}") - - logging.debug (f"Instance doc: {instance_doc}") - logging.debug (f"Main schema: {main_schema}") - - resolver = RefResolver(None, - referrer=None, - store=schema_dict) - - v = Draft202012Validator(main_schema, resolver=resolver) - - v.validate(instance_doc) - - logging.info("Done") \ No newline at end of file diff --git a/103120/utils/xml_to_json.py b/103120/utils/xml_to_json.py deleted file mode 100644 index 0615a035..00000000 --- a/103120/utils/xml_to_json.py +++ /dev/null @@ -1,12 +0,0 @@ -import xmltodict -from pprint import pprint -import json - -with open('../examples/request1.xml') as f: - s = f.read() - -d = xmltodict.parse(s) -pprint (d) - -with open('../examples/request.json', 'w') as f2: - f2.write(json.dumps(d)) \ No newline at end of file diff --git a/103280/TS_103_280.schema.json b/103280/TS_103_280.schema.json index 523a1a51..474b3ee7 100644 --- a/103280/TS_103_280.schema.json +++ b/103280/TS_103_280.schema.json @@ -1,387 +1,389 @@ -{ - "$id" : "http://etsi.org/temp/280", - "$schema" : "https://json-schema.org/draft/2020-12/schema", - "title" : "ETSI TS 103 280 (temp)", - "description" : "A stubbed version of TS 103 280 definitions (need a CR to 280 for this)", - "$defs": { - "ShortString": { - "type": "string", - "maxLength": 255 - }, - "LongString": { - "type": "string", - "maxLength": 65535 - }, - "LIID": { - "type": "string", - "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" - }, - "UTCDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" - }, - "UTCMicrosecondDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" - }, - "QualifiedDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" - }, - "QualifiedMicrosecondDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" - }, - "InternationalE164": { - "type": "string", - "pattern": "^[0-9]{1,15}$" - }, - "IMSI": { - "type": "string", - "pattern": "^[0-9]{6,15}$" - }, - "IMEI": { - "type": "string", - "pattern": "^[0-9]{14}$" - }, - "IMEICheckDigit": { - "type": "string", - "pattern": "^[0-9]{15}$" - }, - "IMEISV": { - "type": "string", - "pattern": "^[0-9]{16}$" - }, - "IPv4Address": { - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" - }, - "IPv4CIDR": { - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" - }, - "IPv6Address": { - "type": "string", - "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" - }, - "IPv6CIDR": { - "type": "string", - "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" - }, - "TCPPort": { - "type": "integer", - "exclusiveMinimum": 1, - "maximum": 65535 - }, - "UDPPort": { - "type": "integer", - "minimum": 0, - "maximum": 65535 - }, - "MACAddress": { - "type": "string", - "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" - }, - "EmailAddress": { - "allOf": [ - { - "$ref": "#/$defs/ShortString" - }, - { - "type": "string", - "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" - } - ] - }, - "UUID": { - "type": "string", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" - }, - "ISOCountryCode": { - "type": "string", - "pattern": "^[A-Z]{2}$" - }, - "SIPURI": { - "type": "string", - "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" - }, - "TELURI": { - "type": "string", - "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" - }, - "WGS84LatitudeDecimal": { - "type": "string", - "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" - }, - "WGS84LongitudeDecimal": { - "type": "string", - "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" - }, - "WGS84LatitudeAngular": { - "type": "string", - "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" - }, - "WGS84LongitudeAngular": { - "type": "string", - "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" - }, - "SUPIIMSI": { - "$ref": "#/$defs/IMSI" - }, - "SUPINAI": { - "$ref": "#/$defs/NAI" - }, - "SUCI": { - "type": "string", - "pattern": "^([a-fA-F0-9]{2})*$" - }, - "PEIIMEI": { - "$ref": "#/$defs/IMEI" - }, - "PEIIMEICheckDigit": { - "$ref": "#/$defs/IMEICheckDigit" - }, - "PEIIMEISV": { - "$ref": "#/$defs/IMEISV" - }, - "GPSIMSISDN": { - "type": "string", - "pattern": "^[0-9]{1,15}$" - }, - "GPSINAI": { - "$ref": "#/$defs/NAI" - }, - "NAI": { - "type": "string" - }, - "LDID": { - "type": "string", - "pattern": "^([A-Z]{2}-.+-.+)$" - }, - "InternationalizedEmailAddress": { - "allOf": [ - { - "$ref": "#/$defs/ShortString" - }, - { - "type": "string", - "pattern": "^.+@.+$" - } - ] - }, - "EUI64": { - "type": "string", - "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" - }, - "CGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" - }, - "ECGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" - }, - "NCGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" - }, - "ICCID": { - "type": "string", - "pattern": "^[0-9]{19,20}$" - }, - "IPAddress": { - "oneOf": [ - { - "type": "object", - "properties": { - "IPv4Address": { - "$ref": "#/$defs/IPv4Address" - } - }, - "required": [ - "IPv4Address" - ] - }, - { - "type": "object", - "properties": { - "IPv6Address": { - "$ref": "#/$defs/IPv6Address" - } - }, - "required": [ - "IPv6Address" - ] - } - ] - }, - "IPCIDR": { - "oneOf": [ - { - "type": "object", - "properties": { - "IPv4CIDR": { - "$ref": "#/$defs/IPv4CIDR" - } - }, - "required": [ - "IPv4CIDR" - ] - }, - { - "type": "object", - "properties": { - "IPv6CIDR": { - "$ref": "#/$defs/IPv6CIDR" - } - }, - "required": [ - "IPv6CIDR" - ] - } - ] - }, - "TCPPortRange": { +{ + "$id": "ts_103280_2017_07", + "$defs": { + "ShortString": { + "type": "string", + "maxLength": 255 + }, + "LongString": { + "type": "string", + "maxLength": 65535 + }, + "LIID": { + "type": "string", + "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" + }, + "UTCDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + }, + "UTCMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" + }, + "QualifiedDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "QualifiedMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "InternationalE164": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "IMSI": { + "type": "string", + "pattern": "^[0-9]{6,15}$" + }, + "IMEI": { + "type": "string", + "pattern": "^[0-9]{14}$" + }, + "IMEICheckDigit": { + "type": "string", + "pattern": "^[0-9]{15}$" + }, + "IMEISV": { + "type": "string", + "pattern": "^[0-9]{16}$" + }, + "IPv4Address": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" + }, + "IPv4CIDR": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" + }, + "IPv6Address": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" + }, + "IPv6CIDR": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" + }, + "TCPPort": { + "type": "integer", + "exclusiveMinimum": 1, + "maximum": 65535 + }, + "UDPPort": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "MACAddress": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" + }, + "EmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" + } + ] + }, + "UUID": { + "type": "string", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" + }, + "ISOCountryCode": { + "type": "string", + "pattern": "^[A-Z]{2}$" + }, + "SIPURI": { + "type": "string", + "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "TELURI": { + "type": "string", + "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "WGS84LatitudeDecimal": { + "type": "string", + "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" + }, + "WGS84LongitudeDecimal": { + "type": "string", + "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" + }, + "WGS84LatitudeAngular": { + "type": "string", + "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" + }, + "WGS84LongitudeAngular": { + "type": "string", + "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" + }, + "SUPIIMSI": { + "$ref": "#/$defs/IMSI" + }, + "SUPINAI": { + "$ref": "#/$defs/NAI" + }, + "SUCI": { + "type": "string", + "pattern": "^([a-fA-F0-9]{2})*$" + }, + "PEIIMEI": { + "$ref": "#/$defs/IMEI" + }, + "PEIIMEICheckDigit": { + "$ref": "#/$defs/IMEICheckDigit" + }, + "PEIIMEISV": { + "$ref": "#/$defs/IMEISV" + }, + "GPSIMSISDN": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "GPSINAI": { + "$ref": "#/$defs/NAI" + }, + "NAI": { + "type": "string" + }, + "LDID": { + "type": "string", + "pattern": "^([A-Z]{2}-.+-.+)$" + }, + "InternationalizedEmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^.+@.+$" + } + ] + }, + "EUI64": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" + }, + "CGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" + }, + "ECGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" + }, + "NCGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" + }, + "ICCID": { + "type": "string", + "pattern": "^[0-9]{19,20}$" + }, + "IPProtocol": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "IPAddress": { + "oneOf": [ + { "type": "object", "properties": { - "start": { - "$ref": "#/$defs/TCPPort" - }, - "end": { - "$ref": "#/$defs/TCPPort" + "IPv4Address": { + "$ref": "#/$defs/IPv4Address" } }, "required": [ - "start", - "end" + "IPv4Address" ] }, - "UDPPortRange": { + { "type": "object", "properties": { - "start": { - "$ref": "#/$defs/UDPPort" - }, - "end": { - "$ref": "#/$defs/UDPPort" + "IPv6Address": { + "$ref": "#/$defs/IPv6Address" } }, "required": [ - "start", - "end" + "IPv6Address" ] - }, - "Port": { - "oneOf": [ - { - "type": "object", - "properties": { - "TCPPort": { - "$ref": "#/$defs/TCPPort" - } - }, - "required": [ - "TCPPort" - ] - }, - { - "type": "object", - "properties": { - "UDPPort": { - "$ref": "#/$defs/UDPPort" - } - }, - "required": [ - "UDPPort" - ] + } + ] + }, + "IPCIDR": { + "oneOf": [ + { + "type": "object", + "properties": { + "IPv4CIDR": { + "$ref": "#/$defs/IPv4CIDR" } + }, + "required": [ + "IPv4CIDR" ] }, - "PortRange": { - "oneOf": [ - { - "type": "object", - "properties": { - "TCPPortRange": { - "$ref": "#/$defs/TCPPortRange" - } - }, - "required": [ - "TCPPortRange" - ] - }, - { - "type": "object", - "properties": { - "UDPPortRange": { - "$ref": "#/$defs/UDPPortRange" - } - }, - "required": [ - "UDPPortRange" - ] + { + "type": "object", + "properties": { + "IPv6CIDR": { + "$ref": "#/$defs/IPv6CIDR" } + }, + "required": [ + "IPv6CIDR" ] - }, - "IPAddressPort": { + } + ] + }, + "TCPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/TCPPort" + }, + "end": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "UDPPortRange": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/UDPPort" + }, + "end": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "start", + "end" + ] + }, + "Port": { + "oneOf": [ + { "type": "object", "properties": { - "address": { - "$ref": "#/$defs/IPAddress" - }, - "port": { - "$ref": "#/$defs/Port" + "TCPPort": { + "$ref": "#/$defs/TCPPort" } }, "required": [ - "address", - "port" + "TCPPort" ] }, - "IPAddressPortRange": { + { "type": "object", "properties": { - "address": { - "$ref": "#/$defs/IPAddress" - }, - "portRange": { - "$ref": "#/$defs/PortRange" + "UDPPort": { + "$ref": "#/$defs/UDPPort" } }, "required": [ - "address", - "portRange" + "UDPPort" ] - }, - "WGS84CoordinateDecimal": { + } + ] + }, + "PortRange": { + "oneOf": [ + { "type": "object", "properties": { - "latitude": { - "$ref": "#/$defs/WGS84LatitudeDecimal" - }, - "longitude": { - "$ref": "#/$defs/WGS84LongitudeDecimal" + "TCPPortRange": { + "$ref": "#/$defs/TCPPortRange" } }, "required": [ - "latitude", - "longitude" + "TCPPortRange" ] }, - "WGS84CoordinateAngular": { + { "type": "object", "properties": { - "latitude": { - "$ref": "#/$defs/WGS84LatitudeAngular" - }, - "longitude": { - "$ref": "#/$defs/WGS84LongitudeAngular" + "UDPPortRange": { + "$ref": "#/$defs/UDPPortRange" } }, "required": [ - "latitude", - "longitude" + "UDPPortRange" ] } - } -} \ No newline at end of file + ] + }, + "IPAddressPort": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "port": { + "$ref": "#/$defs/Port" + } + }, + "required": [ + "address", + "port" + ] + }, + "IPAddressPortRange": { + "type": "object", + "properties": { + "address": { + "$ref": "#/$defs/IPAddress" + }, + "portRange": { + "$ref": "#/$defs/PortRange" + } + }, + "required": [ + "address", + "portRange" + ] + }, + "WGS84CoordinateDecimal": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeDecimal" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeDecimal" + } + }, + "required": [ + "latitude", + "longitude" + ] + }, + "WGS84CoordinateAngular": { + "type": "object", + "properties": { + "latitude": { + "$ref": "#/$defs/WGS84LatitudeAngular" + }, + "longitude": { + "$ref": "#/$defs/WGS84LongitudeAngular" + } + }, + "required": [ + "latitude", + "longitude" + ] + } + } +} \ No newline at end of file -- GitLab From 8767a24f118cecaa9e6f9eb3cb418ca0fa5ac5dc Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 19 May 2023 09:30:54 +0100 Subject: [PATCH 04/15] Preparing to keep namespaces --- utils/xml_to_json.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index 2655bd73..9d519727 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -23,7 +23,6 @@ def removePrefixes (o, prefixes): new_key = k.split(':')[1] replacements.append( (k, new_key) ) for r in replacements: - print(r) o[r[1]] = o.pop(r[0]) if __name__ == "__main__": @@ -32,11 +31,10 @@ if __name__ == "__main__": p = Path(sys.argv[1]) s = p.read_text() - print(s) d = xmltodict.parse(s)['HI1Message'] prefixes = extract_prefixes(d) removePrefixes(d, prefixes) - print(d) + print(json.dumps(d)) -- GitLab From 1c87ce5116143e7fef0f15055cc33edb59d637fa Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 23 May 2023 17:50:11 +0100 Subject: [PATCH 05/15] Updates to converter --- utils/xml_to_json.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index 9d519727..a85d48a7 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -1,8 +1,12 @@ -import xmltodict import sys +import logging from pprint import pprint import json from pathlib import Path +import fileinput + +import xmltodict +import argparse def extract_prefixes (d): @@ -26,12 +30,32 @@ def removePrefixes (o, prefixes): o[r[1]] = o.pop(r[0]) if __name__ == "__main__": - if len(sys.argv) < 2: - print ("Usage: xml_to_json.py filename") + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--verbose', action='count', help='Verbose logging (can be specified multiple times)') + parser.add_argument('-i', '--input', type=argparse.FileType('r'), default=sys.stdin, help="Path to input file (if absent, stdin is used)") + args = parser.parse_args() + + match args.verbose: + case v if v and v >= 2: + logging.basicConfig(level=logging.DEBUG) + case 1: + logging.basicConfig(level=logging.INFO) + case _: + logging.basicConfig(level=logging.WARNING) + + logging.debug(f"Arguments: {args}") - p = Path(sys.argv[1]) - s = p.read_text() + # if (args.input): + # logging.info(f"Reading from {args.input}") + # with open(args.input) as f: + # s = f.read() + # else: + # logging.info(f"Reading from stdin") + # s = sys.stdin.read() + s = args.input.read() + args.input.close() + logging.debug(s) d = xmltodict.parse(s)['HI1Message'] prefixes = extract_prefixes(d) -- GitLab From 46a6583adb46b9e93475c6fde2a9995900f70f70 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 23 May 2023 17:52:47 +0100 Subject: [PATCH 06/15] Moving 280 schema --- 103120/schema/json/TS_103_280.schema.json | 389 ---------------------- 1 file changed, 389 deletions(-) delete mode 100644 103120/schema/json/TS_103_280.schema.json diff --git a/103120/schema/json/TS_103_280.schema.json b/103120/schema/json/TS_103_280.schema.json deleted file mode 100644 index 474b3ee7..00000000 --- a/103120/schema/json/TS_103_280.schema.json +++ /dev/null @@ -1,389 +0,0 @@ -{ - "$id": "ts_103280_2017_07", - "$defs": { - "ShortString": { - "type": "string", - "maxLength": 255 - }, - "LongString": { - "type": "string", - "maxLength": 65535 - }, - "LIID": { - "type": "string", - "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" - }, - "UTCDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" - }, - "UTCMicrosecondDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" - }, - "QualifiedDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" - }, - "QualifiedMicrosecondDateTime": { - "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" - }, - "InternationalE164": { - "type": "string", - "pattern": "^[0-9]{1,15}$" - }, - "IMSI": { - "type": "string", - "pattern": "^[0-9]{6,15}$" - }, - "IMEI": { - "type": "string", - "pattern": "^[0-9]{14}$" - }, - "IMEICheckDigit": { - "type": "string", - "pattern": "^[0-9]{15}$" - }, - "IMEISV": { - "type": "string", - "pattern": "^[0-9]{16}$" - }, - "IPv4Address": { - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" - }, - "IPv4CIDR": { - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" - }, - "IPv6Address": { - "type": "string", - "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" - }, - "IPv6CIDR": { - "type": "string", - "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" - }, - "TCPPort": { - "type": "integer", - "exclusiveMinimum": 1, - "maximum": 65535 - }, - "UDPPort": { - "type": "integer", - "minimum": 0, - "maximum": 65535 - }, - "MACAddress": { - "type": "string", - "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" - }, - "EmailAddress": { - "allOf": [ - { - "$ref": "#/$defs/ShortString" - }, - { - "type": "string", - "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" - } - ] - }, - "UUID": { - "type": "string", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" - }, - "ISOCountryCode": { - "type": "string", - "pattern": "^[A-Z]{2}$" - }, - "SIPURI": { - "type": "string", - "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" - }, - "TELURI": { - "type": "string", - "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" - }, - "WGS84LatitudeDecimal": { - "type": "string", - "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" - }, - "WGS84LongitudeDecimal": { - "type": "string", - "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" - }, - "WGS84LatitudeAngular": { - "type": "string", - "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" - }, - "WGS84LongitudeAngular": { - "type": "string", - "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" - }, - "SUPIIMSI": { - "$ref": "#/$defs/IMSI" - }, - "SUPINAI": { - "$ref": "#/$defs/NAI" - }, - "SUCI": { - "type": "string", - "pattern": "^([a-fA-F0-9]{2})*$" - }, - "PEIIMEI": { - "$ref": "#/$defs/IMEI" - }, - "PEIIMEICheckDigit": { - "$ref": "#/$defs/IMEICheckDigit" - }, - "PEIIMEISV": { - "$ref": "#/$defs/IMEISV" - }, - "GPSIMSISDN": { - "type": "string", - "pattern": "^[0-9]{1,15}$" - }, - "GPSINAI": { - "$ref": "#/$defs/NAI" - }, - "NAI": { - "type": "string" - }, - "LDID": { - "type": "string", - "pattern": "^([A-Z]{2}-.+-.+)$" - }, - "InternationalizedEmailAddress": { - "allOf": [ - { - "$ref": "#/$defs/ShortString" - }, - { - "type": "string", - "pattern": "^.+@.+$" - } - ] - }, - "EUI64": { - "type": "string", - "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" - }, - "CGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" - }, - "ECGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" - }, - "NCGI": { - "type": "string", - "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" - }, - "ICCID": { - "type": "string", - "pattern": "^[0-9]{19,20}$" - }, - "IPProtocol": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "IPAddress": { - "oneOf": [ - { - "type": "object", - "properties": { - "IPv4Address": { - "$ref": "#/$defs/IPv4Address" - } - }, - "required": [ - "IPv4Address" - ] - }, - { - "type": "object", - "properties": { - "IPv6Address": { - "$ref": "#/$defs/IPv6Address" - } - }, - "required": [ - "IPv6Address" - ] - } - ] - }, - "IPCIDR": { - "oneOf": [ - { - "type": "object", - "properties": { - "IPv4CIDR": { - "$ref": "#/$defs/IPv4CIDR" - } - }, - "required": [ - "IPv4CIDR" - ] - }, - { - "type": "object", - "properties": { - "IPv6CIDR": { - "$ref": "#/$defs/IPv6CIDR" - } - }, - "required": [ - "IPv6CIDR" - ] - } - ] - }, - "TCPPortRange": { - "type": "object", - "properties": { - "start": { - "$ref": "#/$defs/TCPPort" - }, - "end": { - "$ref": "#/$defs/TCPPort" - } - }, - "required": [ - "start", - "end" - ] - }, - "UDPPortRange": { - "type": "object", - "properties": { - "start": { - "$ref": "#/$defs/UDPPort" - }, - "end": { - "$ref": "#/$defs/UDPPort" - } - }, - "required": [ - "start", - "end" - ] - }, - "Port": { - "oneOf": [ - { - "type": "object", - "properties": { - "TCPPort": { - "$ref": "#/$defs/TCPPort" - } - }, - "required": [ - "TCPPort" - ] - }, - { - "type": "object", - "properties": { - "UDPPort": { - "$ref": "#/$defs/UDPPort" - } - }, - "required": [ - "UDPPort" - ] - } - ] - }, - "PortRange": { - "oneOf": [ - { - "type": "object", - "properties": { - "TCPPortRange": { - "$ref": "#/$defs/TCPPortRange" - } - }, - "required": [ - "TCPPortRange" - ] - }, - { - "type": "object", - "properties": { - "UDPPortRange": { - "$ref": "#/$defs/UDPPortRange" - } - }, - "required": [ - "UDPPortRange" - ] - } - ] - }, - "IPAddressPort": { - "type": "object", - "properties": { - "address": { - "$ref": "#/$defs/IPAddress" - }, - "port": { - "$ref": "#/$defs/Port" - } - }, - "required": [ - "address", - "port" - ] - }, - "IPAddressPortRange": { - "type": "object", - "properties": { - "address": { - "$ref": "#/$defs/IPAddress" - }, - "portRange": { - "$ref": "#/$defs/PortRange" - } - }, - "required": [ - "address", - "portRange" - ] - }, - "WGS84CoordinateDecimal": { - "type": "object", - "properties": { - "latitude": { - "$ref": "#/$defs/WGS84LatitudeDecimal" - }, - "longitude": { - "$ref": "#/$defs/WGS84LongitudeDecimal" - } - }, - "required": [ - "latitude", - "longitude" - ] - }, - "WGS84CoordinateAngular": { - "type": "object", - "properties": { - "latitude": { - "$ref": "#/$defs/WGS84LatitudeAngular" - }, - "longitude": { - "$ref": "#/$defs/WGS84LongitudeAngular" - } - }, - "required": [ - "latitude", - "longitude" - ] - } - } -} \ No newline at end of file -- GitLab From fcf319170c39fcd9e54e8331ce0ea52e9c8cd44d Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 1 Jun 2023 11:46:23 +0100 Subject: [PATCH 07/15] validate can read from stdin --- utils/validate.py | 37 +++---------------------------------- utils/xml_to_json.py | 7 ------- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/utils/validate.py b/utils/validate.py index a290ed31..c8326310 100644 --- a/utils/validate.py +++ b/utils/validate.py @@ -6,38 +6,6 @@ import logging import argparse - -# filename = sys.argv[1] - -# def load_json (path): -# with open(path) as f: -# s = json.load(f) -# return s - -# schema_store = {} - -# json_instance = load_json(filename) -# print (json_instance) - -# etsi_schema = load_json('response.schema.json') -# ext_schema = load_json('extended.schema.json') -# ext_ent_schema = load_json("extended_entities.schema.json") -# schema_store = { -# etsi_schema['$id'] : etsi_schema, -# ext_schema['$id'] : ext_schema, -# ext_ent_schema['$id'] : ext_ent_schema -# } - -# resolver = RefResolver(None, referrer=None, store=schema_store) - -# print (etsi_schema) - -# v = Draft202012Validator(ext_schema, resolver=resolver) -# v.validate(json_instance) - -# validate(json_instance, ext_schema) -# print ("OK") - def handle_uri(u): print(u) @@ -50,8 +18,8 @@ if __name__ == "__main__": parser.add_argument('-s','--schemadir', action="append", help="Directory containing supporting schema files to use for validation") parser.add_argument('-v', '--verbose', action="count", help="Verbose logging (can be specified multiple times)") + parser.add_argument('-i', '--input', type=argparse.FileType('r'), default=sys.stdin, help="Path to input file (if absent, stdin is used)") parser.add_argument('schema', help="Primary schema to validate against") - parser.add_argument('filename', help="JSON instance document to validate") args = parser.parse_args() @@ -65,7 +33,8 @@ if __name__ == "__main__": logging.debug(f"Arguments: {args}") - instance_doc = load_json(args.filename) + instance_doc = json.loads(args.input.read()) + args.input.close() main_schema = load_json(args.schema) schema_dict = { main_schema['$id'] : main_schema } diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index a85d48a7..b8c9e275 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -45,13 +45,6 @@ if __name__ == "__main__": logging.debug(f"Arguments: {args}") - # if (args.input): - # logging.info(f"Reading from {args.input}") - # with open(args.input) as f: - # s = f.read() - # else: - # logging.info(f"Reading from stdin") - # s = sys.stdin.read() s = args.input.read() args.input.close() -- GitLab From f73dee289c15e868e44c1e6da14e42207e76c115 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 2 Jun 2023 12:40:35 +0100 Subject: [PATCH 08/15] Validation giving more helpful messages --- 103120/examples/fragment.json | 41 ++++- 103120/examples/fragment.schema.json | 4 +- 103120/examples/request1.json | 154 +++++++++-------- .../json/ts_103120_Authorisation.schema.json | 48 +++--- .../schema/json/ts_103120_Common.schema.json | 54 +++--- 103120/schema/json/ts_103120_Core.schema.json | 3 +- .../json/ts_103120_Delivery.schema.json | 30 ++-- .../json/ts_103120_Document.schema.json | 48 +++--- .../json/ts_103120_Notification.schema.json | 28 +-- 103120/schema/json/ts_103120_Task.schema.json | 160 +++++++++--------- .../json/ts_103120_TrafficPolicy.schema.json | 36 ++-- test1.json | 90 ++++++++++ test2.json | 1 + utils/request.fragment.schema.json | 4 + utils/translate/SequenceMapping.py | 18 +- utils/translate/TypeMapping.py | 2 +- utils/translate/__init__.py | 2 +- utils/translate_spec.py | 57 +++---- utils/ts103120_config.json | 46 +++-- utils/validate.py | 59 ++++++- utils/xml_to_json.py | 16 +- 21 files changed, 548 insertions(+), 353 deletions(-) create mode 100644 test1.json create mode 100644 test2.json create mode 100644 utils/request.fragment.schema.json diff --git a/103120/examples/fragment.json b/103120/examples/fragment.json index 98a6bfc4..44f2f88d 100644 --- a/103120/examples/fragment.json +++ b/103120/examples/fragment.json @@ -1,11 +1,38 @@ { - "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject", - "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", - "CountryCode": "GB", + "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Task}LITaskObject", + "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", + "CountryCode": "XX", "OwnerIdentifier": "ACTOR01", - "AuthorisationReference": "W000001", - "AuthorisationTimespan": { - "StartTime": "2015-09-01T12:00:00Z", - "EndTime": "2015-12-01T12:00:00Z" + "AssociatedObjects": { + "AssociatedObject": ["7dbbc880-8750-4d3c-abe7-ea4a17646045"] + }, + "task:Reference": "LIID1", + "task:TargetIdentifier": { + "task:TargetIdentifierValues": { + "task:TargetIdentifierValue": [{ + "task:FormatType": { + "task:FormatOwner": "ETSI", + "task:FormatName": "InternationalE164" + }, + "task:Value": "442079460223" + }] + } + }, + "task:DeliveryType": { + "common:Owner": "ETSI", + "common:Name": "TaskDeliveryType", + "common:Value": "IRIandCC" + }, + "task:DeliveryDetails": { + "task:DeliveryDestination": [{ + "task:DeliveryAddress": { + "IPv4Address": "192.0.2.0" + } + }] + }, + "task:CSPID": { + "CountryCode": "XX", + "UniqueIdentifier": "RECVER01" } + } \ No newline at end of file diff --git a/103120/examples/fragment.schema.json b/103120/examples/fragment.schema.json index 80124bc0..afb21c19 100644 --- a/103120/examples/fragment.schema.json +++ b/103120/examples/fragment.schema.json @@ -1,4 +1,4 @@ { - "$id": "ts_103120_Authorisation_2020_09", - "$ref" : "ts_103120_Authorisation_2020_09#/$defs/AuthorisationObject" + "$id": "ts_103120_Task_2020_09", + "$ref" : "#/$defs/RequestPayload" } \ No newline at end of file diff --git a/103120/examples/request1.json b/103120/examples/request1.json index a73501e8..d5c90abb 100644 --- a/103120/examples/request1.json +++ b/103120/examples/request1.json @@ -1,91 +1,89 @@ { - "HI1Message": { - "@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", - "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", - "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", - "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", - "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", - "Header": { - "SenderIdentifier": { - "CountryCode": "XX", - "UniqueIdentifier": "ACTOR01" - }, - "ReceiverIdentifier": { - "CountryCode": "XX", - "UniqueIdentifier": "ACTOR02" - }, - "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", - "Timestamp": "2015-09-01T12:00:00.000000Z", - "Version": { - "ETSIVersion": "V1.13.1", - "NationalProfileOwner": "XX", - "NationalProfileVersion": "v1.0" - } + "@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", + "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", + "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", + "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", + "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", + "Header": { + "SenderIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR01" }, - "Payload": { - "RequestPayload": { - "ActionRequests": { - "ActionRequest": [ - { - "ActionIdentifier": "0", - "CREATE": { - "HI1Object": { - "@xsi:type": "auth:AuthorisationObject", - "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", - "CountryCode": "XX", - "OwnerIdentifier": "ACTOR01", - "auth:AuthorisationReference": "W000001", - "auth:AuthorisationTimespan": { - "auth:StartTime": "2015-09-01T12:00:00Z", - "auth:EndTime": "2015-12-01T12:00:00Z" - } + "ReceiverIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR02" + }, + "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", + "Timestamp": "2015-09-01T12:00:00.000000Z", + "Version": { + "ETSIVersion": "V1.13.1", + "NationalProfileOwner": "XX", + "NationalProfileVersion": "v1.0" + } + }, + "Payload": { + "RequestPayload": { + "ActionRequests": { + "ActionRequest": [ + { + "ActionIdentifier": 0, + "CREATE": { + "HI1Object": { + "@xsi:type": "auth:AuthorisationObject", + "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "auth:AuthorisationReference": "W000001", + "auth:AuthorisationTimespan": { + "auth:StartTime": "2015-09-01T12:00:00Z", + "auth:EndTime": "2015-12-01T12:00:00Z" } } - }, - { - "ActionIdentifier": "1", - "CREATE": { - "HI1Object": { - "@xsi:type": "task:LITaskObject", - "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", - "CountryCode": "XX", - "OwnerIdentifier": "ACTOR01", - "AssociatedObjects": { - "AssociatedObject": "7dbbc880-8750-4d3c-abe7-ea4a17646045" - }, - "task:Reference": "LIID1", - "task:TargetIdentifier": { - "task:TargetIdentifierValues": { - "task:TargetIdentifierValue": { - "task:FormatType": { - "task:FormatOwner": "ETSI", - "task:FormatName": "InternationalE164" - }, - "task:Value": "442079460223" - } + } + }, + { + "ActionIdentifier": 1, + "CREATE": { + "HI1Object": { + "@xsi:type": "task:LITaskObject", + "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "AssociatedObjects": { + "AssociatedObject": "7dbbc880-8750-4d3c-abe7-ea4a17646045" + }, + "task:Reference": "LIID1", + "task:TargetIdentifier": { + "task:TargetIdentifierValues": { + "task:TargetIdentifierValue": { + "task:FormatType": { + "task:FormatOwner": "ETSI", + "task:FormatName": "InternationalE164" + }, + "task:Value": "442079460223" } - }, - "task:DeliveryType": { - "common:Owner": "ETSI", - "common:Name": "TaskDeliveryType", - "common:Value": "IRIandCC" - }, - "task:DeliveryDetails": { - "task:DeliveryDestination": { - "task:DeliveryAddress": { - "task:IPv4Address": "192.0.2.0" - } + } + }, + "task:DeliveryType": { + "common:Owner": "ETSI", + "common:Name": "TaskDeliveryType", + "common:Value": "IRIandCC" + }, + "task:DeliveryDetails": { + "task:DeliveryDestination": { + "task:DeliveryAddress": { + "task:IPv4Address": "192.0.2.0" } - }, - "task:CSPID": { - "CountryCode": "XX", - "UniqueIdentifier": "RECVER01" } + }, + "task:CSPID": { + "CountryCode": "XX", + "UniqueIdentifier": "RECVER01" } } } - ] - } + } + ] } } } diff --git a/103120/schema/json/ts_103120_Authorisation.schema.json b/103120/schema/json/ts_103120_Authorisation.schema.json index a6f81629..1c9a68ff 100644 --- a/103120/schema/json/ts_103120_Authorisation.schema.json +++ b/103120/schema/json/ts_103120_Authorisation.schema.json @@ -33,61 +33,61 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "AuthorisationReference": { + "auth:AuthorisationReference": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "AuthorisationLegalType": { + "auth:AuthorisationLegalType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "AuthorisationPriority": { + "auth:AuthorisationPriority": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "AuthorisationStatus": { + "auth:AuthorisationStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "AuthorisationDesiredStatus": { + "auth:AuthorisationDesiredStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "AuthorisationTimespan": { + "auth:AuthorisationTimespan": { "$ref": "#/$defs/AuthorisationTimespan" }, - "AuthorisationCSPID": { + "auth:AuthorisationCSPID": { "$ref": "#/$defs/AuthorisationCSPID" }, - "AuthorisationCreationTimestamp": { + "auth:AuthorisationCreationTimestamp": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "AuthorisationServedTimestamp": { + "auth:AuthorisationServedTimestamp": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "AuthorisationTerminationTimestamp": { + "auth:AuthorisationTerminationTimestamp": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "AuthorisationApprovalDetails": { + "auth:AuthorisationApprovalDetails": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" } }, - "AuthorisationInvalidReason": { + "auth:AuthorisationInvalidReason": { "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" }, - "AuthorisationFlags": { + "auth:AuthorisationFlags": { "$ref": "#/$defs/AuthorisationFlags" }, - "AuthorisationManualInformation": { + "auth:AuthorisationManualInformation": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "NationalAuthorisationParameters": { + "auth:NationalAuthorisationParameters": { "$ref": "#/$defs/NationalAuthorisationParameters" }, - "AuthorisationJurisdiction": { + "auth:AuthorisationJurisdiction": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "AuthorisationTypeOfCase": { + "auth:AuthorisationTypeOfCase": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "AuthorisationLegalEntity": { + "auth:AuthorisationLegalEntity": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, @@ -99,7 +99,7 @@ "AuthorisationFlags": { "type": "object", "properties": { - "AuthorisationFlag": { + "auth:AuthorisationFlag": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" @@ -111,10 +111,10 @@ "AuthorisationTimespan": { "type": "object", "properties": { - "StartTime": { + "auth:StartTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "EndTime": { + "auth:EndTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" } }, @@ -123,7 +123,7 @@ "AuthorisationCSPID": { "type": "object", "properties": { - "CSPID": { + "auth:CSPID": { "type": "array", "items": { "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" @@ -136,12 +136,12 @@ "NationalAuthorisationParameters": { "type": "object", "properties": { - "CountryCode": { + "auth:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "auth:CountryCode" ] } } diff --git a/103120/schema/json/ts_103120_Common.schema.json b/103120/schema/json/ts_103120_Common.schema.json index 2149684d..2564e8db 100644 --- a/103120/schema/json/ts_103120_Common.schema.json +++ b/103120/schema/json/ts_103120_Common.schema.json @@ -15,47 +15,47 @@ "DictionaryEntry": { "type": "object", "properties": { - "Owner": { + "common:Owner": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "Name": { + "common:Name": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "Value": { + "common:Value": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, "required": [ - "Owner", - "Name", - "Value" + "common:Owner", + "common:Name", + "common:Value" ] }, "ApprovalDetails": { "type": "object", "properties": { - "ApprovalType": { + "common:ApprovalType": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApprovalDescription": { + "common:ApprovalDescription": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApprovalReference": { + "common:ApprovalReference": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApproverDetails": { + "common:ApproverDetails": { "$ref": "#/$defs/ApproverDetails" }, - "ApprovalTimestamp": { + "common:ApprovalTimestamp": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "ApprovalIsEmergency": { + "common:ApprovalIsEmergency": { "type": "boolean" }, - "ApprovalDigitalSignature": { + "common:ApprovalDigitalSignature": { "$ref": "#/$defs/ApprovalDigitalSignature" }, - "ApprovalNationalDetails": { + "common:ApprovalNationalDetails": { "$ref": "#/$defs/ApprovalNationalDetails" } }, @@ -64,16 +64,16 @@ "ApproverDetails": { "type": "object", "properties": { - "ApproverName": { + "common:ApproverName": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApproverRole": { + "common:ApproverRole": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApproverIdentity": { + "common:ApproverIdentity": { "$ref": "#/$defs/ApproverIdentity" }, - "ApproverContactDetails": { + "common:ApproverContactDetails": { "type": "array", "items": { "$ref": "#/$defs/ApproverContactDetails" @@ -100,13 +100,13 @@ "ApproverContactDetails": { "type": "object", "properties": { - "ApproverAlternateName": { + "common:ApproverAlternateName": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ApproverEmailAddress": { + "common:ApproverEmailAddress": { "$ref": "ts_103280_2017_07#/$defs/InternationalizedEmailAddress" }, - "ApproverPhoneNumber": { + "common:ApproverPhoneNumber": { "$ref": "ts_103280_2017_07#/$defs/InternationalE164" } }, @@ -115,12 +115,12 @@ "NationalApproverIdentity": { "type": "object", "properties": { - "CountryCode": { + "common:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "common:CountryCode" ] }, "ApprovalDigitalSignature": { @@ -141,23 +141,23 @@ "ApprovalNationalDetails": { "type": "object", "properties": { - "CountryCode": { + "common:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "common:CountryCode" ] }, "NationalDigitalSignature": { "type": "object", "properties": { - "CountryCode": { + "common:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "common:CountryCode" ] } } diff --git a/103120/schema/json/ts_103120_Core.schema.json b/103120/schema/json/ts_103120_Core.schema.json index ee2852b8..f116d315 100644 --- a/103120/schema/json/ts_103120_Core.schema.json +++ b/103120/schema/json/ts_103120_Core.schema.json @@ -13,7 +13,8 @@ "Payload": { "$ref": "#/$defs/MessagePayload" }, - "Signature": { + "Signature": {}, + "xmldsig:Signature": { "$ref": "www.w3.org_2000_09_xmldsig##/$defs/SignatureType" } }, diff --git a/103120/schema/json/ts_103120_Delivery.schema.json b/103120/schema/json/ts_103120_Delivery.schema.json index 07ca697f..3d79eb28 100644 --- a/103120/schema/json/ts_103120_Delivery.schema.json +++ b/103120/schema/json/ts_103120_Delivery.schema.json @@ -33,23 +33,23 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "Reference": { + "delivery:Reference": { "$ref": "#/$defs/Reference" }, - "DeliveryID": { + "delivery:DeliveryID": { "$ref": "ts_103280_2017_07#/$defs/UUID" }, - "SequenceNumber": { + "delivery:SequenceNumber": { "type": "integer", "minimum": 0 }, - "LastSequence": { + "delivery:LastSequence": { "type": "boolean" }, - "Manifest": { + "delivery:Manifest": { "$ref": "#/$defs/Manifest" }, - "Delivery": { + "delivery:Delivery": { "$ref": "#/$defs/Delivery" } }, @@ -113,10 +113,10 @@ "ExternalSchema": { "type": "object", "properties": { - "ManifestID": { + "delivery:ManifestID": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "ManifestContents": { + "delivery:ManifestContents": { "$ref": "#/$defs/ManifestContents" } }, @@ -151,10 +151,10 @@ "SchemaContent": { "type": "object", "properties": { - "schema": {} + "delivery:schema": {} }, "required": [ - "schema" + "delivery:schema" ] }, "Delivery": { @@ -186,22 +186,22 @@ "EmbeddedBinaryData": { "type": "object", "properties": { - "Data": { + "delivery:Data": { "type": "string", "pattern": "^[-A-Za-z0-9+/]*={0,3}$" }, - "ContentType": { + "delivery:ContentType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "Checksum": { + "delivery:Checksum": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "ChecksumType": { + "delivery:ChecksumType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, "required": [ - "Data" + "delivery:Data" ] }, "EmbeddedXMLData": {} diff --git a/103120/schema/json/ts_103120_Document.schema.json b/103120/schema/json/ts_103120_Document.schema.json index fc85e137..f5b850b7 100644 --- a/103120/schema/json/ts_103120_Document.schema.json +++ b/103120/schema/json/ts_103120_Document.schema.json @@ -33,40 +33,40 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "DocumentReference": { + "document:DocumentReference": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "DocumentName": { + "document:DocumentName": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "DocumentStatus": { + "document:DocumentStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DocumentDesiredStatus": { + "document:DocumentDesiredStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DocumentTimespan": { + "document:DocumentTimespan": { "$ref": "#/$defs/DocumentTimespan" }, - "DocumentType": { + "document:DocumentType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DocumentProperties": { + "document:DocumentProperties": { "$ref": "#/$defs/DocumentProperties" }, - "DocumentBody": { + "document:DocumentBody": { "$ref": "#/$defs/DocumentBody" }, - "DocumentSignature": { + "document:DocumentSignature": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" } }, - "DocumentInvalidReason": { + "document:DocumentInvalidReason": { "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" }, - "NationalDocumentParameters": { + "document:NationalDocumentParameters": { "$ref": "#/$defs/NationalDocumentParameters" } }, @@ -78,10 +78,10 @@ "DocumentTimespan": { "type": "object", "properties": { - "StartTime": { + "document:StartTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "EndTime": { + "document:EndTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" } }, @@ -90,7 +90,7 @@ "DocumentProperties": { "type": "object", "properties": { - "DocumentProperty": { + "document:DocumentProperty": { "type": "array", "items": { "$ref": "#/$defs/DocumentProperty" @@ -102,32 +102,32 @@ "DocumentProperty": { "type": "object", "properties": { - "PropertyType": { + "document:PropertyType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "PropertyValue": { + "document:PropertyValue": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "PropertyType", - "PropertyValue" + "document:PropertyType", + "document:PropertyValue" ] }, "DocumentBody": { "type": "object", "properties": { - "Contents": { + "document:Contents": { "type": "string", "pattern": "^[-A-Za-z0-9+/]*={0,3}$" }, - "ContentType": { + "document:ContentType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "Checksum": { + "document:Checksum": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "ChecksumType": { + "document:ChecksumType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, @@ -136,12 +136,12 @@ "NationalDocumentParameters": { "type": "object", "properties": { - "CountryCode": { + "document:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "document:CountryCode" ] } } diff --git a/103120/schema/json/ts_103120_Notification.schema.json b/103120/schema/json/ts_103120_Notification.schema.json index dffab1a6..84fbf046 100644 --- a/103120/schema/json/ts_103120_Notification.schema.json +++ b/103120/schema/json/ts_103120_Notification.schema.json @@ -33,22 +33,22 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "NotificationDetails": { + "notification:NotificationDetails": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "NotificationType": { + "notification:NotificationType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "NewNotification": { + "notification:NewNotification": { "type": "boolean" }, - "NotificationTimestamp": { + "notification:NotificationTimestamp": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "StatusOfAssociatedObjects": { + "notification:StatusOfAssociatedObjects": { "$ref": "#/$defs/ListOfAssociatedObjectStatus" }, - "NationalNotificationParameters": { + "notification:NationalNotificationParameters": { "$ref": "#/$defs/NationalNotificationParameters" } }, @@ -60,7 +60,7 @@ "ListOfAssociatedObjectStatus": { "type": "object", "properties": { - "AssociatedObjectStatus": { + "notification:AssociatedObjectStatus": { "type": "array", "items": { "$ref": "#/$defs/AssociatedObjectStatus" @@ -73,30 +73,30 @@ "AssociatedObjectStatus": { "type": "object", "properties": { - "AssociatedObject": { + "notification:AssociatedObject": { "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" }, - "Status": { + "notification:Status": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "Details": { + "notification:Details": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "AssociatedObject", - "Status" + "notification:AssociatedObject", + "notification:Status" ] }, "NationalNotificationParameters": { "type": "object", "properties": { - "CountryCode": { + "notification:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "notification:CountryCode" ] } } diff --git a/103120/schema/json/ts_103120_Task.schema.json b/103120/schema/json/ts_103120_Task.schema.json index d19e1ee6..6854a613 100644 --- a/103120/schema/json/ts_103120_Task.schema.json +++ b/103120/schema/json/ts_103120_Task.schema.json @@ -33,49 +33,49 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "Reference": { + "task:Reference": { "$ref": "ts_103280_2017_07#/$defs/LIID" }, - "Status": { + "task:Status": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DesiredStatus": { + "task:DesiredStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "Timespan": { + "task:Timespan": { "$ref": "#/$defs/TaskTimespan" }, - "TargetIdentifier": { + "task:TargetIdentifier": { "$ref": "#/$defs/TargetIdentifier" }, - "DeliveryType": { + "task:DeliveryType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DeliveryDetails": { + "task:DeliveryDetails": { "$ref": "#/$defs/TaskDeliveryDetails" }, - "ApprovalDetails": { + "task:ApprovalDetails": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" } }, - "CSPID": { + "task:CSPID": { "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" }, - "HandlingProfile": { + "task:HandlingProfile": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "InvalidReason": { + "task:InvalidReason": { "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" }, - "Flags": { + "task:Flags": { "$ref": "#/$defs/TaskFlags" }, - "NationalLITaskingParameters": { + "task:NationalLITaskingParameters": { "$ref": "#/$defs/NationalLITaskingParameters" }, - "ListOfTrafficPolicyReferences": { + "task:ListOfTrafficPolicyReferences": { "$ref": "#/$defs/ListOfTrafficPolicyReferences" } }, @@ -87,19 +87,19 @@ "TaskTimespan": { "type": "object", "properties": { - "StartTime": { + "task:StartTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "EndTime": { + "task:EndTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "TerminationTime": { + "task:TerminationTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "ProvisioningTime": { + "task:ProvisioningTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "DeprovisioningTime": { + "task:DeprovisioningTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" } }, @@ -108,10 +108,10 @@ "TargetIdentifier": { "type": "object", "properties": { - "TargetIdentifierValues": { + "task:TargetIdentifierValues": { "$ref": "#/$defs/TargetIdentifierValues" }, - "ServiceType": { + "task:ServiceType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" } }, @@ -120,7 +120,7 @@ "TargetIdentifierValues": { "type": "object", "properties": { - "TargetIdentifierValue": { + "task:TargetIdentifierValue": { "type": "array", "items": { "$ref": "#/$defs/TargetIdentifierValue" @@ -133,37 +133,37 @@ "TargetIdentifierValue": { "type": "object", "properties": { - "FormatType": { + "task:FormatType": { "$ref": "#/$defs/FormatType" }, - "Value": { + "task:Value": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "FormatType", - "Value" + "task:FormatType", + "task:Value" ] }, "FormatType": { "type": "object", "properties": { - "FormatOwner": { + "task:FormatOwner": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "FormatName": { + "task:FormatName": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, "required": [ - "FormatOwner", - "FormatName" + "task:FormatOwner", + "task:FormatName" ] }, "TaskDeliveryDetails": { "type": "object", "properties": { - "DeliveryDestination": { + "task:DeliveryDestination": { "type": "array", "items": { "$ref": "#/$defs/DeliveryDestination" @@ -176,22 +176,22 @@ "DeliveryDestination": { "type": "object", "properties": { - "DeliveryAddress": { + "task:DeliveryAddress": { "$ref": "#/$defs/DeliveryAddress" }, - "EncryptionDetails": { + "task:EncryptionDetails": { "$ref": "#/$defs/NationalEncryptionDetails" }, - "IRIorCC": { + "task:IRIorCC": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "HandoverFormat": { + "task:HandoverFormat": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "DeliveryProfile": { + "task:DeliveryProfile": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "NationalDeliveryParameters": { + "task:NationalDeliveryParameters": { "$ref": "#/$defs/NationalDeliveryParameters" } }, @@ -325,7 +325,7 @@ "TaskFlags": { "type": "object", "properties": { - "TaskFlag": { + "task:TaskFlag": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" @@ -337,34 +337,34 @@ "NationalLITaskingParameters": { "type": "object", "properties": { - "CountryCode": { + "task:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "task:CountryCode" ] }, "NationalDeliveryParameters": { "type": "object", "properties": { - "CountryCode": { + "task:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "task:CountryCode" ] }, "NationalEncryptionDetails": { "type": "object", "properties": { - "CountryCode": { + "task:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "task:CountryCode" ] }, "LDTaskObject": { @@ -399,40 +399,40 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "Reference": { + "task:Reference": { "$ref": "ts_103280_2017_07#/$defs/LDID" }, - "Status": { + "task:Status": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "StatusReason": { + "task:StatusReason": { "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" }, - "DesiredStatus": { + "task:DesiredStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "RequestDetails": { + "task:RequestDetails": { "$ref": "#/$defs/RequestDetails" }, - "DeliveryDetails": { + "task:DeliveryDetails": { "$ref": "#/$defs/LDDeliveryDetails" }, - "ApprovalDetails": { + "task:ApprovalDetails": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" } }, - "CSPID": { + "task:CSPID": { "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" }, - "HandlingProfile": { + "task:HandlingProfile": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "Flags": { + "task:Flags": { "$ref": "#/$defs/LDTaskFlags" }, - "NationalLDTaskingParameters": { + "task:NationalLDTaskingParameters": { "$ref": "#/$defs/NationalLDTaskingParameters" } }, @@ -444,28 +444,28 @@ "RequestDetails": { "type": "object", "properties": { - "Type": { + "task:Type": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "StartTime": { + "task:StartTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "EndTime": { + "task:EndTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "ObservedTime": { + "task:ObservedTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "ObservedTimes": { + "task:ObservedTimes": { "type": "array", "items": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" } }, - "RequestValues": { + "task:RequestValues": { "$ref": "#/$defs/RequestValues" }, - "Subtype": { + "task:Subtype": { "$ref": "#/$defs/RequestSubtype" } }, @@ -474,7 +474,7 @@ "RequestValues": { "type": "object", "properties": { - "RequestValue": { + "task:RequestValue": { "type": "array", "items": { "$ref": "#/$defs/RequestValue" @@ -487,22 +487,22 @@ "RequestValue": { "type": "object", "properties": { - "FormatType": { + "task:FormatType": { "$ref": "#/$defs/FormatType" }, - "Value": { + "task:Value": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "FormatType", - "Value" + "task:FormatType", + "task:Value" ] }, "RequestSubtype": { "type": "object", "properties": { - "RequestSubtype": { + "task:RequestSubtype": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" @@ -515,7 +515,7 @@ "LDDeliveryDetails": { "type": "object", "properties": { - "LDDeliveryDestination": { + "task:LDDeliveryDestination": { "type": "array", "items": { "$ref": "#/$defs/LDDeliveryDestination" @@ -528,19 +528,19 @@ "LDDeliveryDestination": { "type": "object", "properties": { - "DeliveryAddress": { + "task:DeliveryAddress": { "$ref": "#/$defs/DeliveryAddress" }, - "EncryptionDetails": { + "task:EncryptionDetails": { "$ref": "#/$defs/NationalEncryptionDetails" }, - "LDHandoverFormat": { + "task:LDHandoverFormat": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "LDDeliveryProfile": { + "task:LDDeliveryProfile": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "NationalDeliveryParameters": { + "task:NationalDeliveryParameters": { "$ref": "#/$defs/NationalDeliveryParameters" } }, @@ -549,7 +549,7 @@ "LDTaskFlags": { "type": "object", "properties": { - "LDTaskFlag": { + "task:LDTaskFlag": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" @@ -561,18 +561,18 @@ "NationalLDTaskingParameters": { "type": "object", "properties": { - "CountryCode": { + "task:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "CountryCode" + "task:CountryCode" ] }, "ListOfTrafficPolicyReferences": { "type": "object", "properties": { - "TrafficPolicyReference": { + "task:TrafficPolicyReference": { "type": "array", "items": { "$ref": "#/$defs/TrafficPolicyReference" @@ -585,11 +585,11 @@ "TrafficPolicyReference": { "type": "object", "properties": { - "Order": { + "task:Order": { "type": "integer", "minimum": 1 }, - "ObjectIdentifier": { + "task:ObjectIdentifier": { "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" } }, diff --git a/103120/schema/json/ts_103120_TrafficPolicy.schema.json b/103120/schema/json/ts_103120_TrafficPolicy.schema.json index 53fe978d..2bbfc17c 100644 --- a/103120/schema/json/ts_103120_TrafficPolicy.schema.json +++ b/103120/schema/json/ts_103120_TrafficPolicy.schema.json @@ -33,10 +33,10 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "TrafficPolicyName": { + "tp:TrafficPolicyName": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "TrafficRules": { + "tp:TrafficRules": { "$ref": "#/$defs/ListOfTrafficRuleReferences" } }, @@ -48,7 +48,7 @@ "ListOfTrafficRuleReferences": { "type": "object", "properties": { - "TrafficRuleReference": { + "tp:TrafficRuleReference": { "type": "array", "items": { "$ref": "#/$defs/TrafficRuleReference" @@ -61,17 +61,17 @@ "TrafficRuleReference": { "type": "object", "properties": { - "Order": { + "tp:Order": { "type": "integer", "minimum": 1 }, - "ObjectIdentifier": { + "tp:ObjectIdentifier": { "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" } }, "required": [ - "Order", - "ObjectIdentifier" + "tp:Order", + "tp:ObjectIdentifier" ] }, "TrafficRuleObject": { @@ -106,10 +106,10 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "Criteria": { + "tp:Criteria": { "$ref": "#/$defs/ListOfTrafficCriteria" }, - "Action": { + "tp:Action": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" } }, @@ -121,7 +121,7 @@ "ListOfTrafficCriteria": { "type": "object", "properties": { - "Criteria": { + "tp:Criteria": { "type": "array", "items": { "$ref": "#/$defs/TrafficCriteria" @@ -160,23 +160,23 @@ "IPPolicyCriteria": { "type": "object", "properties": { - "IPProtocol": { + "tp:IPProtocol": { "type": "integer", "minimum": 0 }, - "SourceIPRange": { + "tp:SourceIPRange": { "$ref": "ts_103280_2017_07#/$defs/IPCIDR" }, - "SourcePortRange": { + "tp:SourcePortRange": { "$ref": "ts_103280_2017_07#/$defs/PortRange" }, - "DestinationIPRange": { + "tp:DestinationIPRange": { "$ref": "ts_103280_2017_07#/$defs/IPCIDR" }, - "DestinationPortRange": { + "tp:DestinationPortRange": { "$ref": "ts_103280_2017_07#/$defs/PortRange" }, - "BothDirections": { + "tp:BothDirections": { "type": "boolean" } }, @@ -185,10 +185,10 @@ "MobileAccessPolicyCriteria": { "type": "object", "properties": { - "APN": { + "tp:APN": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "DNN": { + "tp:DNN": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, diff --git a/test1.json b/test1.json new file mode 100644 index 00000000..6838b7d8 --- /dev/null +++ b/test1.json @@ -0,0 +1,90 @@ +{ + "@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", + "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", + "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", + "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", + "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", + "Header": { + "SenderIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR01" + }, + "ReceiverIdentifier": { + "CountryCode": "XX", + "UniqueIdentifier": "ACTOR02" + }, + "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", + "Timestamp": "2015-09-01T12:00:00.000000Z", + "Version": { + "ETSIVersion": "V1.13.1", + "NationalProfileOwner": "XX", + "NationalProfileVersion": "v1.0" + } + }, + "Payload": { + "RequestPayload": { + "ActionRequests": { + "ActionRequest": [ + { + "ActionIdentifier": 1, + "CREATE": { + "HI1Object": { + "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject", + "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "auth:AuthorisationReference": "W000001", + "auth:AuthorisationTimespan": { + "auth:StartTime": "2015-09-01T12:00:00Z", + "auth:EndTime": "2015-12-01T12:00:00Z" + } + } + } + }, + { + "ActionIdentifier": 2, + "CREATE": { + "HI1Object": { + "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Task}LITaskObject", + "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", + "CountryCode": "XX", + "OwnerIdentifier": "ACTOR01", + "AssociatedObjects": { + "AssociatedObject": "7dbbc880-8750-4d3c-abe7-ea4a17646045" + }, + "task:Reference": "LIID1", + "task:TargetIdentifier": { + "task:TargetIdentifierValues": { + "task:TargetIdentifierValue": { + "task:FormatType": { + "task:FormatOwner": "ETSI", + "task:FormatName": "InternationalE164" + }, + "task:Value": "442079460223" + } + } + }, + "task:DeliveryType": { + "common:Owner": "ETSI", + "common:Name": "TaskDeliveryType", + "common:Value": "IRIandCC" + }, + "task:DeliveryDetails": { + "task:DeliveryDestination": { + "task:DeliveryAddress": { + "task:IPv4Address": "192.0.2.0" + } + } + }, + "task:CSPID": { + "CountryCode": "XX", + "UniqueIdentifier": "RECVER01" + } + } + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/test2.json b/test2.json new file mode 100644 index 00000000..bf5b94cc --- /dev/null +++ b/test2.json @@ -0,0 +1 @@ +{"@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", "Header": {"SenderIdentifier": {"CountryCode": "XX", "UniqueIdentifier": "ACTOR01"}, "ReceiverIdentifier": {"CountryCode": "XX", "UniqueIdentifier": "ACTOR02"}, "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", "Timestamp": "2015-09-01T12:00:00.000000Z", "Version": {"ETSIVersion": "V1.13.1", "NationalProfileOwner": "XX", "NationalProfileVersion": "v1.0"}}, "Payload": {"RequestPayload": {"ActionRequests": {"ActionRequest": [{"ActionIdentifier": "0", "CREATE": {"HI1Object": {"@xsi:type": "auth:AuthorisationObject", "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", "CountryCode": "XX", "OwnerIdentifier": "ACTOR01", "auth:AuthorisationReference": "W000001", "auth:AuthorisationTimespan": {"auth:StartTime": "2015-09-01T12:00:00Z", "auth:EndTime": "2015-12-01T12:00:00Z"}}}}, {"ActionIdentifier": "1", "CREATE": {"HI1Object": {"@xsi:type": "task:LITaskObject", "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", "CountryCode": "XX", "OwnerIdentifier": "ACTOR01", "AssociatedObjects": {"AssociatedObject": ["7dbbc880-8750-4d3c-abe7-ea4a17646045", "7dbbc880-8750-4d3c-abe7-ea4a17646045"]}, "task:Reference": "LIID1", "task:TargetIdentifier": {"task:TargetIdentifierValues": {"task:TargetIdentifierValue": {"task:FormatType": {"task:FormatOwner": "ETSI", "task:FormatName": "InternationalE164"}, "task:Value": "442079460223"}}}, "task:DeliveryType": {"common:Owner": "ETSI", "common:Name": "TaskDeliveryType", "common:Value": "IRIandCC"}, "task:DeliveryDetails": {"task:DeliveryDestination": {"task:DeliveryAddress": {"task:IPv4Address": "192.0.2.0"}}}, "task:CSPID": {"CountryCode": "XX", "UniqueIdentifier": "RECVER01"}}}}]}}}} diff --git a/utils/request.fragment.schema.json b/utils/request.fragment.schema.json new file mode 100644 index 00000000..dc2bb14c --- /dev/null +++ b/utils/request.fragment.schema.json @@ -0,0 +1,4 @@ +{ + "$id": "fragment_request", + "$ref" : "#/$defs/RequestPayload" +} \ No newline at end of file diff --git a/utils/translate/SequenceMapping.py b/utils/translate/SequenceMapping.py index 91db5ea9..9fd4d694 100644 --- a/utils/translate/SequenceMapping.py +++ b/utils/translate/SequenceMapping.py @@ -45,23 +45,29 @@ class SequenceMapping(ComplexTypeMapping): inner_choice = None for c in list(content.iter_model()): log.debug(f"Processing model item {c}") + print("Model item -------------") if type(c) is XsdElement: + element_name = c.local_name + if c.target_namespace in self.ns_to_id_map: + ns = self.ns_to_id_map[c.target_namespace] + if 'prefix' in ns: + element_name = ns['prefix'] + ":" + element_name if c.effective_max_occurs != 1: - mapped_type['properties'][c.local_name] = { + mapped_type['properties'][element_name] = { "type" : "array", "items" : TypeMapping.get_type_from_elem(c, xst.namespaces['']) } if c.effective_max_occurs: - mapped_type['properties'][c.local_name]['maxItems'] = c.effective_max_occurs + mapped_type['properties'][element_name]['maxItems'] = c.effective_max_occurs if c.effective_min_occurs > 0: - mapped_type['properties'][c.local_name]['minItems'] = c.effective_min_occurs + mapped_type['properties'][element_name]['minItems'] = c.effective_min_occurs else: - mapped_type['properties'][c.local_name] = TypeMapping.get_type_from_elem(c, xst.namespaces['']) + mapped_type['properties'][element_name] = TypeMapping.get_type_from_elem(c, xst.namespaces['']) if c.effective_min_occurs == 1: - mapped_type['required'].append(c.local_name) + mapped_type['required'].append(element_name) elif type(c) is XsdGroup: if inner_choice: - raise Exception (f"Second group '{c.local_name}' encountered in {xst}") + raise Exception (f"Second group '{element_name}' encountered in {xst}") if c.model != "choice": raise Exception (f"Don't know what to do with inner group {c} in {xst} - not a choice") inner_choice = ChoiceMapping.process_choice(c, xst.namespaces['']) diff --git a/utils/translate/TypeMapping.py b/utils/translate/TypeMapping.py index b796e66b..e3daf622 100644 --- a/utils/translate/TypeMapping.py +++ b/utils/translate/TypeMapping.py @@ -50,7 +50,7 @@ class TypeMapping(ABC): return { "$ref" : f"#/$defs/{xsd_type.local_name}" } else: mapped_id = cls.ns_to_id_map[ns] - return { "$ref" : f"{mapped_id}#/$defs/{xsd_type.local_name}"} + return { "$ref" : f"{mapped_id['id']}#/$defs/{xsd_type.local_name}"} @classmethod def get_type_from_elem(cls, elem: XsdElement, current_ns : str): diff --git a/utils/translate/__init__.py b/utils/translate/__init__.py index 983aa205..ba05008f 100644 --- a/utils/translate/__init__.py +++ b/utils/translate/__init__.py @@ -27,7 +27,7 @@ def translate_schema (schema_path: str, ns_to_id_map: dict, schema_locations = [ xs = XMLSchema(schema_path, validation='lax', locations=schema_locations) logging.info(f"Schema namespace: {xs.target_namespace}" ) - schema_id = ns_to_id_map[xs.target_namespace] + schema_id = ns_to_id_map[xs.target_namespace]["id"] js['$id'] = schema_id TypeMapping.ns_to_id_map = ns_to_id_map diff --git a/utils/translate_spec.py b/utils/translate_spec.py index 8f890934..54ac5cd4 100644 --- a/utils/translate_spec.py +++ b/utils/translate_spec.py @@ -8,8 +8,6 @@ from xmlschema import * from translate import * -import jsonschema - logging.basicConfig(level = logging.INFO) def build_schema_locations (paths): @@ -46,24 +44,22 @@ if __name__ == "__main__": config = get_json(sys.argv[1]) - schema_paths = config['schemas'] - logging.info("Bulding schema locations...") - schema_locations = build_schema_locations(schema_paths) + + logging.info("Bulding ns map...") + ns_map = {} + for location, settings in config['schemas'].items(): + xs = XMLSchema(location, validation='skip') + ns = xs.target_namespace + id = convert_ns_to_id(ns) + ns_map[ns] = { + "id" : id, + "location" : str(Path(location).resolve()) + } | settings + logging.debug(ns_map) + + logging.info("Building schema locations") + schema_locations = [(k, v["location"]) for k,v in ns_map.items()] logging.debug(schema_locations) - - # ns_to_id_map = { - # schema[0]: schema[0].split('/')[-1].lower() + ".json" - # for schema in schema_locations if '03120' in schema[0] - # } | { - # 'http://uri.etsi.org/03280/common/2017/07' : 'etsi103280.json', - # 'http://www.w3.org/2000/09/xmldsig#' : 'xmldsig.json', - # } - logging.info("Constructing XSD NS to JSON Schema ID mapping...") - ns_to_id_map = { schema[0] : convert_ns_to_id(schema[0]) for schema in schema_locations} - logging.debug(ns_to_id_map) - - # # js = translate_schema("103280/TS_103_280.xsd", "103120.json") - # # print(json.dumps(js, indent=2)) output_path = Path(config['output']) if not output_path.exists(): @@ -78,13 +74,14 @@ if __name__ == "__main__": # TODO - work out what to do here logging.info(" Skipping XML Dsig...") continue - js = translate_schema(schema_tuple[1], ns_to_id_map, schema_locations) - if ns_to_id_map[schema_tuple[0]] == 'core.json': + js = translate_schema(schema_tuple[1], ns_map, schema_locations) + + # TODO - Special case, get rid of signature + if ns_map[schema_tuple[0]] == 'core.json': js['$defs']['HI1Message']['properties'].pop('Signature') js_path = output_path / convert_xsd_to_filename(schema_tuple[1]) - # TODO - work out how to do this substitution automatically - # and build the graph of acceptable descendent types + # TODO - Special case - abstract HI1Object if "Core" in schema_tuple[1]: js["$defs"]['ConcreteHI1Object'] = { 'oneOf' : [ @@ -106,17 +103,3 @@ if __name__ == "__main__": with open(str(js_path), 'w') as f: f.write(json_string) json_schemas[js['$id']] = json.loads(json_string) - - # else: - # json_schemas = {} - # json_path = Path('json/') - # for json_file in json_path.glob("*.json"): - # json_schemas[json_file.name] = get_json(json_file) - - # resolver = jsonschema.RefResolver("", "", json_schemas) - - # instance = get_json("120.json") - # schema = json_schemas['core.json'] - # jsonschema.validate(instance, schema, resolver=resolver) - - # print(json.dumps(js, indent=2)) diff --git a/utils/ts103120_config.json b/utils/ts103120_config.json index 08aadb87..ec321710 100644 --- a/utils/ts103120_config.json +++ b/utils/ts103120_config.json @@ -1,14 +1,36 @@ { - "schemas" : [ "../103120/schema/ts_103120_Authorisation.xsd", - "../103120/schema/ts_103120_Common.xsd", - "../103120/schema/ts_103120_Core.xsd", - "../103120/schema/ts_103120_Delivery.xsd", - "../103120/schema/ts_103120_Document.xsd", - "../103120/schema/ts_103120_Notification.xsd", - "../103120/schema/ts_103120_Task.xsd", - "../103120/schema/ts_103120_TrafficPolicy.xsd", - "../103280/TS_103_280.xsd", - "../testing/deps/xmldsig/xmldsig-core-schema.xsd" - ], - "output" : "../103120/schema/json/" + "schemas" : { + "./103120/schema/ts_103120_Authorisation.xsd" : { + "prefix" : "auth" + }, + "./103120/schema/ts_103120_Common.xsd" : { + "prefix" : "common" + }, + "./103120/schema/ts_103120_Core.xsd" : { + }, + "./103120/schema/ts_103120_Delivery.xsd" : { + "prefix" : "delivery" + }, + "./103120/schema/ts_103120_Document.xsd" : { + "prefix" : "document" + }, + "./103120/schema/ts_103120_Notification.xsd" : { + "prefix" : "notification" + }, + "./103120/schema/ts_103120_Task.xsd" : { + "prefix" : "task" + }, + "./103120/schema/ts_103120_TrafficPolicy.xsd" : { + "prefix" : "tp" + }, + "./103280/TS_103_280.xsd" : { + "prefix" : "etsi280", + "skip" : true + }, + "./testing/deps/xmldsig/xmldsig-core-schema.xsd" : { + "prefix" : "xmldsig", + "skip" : true + } + }, + "output" : "./103120/schema/json/" } \ No newline at end of file diff --git a/utils/validate.py b/utils/validate.py index c8326310..17070bbb 100644 --- a/utils/validate.py +++ b/utils/validate.py @@ -1,5 +1,6 @@ import sys from jsonschema import validate, RefResolver, Draft202012Validator +from jsonschema.exceptions import ValidationError import json from pathlib import Path import logging @@ -41,6 +42,8 @@ if __name__ == "__main__": if args.schemadir: schema_paths = [] for d in args.schemadir: + logging.info(f"Searching {d}") + logging.info(list(Path(d).rglob("*.schema.json"))) schema_paths += [f for f in Path(d).rglob("*.schema.json")] logging.info(f"Schema files loaded: {schema_paths}") @@ -57,7 +60,61 @@ if __name__ == "__main__": store=schema_dict) v = Draft202012Validator(main_schema, resolver=resolver) + try: + v.validate(instance_doc) + except ValidationError as ex: + # Any failure within the Payload element results in a failure against the oneOf constraint in the Payload element + # This isn't terribly helpful in working out what is actually wrong, so in this case we attempt an explicit + # validation against the relevant oneOf alternation to try and get a more useful validation error + if list(ex.schema_path) == ['properties', 'Payload', 'oneOf']: + logging.error ("Error detected validating payload oneOf - attempting explicit validation...") + try: + if 'RequestPayload' in instance_doc['Payload'].keys(): + request_fragment_schema = { "$ref" : "ts_103120_Core_2019_10#/$defs/RequestPayload" } + v = Draft202012Validator(request_fragment_schema, resolver=resolver) + v.validate(instance_doc['Payload']['RequestPayload']) + elif 'ResponsePayload' in instance_doc['Payload'].keys(): + request_fragment_schema = { "$ref" : "ts_103120_Core_2019_10#/$defs/ResponsePayload" } + v = Draft202012Validator(request_fragment_schema, resolver=resolver) + v.validate(instance_doc['Payload']['ResponsePayload']) + else: + logging.error("No RequestPayload or ResponsePayload found - is the Payload malformed?") + raise ex + except ValidationError as ex2: + # Similar to above, this is inner validation to try and get a more useful error in the event + # that something fails the verb oneOf constraint + logging.error("Error detected in ActionRequests/ActionResponses") + error_path = list(ex2.schema_path) + if error_path != ['properties', 'ActionRequests', 'properties', 'ActionRequest', 'items', 'allOf', 1, 'oneOf'] and error_path != ['properties', 'ActionResponses', 'properties', 'ActionResponse', 'items', 'allOf', 1, 'oneOf']: + logging.error("Error not in inner Request/Response allOf/oneOf constraint") + raise ex2 + j = ex2.instance + j.pop('ActionIdentifier') # Remove ActionIdentifier - one remaining key will be the verb + verb = list(j.keys())[0] + message = "Request" if error_path[1] == "ActionRequests" else "Response" + v = Draft202012Validator({"$ref" : f"ts_103120_Core_2019_10#/$defs/{verb}{message}"}, resolver=resolver) + try: + v.validate(j[verb]) + except ValidationError as ex3: + logging.error("Error detected in verb") + # The final level of validation is for the actual HI1Object validation + if list(ex3.schema_path) != ['properties', 'HI1Object', 'oneOf']: + logging.error("Error not inside HI1Object") + raise ex3 + object_type = ex3.instance['@xsi:type'].split('}')[-1] + object_ref = { + 'AuthorisationObject': 'ts_103120_Authorisation_2020_09#/$defs/AuthorisationObject', + 'LITaskObject': 'ts_103120_Task_2020_09#/$defs/LITaskObject', + 'LDTaskObject': 'ts_103120_Task_2020_09#/$defs/LDTaskObject', + 'DocumentObject': 'ts_103120_Document_2020_09#/$defs/DocumentObject', + 'NotificationObject': 'ts_103120_Notification_2016_02#/$defs/NotificationObject', + 'DeliveryObject': 'ts_103120_Delivery_2019_10#/$defs/DeliveryObject', + 'TrafficPolicyObject': 'ts_103120_TrafficPolicy_2022_07#/$defs/TrafficPolicyObject' + }[object_type] + v = Draft202012Validator({"$ref" : object_ref}, resolver=resolver) + v.validate(ex3.instance) + + exit(-1) - v.validate(instance_doc) logging.info("Done") \ No newline at end of file diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index b8c9e275..ac32d7ec 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -49,9 +49,15 @@ if __name__ == "__main__": args.input.close() logging.debug(s) - d = xmltodict.parse(s)['HI1Message'] - - prefixes = extract_prefixes(d) - removePrefixes(d, prefixes) + # d = xmltodict.parse(s, + # force_list=('AssociatedObject',) + # )['HI1Message'] - print(json.dumps(d)) + d = xmltodict.parse(s, + force_list=('AssociatedObject',) + )['HI1Message'] + + # prefixes = extract_prefixes(d) + # removePrefixes(d, prefixes) + + print(json.dumps(d, indent=2)) -- GitLab From 25b554c8c8d54e2866643316da4bd65ef46dd437 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 2 Jun 2023 12:43:01 +0100 Subject: [PATCH 09/15] Tidying up a bit --- test1.json | 90 ------------------------------------------------------ test2.json | 1 - 2 files changed, 91 deletions(-) delete mode 100644 test1.json delete mode 100644 test2.json diff --git a/test1.json b/test1.json deleted file mode 100644 index 6838b7d8..00000000 --- a/test1.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", - "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", - "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", - "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", - "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", - "Header": { - "SenderIdentifier": { - "CountryCode": "XX", - "UniqueIdentifier": "ACTOR01" - }, - "ReceiverIdentifier": { - "CountryCode": "XX", - "UniqueIdentifier": "ACTOR02" - }, - "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", - "Timestamp": "2015-09-01T12:00:00.000000Z", - "Version": { - "ETSIVersion": "V1.13.1", - "NationalProfileOwner": "XX", - "NationalProfileVersion": "v1.0" - } - }, - "Payload": { - "RequestPayload": { - "ActionRequests": { - "ActionRequest": [ - { - "ActionIdentifier": 1, - "CREATE": { - "HI1Object": { - "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Authorisation}AuthorisationObject", - "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", - "CountryCode": "XX", - "OwnerIdentifier": "ACTOR01", - "auth:AuthorisationReference": "W000001", - "auth:AuthorisationTimespan": { - "auth:StartTime": "2015-09-01T12:00:00Z", - "auth:EndTime": "2015-12-01T12:00:00Z" - } - } - } - }, - { - "ActionIdentifier": 2, - "CREATE": { - "HI1Object": { - "@xsi:type": "{http://uri.etsi.org/03120/common/2020/09/Task}LITaskObject", - "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", - "CountryCode": "XX", - "OwnerIdentifier": "ACTOR01", - "AssociatedObjects": { - "AssociatedObject": "7dbbc880-8750-4d3c-abe7-ea4a17646045" - }, - "task:Reference": "LIID1", - "task:TargetIdentifier": { - "task:TargetIdentifierValues": { - "task:TargetIdentifierValue": { - "task:FormatType": { - "task:FormatOwner": "ETSI", - "task:FormatName": "InternationalE164" - }, - "task:Value": "442079460223" - } - } - }, - "task:DeliveryType": { - "common:Owner": "ETSI", - "common:Name": "TaskDeliveryType", - "common:Value": "IRIandCC" - }, - "task:DeliveryDetails": { - "task:DeliveryDestination": { - "task:DeliveryAddress": { - "task:IPv4Address": "192.0.2.0" - } - } - }, - "task:CSPID": { - "CountryCode": "XX", - "UniqueIdentifier": "RECVER01" - } - } - } - } - ] - } - } - } -} \ No newline at end of file diff --git a/test2.json b/test2.json deleted file mode 100644 index bf5b94cc..00000000 --- a/test2.json +++ /dev/null @@ -1 +0,0 @@ -{"@xmlns": "http://uri.etsi.org/03120/common/2019/10/Core", "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "@xmlns:common": "http://uri.etsi.org/03120/common/2016/02/Common", "@xmlns:task": "http://uri.etsi.org/03120/common/2020/09/Task", "@xmlns:auth": "http://uri.etsi.org/03120/common/2020/09/Authorisation", "Header": {"SenderIdentifier": {"CountryCode": "XX", "UniqueIdentifier": "ACTOR01"}, "ReceiverIdentifier": {"CountryCode": "XX", "UniqueIdentifier": "ACTOR02"}, "TransactionIdentifier": "c02358b2-76cf-4ba4-a8eb-f6436ccaea2e", "Timestamp": "2015-09-01T12:00:00.000000Z", "Version": {"ETSIVersion": "V1.13.1", "NationalProfileOwner": "XX", "NationalProfileVersion": "v1.0"}}, "Payload": {"RequestPayload": {"ActionRequests": {"ActionRequest": [{"ActionIdentifier": "0", "CREATE": {"HI1Object": {"@xsi:type": "auth:AuthorisationObject", "ObjectIdentifier": "7dbbc880-8750-4d3c-abe7-ea4a17646045", "CountryCode": "XX", "OwnerIdentifier": "ACTOR01", "auth:AuthorisationReference": "W000001", "auth:AuthorisationTimespan": {"auth:StartTime": "2015-09-01T12:00:00Z", "auth:EndTime": "2015-12-01T12:00:00Z"}}}}, {"ActionIdentifier": "1", "CREATE": {"HI1Object": {"@xsi:type": "task:LITaskObject", "ObjectIdentifier": "2b36a78b-b628-416d-bd22-404e68a0cd36", "CountryCode": "XX", "OwnerIdentifier": "ACTOR01", "AssociatedObjects": {"AssociatedObject": ["7dbbc880-8750-4d3c-abe7-ea4a17646045", "7dbbc880-8750-4d3c-abe7-ea4a17646045"]}, "task:Reference": "LIID1", "task:TargetIdentifier": {"task:TargetIdentifierValues": {"task:TargetIdentifierValue": {"task:FormatType": {"task:FormatOwner": "ETSI", "task:FormatName": "InternationalE164"}, "task:Value": "442079460223"}}}, "task:DeliveryType": {"common:Owner": "ETSI", "common:Name": "TaskDeliveryType", "common:Value": "IRIandCC"}, "task:DeliveryDetails": {"task:DeliveryDestination": {"task:DeliveryAddress": {"task:IPv4Address": "192.0.2.0"}}}, "task:CSPID": {"CountryCode": "XX", "UniqueIdentifier": "RECVER01"}}}}]}}}} -- GitLab From 6b3953e673df0a0cff727eeff5eb155dfd0a92ee Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 2 Jun 2023 14:07:08 +0100 Subject: [PATCH 10/15] Fixing namespace qualifiers for choice --- 103120/schema/json/TS_103_280.schema.json | 389 ++++++++++++++++++ .../schema/json/ts_103120_Common.schema.json | 8 +- .../json/ts_103120_Delivery.schema.json | 32 +- 103120/schema/json/ts_103120_Task.schema.json | 44 +- .../json/ts_103120_TrafficPolicy.schema.json | 8 +- utils/translate/ChoiceMapping.py | 13 +- utils/translate/SequenceMapping.py | 2 +- utils/xml_to_json.py | 60 ++- 8 files changed, 501 insertions(+), 55 deletions(-) create mode 100644 103120/schema/json/TS_103_280.schema.json diff --git a/103120/schema/json/TS_103_280.schema.json b/103120/schema/json/TS_103_280.schema.json new file mode 100644 index 00000000..02cd078e --- /dev/null +++ b/103120/schema/json/TS_103_280.schema.json @@ -0,0 +1,389 @@ +{ + "$id": "ts_103280_2017_07", + "$defs": { + "ShortString": { + "type": "string", + "maxLength": 255 + }, + "LongString": { + "type": "string", + "maxLength": 65535 + }, + "LIID": { + "type": "string", + "pattern": "^([!-~]{1,25})|([0-9a-f]{26,50})$" + }, + "UTCDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + }, + "UTCMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}Z$" + }, + "QualifiedDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "QualifiedMicrosecondDateTime": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6}(Z|[+-][0-9]{2}:[0-9]{2})$" + }, + "InternationalE164": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "IMSI": { + "type": "string", + "pattern": "^[0-9]{6,15}$" + }, + "IMEI": { + "type": "string", + "pattern": "^[0-9]{14}$" + }, + "IMEICheckDigit": { + "type": "string", + "pattern": "^[0-9]{15}$" + }, + "IMEISV": { + "type": "string", + "pattern": "^[0-9]{16}$" + }, + "IPv4Address": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$" + }, + "IPv4CIDR": { + "type": "string", + "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/([1-2]?[0-9]|3[0-2])$" + }, + "IPv6Address": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})$" + }, + "IPv6CIDR": { + "type": "string", + "pattern": "^([0-9a-f]{4}:){7}([0-9a-f]{4})/(([1-9][0-9]?)|(1[0-1][0-9])|(12[0-8]))$" + }, + "TCPPort": { + "type": "integer", + "exclusiveMinimum": 1, + "maximum": 65535 + }, + "UDPPort": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "MACAddress": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" + }, + "EmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^[a-zA-Z0-9\\.!#$%&'\\*\\+\\\\/=\\?\\^_`\\{\\|\\}~\\-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" + } + ] + }, + "UUID": { + "type": "string", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" + }, + "ISOCountryCode": { + "type": "string", + "pattern": "^[A-Z]{2}$" + }, + "SIPURI": { + "type": "string", + "pattern": "^sips?:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "TELURI": { + "type": "string", + "pattern": "^tel:[a-zA-Z0-9!#$&-;=?-\\[\\]_~%]+$" + }, + "WGS84LatitudeDecimal": { + "type": "string", + "pattern": "^[NS][0-9]{2}\\.[0-9]{6}$" + }, + "WGS84LongitudeDecimal": { + "type": "string", + "pattern": "^[EW][0-9]{3}\\.[0-9]{6}$" + }, + "WGS84LatitudeAngular": { + "type": "string", + "pattern": "^[NS][0-9]{6}\\.[0-9]{2}$" + }, + "WGS84LongitudeAngular": { + "type": "string", + "pattern": "^[EW][0-9]{7}\\.[0-9]{2}$" + }, + "SUPIIMSI": { + "$ref": "#/$defs/IMSI" + }, + "SUPINAI": { + "$ref": "#/$defs/NAI" + }, + "SUCI": { + "type": "string", + "pattern": "^([a-fA-F0-9]{2})*$" + }, + "PEIIMEI": { + "$ref": "#/$defs/IMEI" + }, + "PEIIMEICheckDigit": { + "$ref": "#/$defs/IMEICheckDigit" + }, + "PEIIMEISV": { + "$ref": "#/$defs/IMEISV" + }, + "GPSIMSISDN": { + "type": "string", + "pattern": "^[0-9]{1,15}$" + }, + "GPSINAI": { + "$ref": "#/$defs/NAI" + }, + "NAI": { + "type": "string" + }, + "LDID": { + "type": "string", + "pattern": "^([A-Z]{2}-.+-.+)$" + }, + "InternationalizedEmailAddress": { + "allOf": [ + { + "$ref": "#/$defs/ShortString" + }, + { + "type": "string", + "pattern": "^.+@.+$" + } + ] + }, + "EUI64": { + "type": "string", + "pattern": "^([a-f0-9]{2}:){7}[a-f0-9]{2}$" + }, + "CGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{4}-[a-f0-9]{4}$" + }, + "ECGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{7}$" + }, + "NCGI": { + "type": "string", + "pattern": "^[0-9]{3}-[0-9]{2,3}-[a-f0-9]{9}$" + }, + "ICCID": { + "type": "string", + "pattern": "^[0-9]{19,20}$" + }, + "IPProtocol": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "IPAddress": { + "oneOf": [ + { + "type": "object", + "properties": { + "etsi280:IPv4Address": { + "$ref": "#/$defs/IPv4Address" + } + }, + "required": [ + "etsi280:IPv4Address" + ] + }, + { + "type": "object", + "properties": { + "etsi280:IPv6Address": { + "$ref": "#/$defs/IPv6Address" + } + }, + "required": [ + "etsi280:IPv6Address" + ] + } + ] + }, + "IPCIDR": { + "oneOf": [ + { + "type": "object", + "properties": { + "etsi280:IPv4CIDR": { + "$ref": "#/$defs/IPv4CIDR" + } + }, + "required": [ + "etsi280:IPv4CIDR" + ] + }, + { + "type": "object", + "properties": { + "etsi280:IPv6CIDR": { + "$ref": "#/$defs/IPv6CIDR" + } + }, + "required": [ + "etsi280:IPv6CIDR" + ] + } + ] + }, + "TCPPortRange": { + "type": "object", + "properties": { + "etsi280:start": { + "$ref": "#/$defs/TCPPort" + }, + "etsi280:end": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "etsi280:start", + "etsi280:end" + ] + }, + "UDPPortRange": { + "type": "object", + "properties": { + "etsi280:start": { + "$ref": "#/$defs/UDPPort" + }, + "etsi280:end": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "etsi280:start", + "etsi280:end" + ] + }, + "Port": { + "oneOf": [ + { + "type": "object", + "properties": { + "etsi280:TCPPort": { + "$ref": "#/$defs/TCPPort" + } + }, + "required": [ + "etsi280:TCPPort" + ] + }, + { + "type": "object", + "properties": { + "etsi280:UDPPort": { + "$ref": "#/$defs/UDPPort" + } + }, + "required": [ + "etsi280:UDPPort" + ] + } + ] + }, + "PortRange": { + "oneOf": [ + { + "type": "object", + "properties": { + "etsi280:TCPPortRange": { + "$ref": "#/$defs/TCPPortRange" + } + }, + "required": [ + "etsi280:TCPPortRange" + ] + }, + { + "type": "object", + "properties": { + "etsi280:UDPPortRange": { + "$ref": "#/$defs/UDPPortRange" + } + }, + "required": [ + "etsi280:UDPPortRange" + ] + } + ] + }, + "IPAddressPort": { + "type": "object", + "properties": { + "etsi280:address": { + "$ref": "#/$defs/IPAddress" + }, + "etsi280:port": { + "$ref": "#/$defs/Port" + } + }, + "required": [ + "etsi280:address", + "etsi280:port" + ] + }, + "IPAddressPortRange": { + "type": "object", + "properties": { + "etsi280:address": { + "$ref": "#/$defs/IPAddress" + }, + "etsi280:portRange": { + "$ref": "#/$defs/PortRange" + } + }, + "required": [ + "etsi280:address", + "etsi280:portRange" + ] + }, + "WGS84CoordinateDecimal": { + "type": "object", + "properties": { + "etsi280:latitude": { + "$ref": "#/$defs/WGS84LatitudeDecimal" + }, + "etsi280:longitude": { + "$ref": "#/$defs/WGS84LongitudeDecimal" + } + }, + "required": [ + "etsi280:latitude", + "etsi280:longitude" + ] + }, + "WGS84CoordinateAngular": { + "type": "object", + "properties": { + "etsi280:latitude": { + "$ref": "#/$defs/WGS84LatitudeAngular" + }, + "etsi280:longitude": { + "$ref": "#/$defs/WGS84LongitudeAngular" + } + }, + "required": [ + "etsi280:latitude", + "etsi280:longitude" + ] + } + } +} \ No newline at end of file diff --git a/103120/schema/json/ts_103120_Common.schema.json b/103120/schema/json/ts_103120_Common.schema.json index 2564e8db..d11b4b4c 100644 --- a/103120/schema/json/ts_103120_Common.schema.json +++ b/103120/schema/json/ts_103120_Common.schema.json @@ -87,12 +87,12 @@ { "type": "object", "properties": { - "NationalApproverIdentity": { + "common:NationalApproverIdentity": { "$ref": "#/$defs/NationalApproverIdentity" } }, "required": [ - "NationalApproverIdentity" + "common:NationalApproverIdentity" ] } ] @@ -128,12 +128,12 @@ { "type": "object", "properties": { - "NationalDigitalSignature": { + "common:NationalDigitalSignature": { "$ref": "#/$defs/NationalDigitalSignature" } }, "required": [ - "NationalDigitalSignature" + "common:NationalDigitalSignature" ] } ] diff --git a/103120/schema/json/ts_103120_Delivery.schema.json b/103120/schema/json/ts_103120_Delivery.schema.json index 3d79eb28..9cfceae2 100644 --- a/103120/schema/json/ts_103120_Delivery.schema.json +++ b/103120/schema/json/ts_103120_Delivery.schema.json @@ -63,23 +63,23 @@ { "type": "object", "properties": { - "LDID": { + "delivery:LDID": { "$ref": "ts_103280_2017_07#/$defs/LDID" } }, "required": [ - "LDID" + "delivery:LDID" ] }, { "type": "object", "properties": { - "LIID": { + "delivery:LIID": { "$ref": "ts_103280_2017_07#/$defs/LIID" } }, "required": [ - "LIID" + "delivery:LIID" ] } ] @@ -89,23 +89,23 @@ { "type": "object", "properties": { - "Specification": { + "delivery:Specification": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" } }, "required": [ - "Specification" + "delivery:Specification" ] }, { "type": "object", "properties": { - "ExternalSchema": { + "delivery:ExternalSchema": { "$ref": "#/$defs/ExternalSchema" } }, "required": [ - "ExternalSchema" + "delivery:ExternalSchema" ] } ] @@ -127,23 +127,23 @@ { "type": "object", "properties": { - "BinaryData": { + "delivery:BinaryData": { "$ref": "#/$defs/EmbeddedBinaryData" } }, "required": [ - "BinaryData" + "delivery:BinaryData" ] }, { "type": "object", "properties": { - "XMLSchema": { + "delivery:XMLSchema": { "$ref": "#/$defs/SchemaContent" } }, "required": [ - "XMLSchema" + "delivery:XMLSchema" ] } ] @@ -162,23 +162,23 @@ { "type": "object", "properties": { - "BinaryData": { + "delivery:BinaryData": { "$ref": "#/$defs/EmbeddedBinaryData" } }, "required": [ - "BinaryData" + "delivery:BinaryData" ] }, { "type": "object", "properties": { - "XMLData": { + "delivery:XMLData": { "$ref": "#/$defs/EmbeddedXMLData" } }, "required": [ - "XMLData" + "delivery:XMLData" ] } ] diff --git a/103120/schema/json/ts_103120_Task.schema.json b/103120/schema/json/ts_103120_Task.schema.json index 6854a613..24de4c57 100644 --- a/103120/schema/json/ts_103120_Task.schema.json +++ b/103120/schema/json/ts_103120_Task.schema.json @@ -202,122 +202,122 @@ { "type": "object", "properties": { - "IPv4Address": { + "task:IPv4Address": { "$ref": "ts_103280_2017_07#/$defs/IPv4Address" } }, "required": [ - "IPv4Address" + "task:IPv4Address" ] }, { "type": "object", "properties": { - "IPv6Address": { + "task:IPv6Address": { "$ref": "ts_103280_2017_07#/$defs/IPv6Address" } }, "required": [ - "IPv6Address" + "task:IPv6Address" ] }, { "type": "object", "properties": { - "IPAddressPort": { + "task:IPAddressPort": { "$ref": "ts_103280_2017_07#/$defs/IPAddressPort" } }, "required": [ - "IPAddressPort" + "task:IPAddressPort" ] }, { "type": "object", "properties": { - "IPAddressPortRange": { + "task:IPAddressPortRange": { "$ref": "ts_103280_2017_07#/$defs/IPAddressPortRange" } }, "required": [ - "IPAddressPortRange" + "task:IPAddressPortRange" ] }, { "type": "object", "properties": { - "E164Number": { + "task:E164Number": { "$ref": "ts_103280_2017_07#/$defs/InternationalE164" } }, "required": [ - "E164Number" + "task:E164Number" ] }, { "type": "object", "properties": { - "FTPAddress": { + "task:FTPAddress": { "type": "string" } }, "required": [ - "FTPAddress" + "task:FTPAddress" ] }, { "type": "object", "properties": { - "URL": { + "task:URL": { "type": "string" } }, "required": [ - "URL" + "task:URL" ] }, { "type": "object", "properties": { - "FQDN": { + "task:FQDN": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "FQDN" + "task:FQDN" ] }, { "type": "object", "properties": { - "EmailAddress": { + "task:EmailAddress": { "$ref": "ts_103280_2017_07#/$defs/EmailAddress" } }, "required": [ - "EmailAddress" + "task:EmailAddress" ] }, { "type": "object", "properties": { - "EndpointID": { + "task:EndpointID": { "$ref": "ts_103120_Core_2019_10#/$defs/EndpointID" } }, "required": [ - "EndpointID" + "task:EndpointID" ] }, { "type": "object", "properties": { - "DeliveryInformationID": { + "task:DeliveryInformationID": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "DeliveryInformationID" + "task:DeliveryInformationID" ] } ] diff --git a/103120/schema/json/ts_103120_TrafficPolicy.schema.json b/103120/schema/json/ts_103120_TrafficPolicy.schema.json index 2bbfc17c..1d9619e4 100644 --- a/103120/schema/json/ts_103120_TrafficPolicy.schema.json +++ b/103120/schema/json/ts_103120_TrafficPolicy.schema.json @@ -136,23 +136,23 @@ { "type": "object", "properties": { - "IPPolicyCriteria": { + "tp:IPPolicyCriteria": { "$ref": "#/$defs/IPPolicyCriteria" } }, "required": [ - "IPPolicyCriteria" + "tp:IPPolicyCriteria" ] }, { "type": "object", "properties": { - "MobileAccessPolicyCriteria": { + "tp:MobileAccessPolicyCriteria": { "$ref": "#/$defs/MobileAccessPolicyCriteria" } }, "required": [ - "MobileAccessPolicyCriteria" + "tp:MobileAccessPolicyCriteria" ] } ] diff --git a/utils/translate/ChoiceMapping.py b/utils/translate/ChoiceMapping.py index fecadf80..b477a336 100644 --- a/utils/translate/ChoiceMapping.py +++ b/utils/translate/ChoiceMapping.py @@ -12,20 +12,25 @@ log = logging.getLogger() class ChoiceMapping(ComplexTypeMapping): @classmethod - def process_choice(cls, choice: XsdGroup, current_ns : str): + def process_choice(cls, choice: XsdGroup, current_ns : str, ns_to_id_map): if choice.model != 'choice': raise Exception(f"Wrong group type: {c.model}") oneOf = [] for c in choice.iter_model(): if not (type(c) is XsdElement): raise Exception (f"Non-element {c} encountered in choice {choice}") + element_name = c.local_name + if c.target_namespace in ns_to_id_map: + ns = ns_to_id_map[c.target_namespace] + if 'prefix' in ns: + element_name = ns['prefix'] + ":" + element_name t = TypeMapping.get_type_from_elem(c, current_ns) oneOf.append({ "type" : "object", "properties" : { - c.local_name : t + element_name : t }, - "required" : [c.local_name] + "required" : [element_name] }) return oneOf @@ -39,4 +44,4 @@ class ChoiceMapping(ComplexTypeMapping): if (content.model != 'choice'): log.debug("Not a choice, giving up") return None - return { 'oneOf' : ChoiceMapping.process_choice(content, xst.namespaces[''])} + return { 'oneOf' : ChoiceMapping.process_choice(content, xst.namespaces[''], self.ns_to_id_map)} diff --git a/utils/translate/SequenceMapping.py b/utils/translate/SequenceMapping.py index 9fd4d694..670a3ba4 100644 --- a/utils/translate/SequenceMapping.py +++ b/utils/translate/SequenceMapping.py @@ -70,7 +70,7 @@ class SequenceMapping(ComplexTypeMapping): raise Exception (f"Second group '{element_name}' encountered in {xst}") if c.model != "choice": raise Exception (f"Don't know what to do with inner group {c} in {xst} - not a choice") - inner_choice = ChoiceMapping.process_choice(c, xst.namespaces['']) + inner_choice = ChoiceMapping.process_choice(c, xst.namespaces[''], self.ns_to_id_map) elif type(c) is XsdAnyElement: mapped_type = {} else: diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index ac32d7ec..92a0348e 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -29,6 +29,58 @@ def removePrefixes (o, prefixes): for r in replacements: o[r[1]] = o.pop(r[0]) +object_namespaces = { + 'AuthorisationObject' : 'http://uri.etsi.org/03120/common/2020/09/Authorisation', + 'DeliveryObject' : 'http://uri.etsi.org/03120/common/2019/10/Delivery', + 'DocumentObject' : 'http://uri.etsi.org/03120/common/2020/09/Document', + 'NotificationObject' : 'http://uri.etsi.org/03120/common/2016/02/Notification', + 'LITaskObject' : 'http://uri.etsi.org/03120/common/2020/09/Task', + 'LDTaskObject' : 'http://uri.etsi.org/03120/common/2020/09/Task', + 'TrafficPolicyObject' : 'http://uri.etsi.org/03120/common/2022/07/TrafficPolicy', + 'TrafficRuleObject' : 'http://uri.etsi.org/03120/common/2022/07/TrafficPolicy' +} + +coerce_to_list = [ + 'auth:AuthorisationApprovalDetails', + 'auth:AuthorisationFlag', + 'auth:CSPID', + 'common:ApproverContactDetails', + 'ActionRequest', + 'ActionResponse', + 'ListResponseRecord', + 'AssociatedObject', + 'document:DocumentSignature', + 'document:DocumentProperty', + 'notification:AssociatedObjectStatus', + 'task:ApprovalDetails', + 'task:TargetIdentifierValue', + 'task:DeliveryDestination', + 'task:TaskFlag', + 'task:ApprovalDetails', + 'task:ObservedTimes', + 'task:RequestValue', + 'task:RequestSubtype', + 'task:LDDeliveryDestination', + 'task:LDTaskFlag', + 'task:TrafficPolicyReference', + 'tp:TrafficRuleReference', + 'tp:Criteria' +] + +coerce_to_int = [ + 'ActionIdentifier' +] + +def postprocessor (path, key, value): + if key == "@xsi:type": + object_name = value.split(":")[-1] + if object_name in object_namespaces.keys(): + value = "{" + object_namespaces[object_name] + "}" + object_name + return key, value + if key in coerce_to_int: + return key, int(value) + return key, value + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbose', action='count', help='Verbose logging (can be specified multiple times)') @@ -49,12 +101,12 @@ if __name__ == "__main__": args.input.close() logging.debug(s) - # d = xmltodict.parse(s, - # force_list=('AssociatedObject',) - # )['HI1Message'] d = xmltodict.parse(s, - force_list=('AssociatedObject',) + force_list=tuple(coerce_to_list), + # process_namespaces=True, + # namespaces = namespace_prefixes, + postprocessor=postprocessor )['HI1Message'] # prefixes = extract_prefixes(d) -- GitLab From 2c8079b496b7976cba9bfcfe8f29e48623e7cfa5 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 2 Jun 2023 15:38:06 +0100 Subject: [PATCH 11/15] Fixing doc prefix --- 103120/examples/request3.xml | 2 +- .../json/ts_103120_Document.schema.json | 48 +++++++++---------- utils/translate/SequenceMapping.py | 1 - utils/ts103120_config.json | 2 +- utils/xml_to_json.py | 4 +- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/103120/examples/request3.xml b/103120/examples/request3.xml index 718f6213..7d9b7c39 100644 --- a/103120/examples/request3.xml +++ b/103120/examples/request3.xml @@ -29,7 +29,7 @@ ACTOR01 W000001 - 2015-09-01T12:00:00Z + 2015-09-01T12:00:00BlahBlahZ 2015-12-01T12:00:00Z diff --git a/103120/schema/json/ts_103120_Document.schema.json b/103120/schema/json/ts_103120_Document.schema.json index f5b850b7..afeb421d 100644 --- a/103120/schema/json/ts_103120_Document.schema.json +++ b/103120/schema/json/ts_103120_Document.schema.json @@ -33,40 +33,40 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "document:DocumentReference": { + "doc:DocumentReference": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "document:DocumentName": { + "doc:DocumentName": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, - "document:DocumentStatus": { + "doc:DocumentStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "document:DocumentDesiredStatus": { + "doc:DocumentDesiredStatus": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "document:DocumentTimespan": { + "doc:DocumentTimespan": { "$ref": "#/$defs/DocumentTimespan" }, - "document:DocumentType": { + "doc:DocumentType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "document:DocumentProperties": { + "doc:DocumentProperties": { "$ref": "#/$defs/DocumentProperties" }, - "document:DocumentBody": { + "doc:DocumentBody": { "$ref": "#/$defs/DocumentBody" }, - "document:DocumentSignature": { + "doc:DocumentSignature": { "type": "array", "items": { "$ref": "ts_103120_Common_2016_02#/$defs/ApprovalDetails" } }, - "document:DocumentInvalidReason": { + "doc:DocumentInvalidReason": { "$ref": "ts_103120_Core_2019_10#/$defs/ActionUnsuccesfulInformation" }, - "document:NationalDocumentParameters": { + "doc:NationalDocumentParameters": { "$ref": "#/$defs/NationalDocumentParameters" } }, @@ -78,10 +78,10 @@ "DocumentTimespan": { "type": "object", "properties": { - "document:StartTime": { + "doc:StartTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" }, - "document:EndTime": { + "doc:EndTime": { "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" } }, @@ -90,7 +90,7 @@ "DocumentProperties": { "type": "object", "properties": { - "document:DocumentProperty": { + "doc:DocumentProperty": { "type": "array", "items": { "$ref": "#/$defs/DocumentProperty" @@ -102,32 +102,32 @@ "DocumentProperty": { "type": "object", "properties": { - "document:PropertyType": { + "doc:PropertyType": { "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" }, - "document:PropertyValue": { + "doc:PropertyValue": { "$ref": "ts_103280_2017_07#/$defs/LongString" } }, "required": [ - "document:PropertyType", - "document:PropertyValue" + "doc:PropertyType", + "doc:PropertyValue" ] }, "DocumentBody": { "type": "object", "properties": { - "document:Contents": { + "doc:Contents": { "type": "string", "pattern": "^[-A-Za-z0-9+/]*={0,3}$" }, - "document:ContentType": { + "doc:ContentType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "document:Checksum": { + "doc:Checksum": { "$ref": "ts_103280_2017_07#/$defs/ShortString" }, - "document:ChecksumType": { + "doc:ChecksumType": { "$ref": "ts_103280_2017_07#/$defs/ShortString" } }, @@ -136,12 +136,12 @@ "NationalDocumentParameters": { "type": "object", "properties": { - "document:CountryCode": { + "doc:CountryCode": { "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" } }, "required": [ - "document:CountryCode" + "doc:CountryCode" ] } } diff --git a/utils/translate/SequenceMapping.py b/utils/translate/SequenceMapping.py index 670a3ba4..4dc5c93e 100644 --- a/utils/translate/SequenceMapping.py +++ b/utils/translate/SequenceMapping.py @@ -45,7 +45,6 @@ class SequenceMapping(ComplexTypeMapping): inner_choice = None for c in list(content.iter_model()): log.debug(f"Processing model item {c}") - print("Model item -------------") if type(c) is XsdElement: element_name = c.local_name if c.target_namespace in self.ns_to_id_map: diff --git a/utils/ts103120_config.json b/utils/ts103120_config.json index ec321710..d2133761 100644 --- a/utils/ts103120_config.json +++ b/utils/ts103120_config.json @@ -12,7 +12,7 @@ "prefix" : "delivery" }, "./103120/schema/ts_103120_Document.xsd" : { - "prefix" : "document" + "prefix" : "doc" }, "./103120/schema/ts_103120_Notification.xsd" : { "prefix" : "notification" diff --git a/utils/xml_to_json.py b/utils/xml_to_json.py index 92a0348e..afc0f038 100644 --- a/utils/xml_to_json.py +++ b/utils/xml_to_json.py @@ -49,8 +49,8 @@ coerce_to_list = [ 'ActionResponse', 'ListResponseRecord', 'AssociatedObject', - 'document:DocumentSignature', - 'document:DocumentProperty', + 'doc:DocumentSignature', + 'doc:DocumentProperty', 'notification:AssociatedObjectStatus', 'task:ApprovalDetails', 'task:TargetIdentifierValue', -- GitLab From a8efd9a16acd84764345d468f090d9d2eb2155c3 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 2 Jun 2023 15:39:05 +0100 Subject: [PATCH 12/15] Fixing XML --- 103120/examples/request3.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/103120/examples/request3.xml b/103120/examples/request3.xml index 7d9b7c39..718f6213 100644 --- a/103120/examples/request3.xml +++ b/103120/examples/request3.xml @@ -29,7 +29,7 @@ ACTOR01 W000001 - 2015-09-01T12:00:00BlahBlahZ + 2015-09-01T12:00:00Z 2015-12-01T12:00:00Z -- GitLab From ad6129a207fc5682a3b130192c86373a4afc384b Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 8 Jun 2023 16:21:38 +0100 Subject: [PATCH 13/15] Changing extensions of interest for CI/CD --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a8ec525b..2cee5384 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ generate_artefacts: - echo $CI_MERGE_REQUEST_IID - echo $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME - echo $ARTEFACT_NAME - - forgelib-changedocs -v -d -c -l --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID + - forgelib-changedocs -v -d -c -l -x asn -x asn1 -x xml -x xsd -x json --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID artifacts: untracked: true paths: -- GitLab From f5df1a9824194aa3e5cf0b8ca778e38fe5905531 Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 8 Jun 2023 16:27:27 +0100 Subject: [PATCH 14/15] Extensions --- .gitlab-ci.yml | 2 +- ...ce_diff_blocks_instead_of_track_changes.docx | Bin 0 -> 36570 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Update_artefacts_to_produce_diff_blocks_instead_of_track_changes.docx diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cee5384..bb699144 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ generate_artefacts: - echo $CI_MERGE_REQUEST_IID - echo $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME - echo $ARTEFACT_NAME - - forgelib-changedocs -v -d -c -l -x asn -x asn1 -x xml -x xsd -x json --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID + - forgelib-changedocs -v -d -c -l -x json --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID artifacts: untracked: true paths: diff --git a/Update_artefacts_to_produce_diff_blocks_instead_of_track_changes.docx b/Update_artefacts_to_produce_diff_blocks_instead_of_track_changes.docx new file mode 100644 index 0000000000000000000000000000000000000000..74b1d0ec85080a6d16d974d4c00ebabeba589c59 GIT binary patch literal 36570 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 literal 0 HcmV?d00001 -- GitLab From e1ace00f4176279aef5efb6be60d88e792dae338 Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 8 Jun 2023 16:35:51 +0100 Subject: [PATCH 15/15] Reverting CI/CD changes --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bb699144..a8ec525b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ generate_artefacts: - echo $CI_MERGE_REQUEST_IID - echo $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME - echo $ARTEFACT_NAME - - forgelib-changedocs -v -d -c -l -x json --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID + - forgelib-changedocs -v -d -c -l --startdelimiter coversheets/delimiter_start.docx --enddelimiter coversheets/delimiter_end.docx https://$CI_SERVER_HOST/rep $CI_PROJECT_ID $CI_PROJECT_PATH $CI_MERGE_REQUEST_IID artifacts: untracked: true paths: -- GitLab