From 892a0b83c69f324c97e2e712d2c208a35edc1485 Mon Sep 17 00:00:00 2001
From: Janet Goldstein <jgoldste@nrao.edu>
Date: Fri, 17 Dec 2021 11:50:13 -0500
Subject: [PATCH] WS-833: capability version number in`announce_qa` endpoint

---
 .../test/test_workflow_service_rest_api.py    | 11 +++++--
 services/workflow/workflow/server.py          | 10 +++++-
 .../workspaces/workflow/message_architect.py  |  5 +++
 .../workflow/services/workflow_service.py     | 31 ++++++++++++++-----
 4 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/services/workflow/test/test_workflow_service_rest_api.py b/services/workflow/test/test_workflow_service_rest_api.py
index 48719f275..f3fc24385 100644
--- a/services/workflow/test/test_workflow_service_rest_api.py
+++ b/services/workflow/test/test_workflow_service_rest_api.py
@@ -150,17 +150,22 @@ def test_announces_qa(workflow_request: DummyRequest):
     :return: pyramid request
     """
 
-    # Init dummy request values
+    # Stash dummy request properties
     matchdict_savepoint = workflow_request.matchdict
     body_savepoint = workflow_request.json_body
-    workflow_request.matchdict["request_id"] = -1
+
+    # Init dummy request values
+    request_id = -1
+    version = 1
+    workflow_request.matchdict["request_id"] = request_id
+    workflow_request.json_body["capability_version"] = version
     workflow_request.workflows.announce_qa = MagicMock()
 
     for msg_type in ["qa_ready", "qa_pass", "qa_fail"]:
         workflow_request.matchdict["msg_type"] = msg_type
         response = WorkflowRequestRestService(workflow_request).announce_qa()
         assert response.status_code == http.HTTPStatus.OK
-        workflow_request.workflows.announce_qa.assert_called_with(-1, msg_type)
+        workflow_request.workflows.announce_qa.assert_called_with(request_id, msg_type, version)
 
     # Reset dummy request properties to their initial values
     workflow_request_request.matchdict = matchdict_savepoint
diff --git a/services/workflow/workflow/server.py b/services/workflow/workflow/server.py
index 0364f23b3..cc152e08f 100644
--- a/services/workflow/workflow/server.py
+++ b/services/workflow/workflow/server.py
@@ -282,6 +282,12 @@ class WorkflowRequestRestService:
 
     @view_config(request_method="POST", route_name="create_and_submit_workflow_request")
     def create_and_submit(self):
+        """
+        Create a new workflow request from the name/arguments supplied, then submit the request.
+
+        Audience: front-end and CLI
+        :return:
+        """
         self.request.context = self.create_workflow_request()
         return self.submit_workflow()
 
@@ -327,6 +333,7 @@ class WorkflowRequestRestService:
     def qa_fail(self):
         """
         Perform qa_fail on specified workflow
+
         :return:
         """
         print(f"QA Failing workflow request #{self.request.context}")
@@ -403,7 +410,8 @@ class WorkflowRequestRestService:
         """
         request_id = self.request.matchdict["request_id"]
         msg_type = self.request.matchdict["msg_type"]
-        self.request.workflows.announce_qa(request_id, msg_type)
+        version = self.request.json_body["capability_version"]
+        self.request.workflows.announce_qa(request_id, msg_type, version)
 
         return Response(
             status_code=http.HTTPStatus.OK,
diff --git a/shared/workspaces/workspaces/workflow/message_architect.py b/shared/workspaces/workspaces/workflow/message_architect.py
index d2c98bf94..e4923144a 100644
--- a/shared/workspaces/workspaces/workflow/message_architect.py
+++ b/shared/workspaces/workspaces/workflow/message_architect.py
@@ -117,10 +117,12 @@ class WorkflowMessageArchitect(MessageArchitectIF):
         previous_info=None,
         delivery_info=None,
         carta_url=None,
+        ui_info=None,
     ):
         self.subject = request or previous_info
         self.delivery = delivery_info
         self.carta_url = carta_url
+        self.ui_info = ui_info
 
     @staticmethod
     def get_message_template(msg_type: str) -> dict:
@@ -145,6 +147,9 @@ class WorkflowMessageArchitect(MessageArchitectIF):
         if self.carta_url is not None:
             template["carta_url"] = self.carta_url
 
+        if self.ui_info is not None:
+            template["capability_version"] = self.ui_info
+
         return DictView(template)
 
 
diff --git a/shared/workspaces/workspaces/workflow/services/workflow_service.py b/shared/workspaces/workspaces/workflow/services/workflow_service.py
index bf79d1a08..0be4b1788 100644
--- a/shared/workspaces/workspaces/workflow/services/workflow_service.py
+++ b/shared/workspaces/workspaces/workflow/services/workflow_service.py
@@ -17,6 +17,8 @@
 # along with Workspaces.  If not, see <https://www.gnu.org/licenses/>.
 """ This is the workflow service. """
 
+# pylint: disable=E0401, E0402, W1203
+
 import json
 import logging
 import os
@@ -43,8 +45,6 @@ from workspaces.workflow.message_architect import (
 from workspaces.workflow.schema import Workflow, WorkflowRequest, WorkflowRequestFile
 from workspaces.workflow.services.interfaces import WorkflowInfoIF, WorkflowServiceIF
 
-# pylint: disable=E0401, W1203
-
 logger = logging.getLogger(__name__)
 
 
@@ -121,7 +121,7 @@ class WorkflowServiceRESTClient(WorkflowServiceIF):
 
         return WorkflowRequest.from_json(result)
 
-    def announce_qa(self, workflow_request_id: int, msg_type: str):
+    def announce_qa(self, workflow_request_id: int, msg_type: str, capability_version: int) -> WorkflowRequest:
         """
         Announce QA event
 
@@ -129,7 +129,11 @@ class WorkflowServiceRESTClient(WorkflowServiceIF):
         :param msg_type: pass/fail/ready
         :return:
         """
-        requests.post(f"{self.url}/workflows/requests/{workflow_request_id}/qa/{msg_type}")
+        argument = {"capabilityVersion": capability_version}
+
+        result = requests.post(f"{self.url}/workflows/requests/{workflow_request_id}/qa/{msg_type}", json=argument)
+
+        return WorkflowRequest.from_json(result)
 
     def ingest(self, request: WorkflowRequest):
         """
@@ -179,6 +183,13 @@ class WorkflowService(WorkflowServiceIF):
             logger.info(f"{filename} is a protected file name.")
 
     def retrieve_file_content(self, request_id: int, filename: str):
+        """
+        Grab the content of this workflow request file.
+
+        :param request_id:
+        :param filename:
+        :return:
+        """
         wf_req = self.info.lookup_workflow_request(request_id)
         for file in wf_req.files:
             if file.filename == filename:
@@ -578,17 +589,23 @@ class WorkflowService(WorkflowServiceIF):
             workflow_name + ".dag",
         ]
 
-    def announce_qa(self, workflow_request_id: int, msg_type: str):
+    def announce_qa(self, workflow_request_id: int, msg_type: str, capability_version: int):
         """
         Announce this QA ready/pass/fail event
         :param workflow_request_id: the workflow request ID
         :param msg_type: ready, pass, or fail
+        :param capability_version: version that requires qa
         :return:
         """
-        logger.info(f"ANNOUNCING QA {msg_type.upper()} for request #{workflow_request_id}!")
+        logger.info(
+            f"ANNOUNCING QA {msg_type.upper()} for request #{workflow_request_id}, capability version"
+            f" {capability_version}!"
+        )
         wf_request = self.info.lookup_workflow_request(workflow_request_id)
 
-        qa_event_msg = WorkflowMessageArchitect(request=wf_request).compose_message(msg_type)
+        qa_event_msg = WorkflowMessageArchitect(request=wf_request, ui_info=capability_version).compose_message(
+            msg_type
+        )
         self.messenger.send_message(**qa_event_msg)
 
         return qa_event_msg
-- 
GitLab