From ad5a448bab6b4c33368d7d42b462bdd8fa048ce9 Mon Sep 17 00:00:00 2001 From: Dan Jones <danjon@noc.ac.uk> Date: Fri, 6 Sep 2024 09:51:56 +0100 Subject: [PATCH] refactor: make version a oneof to match git refs + move all schemas into formats + add test messages for semver, commit ref and branch --- examples/mas-dt/platform_status_branch.json | 24 +++++ examples/mas-dt/platform_status_commit.json | 24 +++++ examples/mas-dt/platform_status_semver.json | 24 +++++ formats/__init__.py | 50 ---------- formats/header.py | 100 ++++++++++++++++++++ formats/message.py | 13 +++ formats/payload.py | 33 +++++++ generate_schema_config.py | 55 +---------- project/soar/swagger.json | 72 ++++++++++++-- 9 files changed, 286 insertions(+), 109 deletions(-) create mode 100644 examples/mas-dt/platform_status_branch.json create mode 100644 examples/mas-dt/platform_status_commit.json create mode 100644 examples/mas-dt/platform_status_semver.json create mode 100644 formats/header.py create mode 100644 formats/message.py create mode 100644 formats/payload.py diff --git a/examples/mas-dt/platform_status_branch.json b/examples/mas-dt/platform_status_branch.json new file mode 100644 index 0000000..1081184 --- /dev/null +++ b/examples/mas-dt/platform_status_branch.json @@ -0,0 +1,24 @@ +{ + "header":{ + "message_ID": "b427003c-0000-11aa-a1eb-bvcdfghjgfdd", + "timestamp": "2024-09-05T00:00:00Z", + "version": "dev", + "source": "noc-sfmc", + "destination": "mas-dt.noc.slocum.unit_xxx.from_platform.platform_status", + "delivery_type": "publish", + "encoded": false + }, + "payload":{ + "message_type": "platform_status", + "platform_ID": "unit_xxx", + "platform_timestamp": "2024-09-05T00:00:00Z", + "status_source": "onboard_platform", + "autonomy_engine_plan_ID": 1, + "mission_plan_ID": 1, + "mission_track_ID": 4, + "latitude": 78.2, + "longitude": -10.122, + "depth": 50.0, + "altitude": 20 + } +} diff --git a/examples/mas-dt/platform_status_commit.json b/examples/mas-dt/platform_status_commit.json new file mode 100644 index 0000000..c832425 --- /dev/null +++ b/examples/mas-dt/platform_status_commit.json @@ -0,0 +1,24 @@ +{ + "header":{ + "message_ID": "b427003c-0000-11aa-a1eb-bvcdfghjgfdd", + "timestamp": "2024-09-05T00:00:00Z", + "version": "2bbede2412f9038c0b1ecd8c2965532ea97264a3", + "source": "noc-sfmc", + "destination": "mas-dt.noc.slocum.unit_xxx.from_platform.platform_status", + "delivery_type": "publish", + "encoded": false + }, + "payload":{ + "message_type": "platform_status", + "platform_ID": "unit_xxx", + "platform_timestamp": "2024-09-05T00:00:00Z", + "status_source": "onboard_platform", + "autonomy_engine_plan_ID": 1, + "mission_plan_ID": 1, + "mission_track_ID": 4, + "latitude": 78.2, + "longitude": -10.122, + "depth": 50.0, + "altitude": 20 + } +} diff --git a/examples/mas-dt/platform_status_semver.json b/examples/mas-dt/platform_status_semver.json new file mode 100644 index 0000000..529e91f --- /dev/null +++ b/examples/mas-dt/platform_status_semver.json @@ -0,0 +1,24 @@ +{ + "header":{ + "message_ID": "b427003c-0000-11aa-a1eb-bvcdfghjgfdd", + "timestamp": "2024-09-05T00:00:00Z", + "version": "v2.0.0-beta.1", + "source": "noc-sfmc", + "destination": "mas-dt.noc.slocum.unit_xxx.from_platform.platform_status", + "delivery_type": "publish", + "encoded": false + }, + "payload":{ + "message_type": "platform_status", + "platform_ID": "unit_xxx", + "platform_timestamp": "2024-09-05T00:00:00Z", + "status_source": "onboard_platform", + "autonomy_engine_plan_ID": 1, + "mission_plan_ID": 1, + "mission_track_ID": 4, + "latitude": 78.2, + "longitude": -10.122, + "depth": 50.0, + "altitude": 20 + } +} diff --git a/formats/__init__.py b/formats/__init__.py index 96c6be0..2253a07 100644 --- a/formats/__init__.py +++ b/formats/__init__.py @@ -6,53 +6,3 @@ __all__ = [ for x in os.listdir(os.path.dirname(__file__)) if x.endswith(".py") and x != "__init__.py" ] - -message_header = { - "type": "object", - "discriminator": { - "propertyName": "message_type", - }, - "properties": { - "message_ID": { - "type": "string", - "description": "An identifier for the type of message received.", - "example": "b427003c-0000-11aa-a1eb-bvcdfghjgfdd", - }, - "timestamp": { - "type": "string", - "format": "date-time", - "description": "Timestamp of message", - "example": "2022-11-16T00:00:00Z", - }, - "version": { - "type": "number", - "format": "float", - "description": "Version of comms backbone message format protocol", - "example": 2.0, - }, - "source": { - "type": "string", - "description": "The sender; Where is this message from", - "example": "autonomy_engine", - }, - "destination": { - "type": "string", - "description": "Publisher topic; What is the destination" - + " of this message", - "example": "ah1", - }, - "encoded": { - "type": "boolean", - "description": "Indicate that message raw (encoded) or decoded. " - + "Options: encoded=true, decoded=false", - "example": False, - }, - "delivery_type": { - "type": "string", - "description": "To publish or broadcast this message.", - "enum": ["broadcast", "publish"], - "example": "publish", - "default": "publish", - }, - }, -} diff --git a/formats/header.py b/formats/header.py new file mode 100644 index 0000000..f857660 --- /dev/null +++ b/formats/header.py @@ -0,0 +1,100 @@ +message_header = { + "type": "object", + "properties": { + "message_ID": { + "type": "string", + "description": "An identifier for the type of message received.", + "example": "b427003c-0000-11aa-a1eb-bvcdfghjgfdd", + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "Timestamp of message", + "example": "2022-11-16T00:00:00Z", + }, + "source": { + "type": "string", + "description": "The sender; Where is this message from", + "example": "autonomy_engine", + }, + "destination": { + "type": "string", + "description": "Publisher topic; What is the destination" + + " of this message", + "example": "ah1", + }, + "encoded": { + "type": "boolean", + "description": "Indicate that message raw (encoded) or decoded. " + + "Options: encoded=true, decoded=false", + "example": False, + }, + "delivery_type": { + "type": "string", + "description": "To publish or broadcast this message.", + "enum": ["broadcast", "publish"], + "example": "publish", + "default": "publish", + }, + }, + "oneOf": [ + { + # semver pattern https://semver.org/ + # https://regex101.com/r/Ly7O1x/3/ + # + optionally include 'v' prefix + # escape backslashes get doubled so use char groups + # simplify to planned variants + "type": "object", + "properties": { + "version": { + "type": "string", + "pattern": "^(v{0,1}(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)" + + "(?:-(alpha|beta)[.](0|[1-9][0-9]*))?)$", + } + }, + "required": ["version"], + }, + { + # commit ref + "type": "object", + "properties": { + "version": { + "type": "string", + "pattern": "^([0-9a-f]+)$", + } + }, + "required": ["version"], + }, + { + # reserved word + "type": "object", + "properties": { + "version": { + "type": "string", + "enum": ["dev", "master", "latest"], + } + }, + "required": ["version"], + }, + { + # existing float version + "type": "object", + "properties": { + "version": { + "type": "number", + "format": "float", + "example": 2.0, + } + }, + "required": ["version"], + }, + ], + "required": [ + "message_ID", + "timestamp", + "source", + "destination", + "delivery_type", + "encoded", + ], +} diff --git a/formats/message.py b/formats/message.py new file mode 100644 index 0000000..b944c48 --- /dev/null +++ b/formats/message.py @@ -0,0 +1,13 @@ +message_schema = { + "type": "object", + "description": "Full message definition with" + + " message-metadata in `header` and different" + + " message type schemas under `payload`", + "properties": { + "header": { + "$ref": "#/components/schemas/header", + }, + "payload": {"$ref": "#/components/schemas/payload"}, + }, + "required": ["header", "payload"], +} diff --git a/formats/payload.py b/formats/payload.py new file mode 100644 index 0000000..062527f --- /dev/null +++ b/formats/payload.py @@ -0,0 +1,33 @@ +payload_schema = { + "discriminator": { + "propertyName": "message_type", + "mapping": { + "alert": "#/components/schemas/alert", + "mission_plan": "#/components/schemas/mission_plan", + "mission_plan_encoded": "#/components/schemas/" + "mission_plan_encoded", + "observation": "#/components/schemas/observation", + "observation_encoded": "#/components/schemas/" + "observation_encoded", + "planning_configuration": "#/components/schemas/" + + "planning_configuration", + "platform_status": "#/components/schemas/platform_status", + "platform_status_encoded": "#/components/schemas/" + + "platform_status_encoded", + "acknowledgement": "#/components/schemas/acknowledgement", + "survey": "#/components/schemas/survey", + "survey_encoded": "#/components/schemas/" + "survey_encoded", + }, + }, + "oneOf": [ + {"$ref": "#/components/schemas/alert"}, + {"$ref": "#/components/schemas/acknowledgement"}, + {"$ref": "#/components/schemas/mission_plan"}, + {"$ref": "#/components/schemas/mission_plan_encoded"}, + {"$ref": "#/components/schemas/observation"}, + {"$ref": "#/components/schemas/observation_encoded"}, + {"$ref": "#/components/schemas/planning_configuration"}, + {"$ref": "#/components/schemas/platform_status"}, + {"$ref": "#/components/schemas/platform_status_encoded"}, + {"$ref": "#/components/schemas/survey"}, + {"$ref": "#/components/schemas/survey_encoded"}, + ], +} diff --git a/generate_schema_config.py b/generate_schema_config.py index 3d223a1..57cadb6 100644 --- a/generate_schema_config.py +++ b/generate_schema_config.py @@ -1,8 +1,10 @@ -from formats import message_header +from formats.header import message_header +from formats.message import message_schema from formats.mission_plan import mission_plan_schema from formats.mission_plan_encoded import mission_plan_encoded_schema from formats.observation import observation_schema from formats.observation_encoded import observation_encoded_schema +from formats.payload import payload_schema from formats.planning_configuration import planning_configuration_schema from formats.platform_status import platform_status_schema from formats.platform_status_encoded import platform_status_encoded_schema @@ -55,56 +57,9 @@ def get_swagger_config(reload=False): "paths": {}, "components": { "schemas": { - "MESSAGE": { - "type": "object", - "description": "Full message definition with" - + " message-metadata in `header` and different" - + " message type schemas under `payload`", - "properties": { - "header": { - "$ref": "#/components/schemas/header", - }, - "payload": {"$ref": "#/components/schemas/payload"}, - }, - "required": ["header", "payload"], - }, - "payload": { - "discriminator": { - "propertyName": "message_type", - "mapping": { - "alert": "#/components/schemas/alert", - "mission_plan": "#/components/schemas/mission_plan", - "mission_plan_encoded": "#/components/schemas/" - + "mission_plan_encoded", - "observation": "#/components/schemas/observation", - "observation_encoded": "#/components/schemas/" - + "observation_encoded", - "planning_configuration": "#/components/schemas/" - + "planning_configuration", - "platform_status": "#/components/schemas/platform_status", - "platform_status_encoded": "#/components/schemas/" - + "platform_status_encoded", - "acknowledgement": "#/components/schemas/acknowledgement", - "survey": "#/components/schemas/survey", - "survey_encoded": "#/components/schemas/" - + "survey_encoded", - }, - }, - "oneOf": [ - {"$ref": "#/components/schemas/alert"}, - {"$ref": "#/components/schemas/acknowledgement"}, - {"$ref": "#/components/schemas/mission_plan"}, - {"$ref": "#/components/schemas/mission_plan_encoded"}, - {"$ref": "#/components/schemas/observation"}, - {"$ref": "#/components/schemas/observation_encoded"}, - {"$ref": "#/components/schemas/planning_configuration"}, - {"$ref": "#/components/schemas/platform_status"}, - {"$ref": "#/components/schemas/platform_status_encoded"}, - {"$ref": "#/components/schemas/survey"}, - {"$ref": "#/components/schemas/survey_encoded"}, - ], - }, + "MESSAGE": message_schema, "header": message_header, + "payload": payload_schema, "mission_plan": mission_plan_schema, "mission_plan_encoded": mission_plan_encoded_schema, "observation": observation_schema, diff --git a/project/soar/swagger.json b/project/soar/swagger.json index b61da63..aaee112 100644 --- a/project/soar/swagger.json +++ b/project/soar/swagger.json @@ -1343,9 +1343,61 @@ "type": "object" }, "header": { - "discriminator": { - "propertyName": "message_type" - }, + "oneOf": [ + { + "properties": { + "version": { + "pattern": "^(v{0,1}(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(?:-(alpha|beta)[.](0|[1-9][0-9]*))?)$", + "type": "string" + } + }, + "required": [ + "version" + ], + "type": "object" + }, + { + "properties": { + "version": { + "pattern": "^([0-9a-f]+)$", + "type": "string" + } + }, + "required": [ + "version" + ], + "type": "object" + }, + { + "properties": { + "version": { + "enum": [ + "dev", + "master", + "latest" + ], + "type": "string" + } + }, + "required": [ + "version" + ], + "type": "object" + }, + { + "properties": { + "version": { + "example": 2.0, + "format": "float", + "type": "number" + } + }, + "required": [ + "version" + ], + "type": "object" + } + ], "properties": { "delivery_type": { "default": "publish", @@ -1382,14 +1434,16 @@ "example": "2022-11-16T00:00:00Z", "format": "date-time", "type": "string" - }, - "version": { - "description": "Version of comms backbone message format protocol", - "example": 2.0, - "format": "float", - "type": "number" } }, + "required": [ + "message_ID", + "timestamp", + "source", + "destination", + "delivery_type", + "encoded" + ], "type": "object" }, "mission_plan": { -- GitLab