From 59a5804932e558a3c0d93b382ae66fb1df25926f Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Tue, 4 Sep 2018 10:51:46 +0100 Subject: [PATCH] Implements an API endpoint for retrieving generated alert IDs, tests and documentation included --- docs/clmc-service.md | 35 ++++++++++++++++++++++ src/service/clmcservice/alertsapi/tests.py | 26 ++++++++++++++++ src/service/clmcservice/alertsapi/views.py | 25 ++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/docs/clmc-service.md b/docs/clmc-service.md index 2ffd82e..e99b485 100644 --- a/docs/clmc-service.md +++ b/docs/clmc-service.md @@ -39,6 +39,41 @@ configuration files of the service can be found in the **src/service** folder. ## Alerts API Endpoints +* **GET** ***/alerts?sfc={service function chain id}&sfci={service function chain instance id}&policy={policy id}&trigger={trigger id}*** + + This API method can be used to retrieve the generated alert task and alert topic identifiers during the processing of an alerts specification document. + These identifiers can then be used to interact with the Kapacitor HTTP API for further configiuration or modification of alerts - https://docs.influxdata.com/kapacitor/v1.4/working/api/. + + * Request: + + Expects a URL query string with the request parameters - **sfc**, **sfci**, **policy** and **trigger**. The given parameters must match the values used in the alerts specification + document. Otherwise, a wrong ID will be returned. + + * Request URL Examples: + + **/alerts?sfc=MSDemo&sfci=MSDemo-premium&policy=requests_diff&trigger=low_requests** + + **/alerts?sfc=SimpleMediaService&sfci=SimpleMediaService-1&policy=rtt_deviation&trigger=increase_in_rtt** + + * Response + + The response of this request is a JSON-formatted content, which contains the task and topic identifiers, along with the Kapacitor + API endpoints to use for configuring the given task, topic and the respective handlers. + + Returns a 400 Bad Request if the URL query string parameters are invalid or otherwise incorrect. + + * Response Body Example: + + ```json + { + "task_identifier": "094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388", + "topic_identifier": "094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388", + "task_api_endpoint": "/kapacitor/v1/tasks/094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388", + "topic_api_endpoint": "/kapacitor/v1/alerts/topics/094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388", + "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388/handlers" + } + ``` + * **POST** ***/alerts*** This API method can be used to send an alert specification document, which is then used by the CLMC service to create diff --git a/src/service/clmcservice/alertsapi/tests.py b/src/service/clmcservice/alertsapi/tests.py index 0f1d489..09e4d61 100644 --- a/src/service/clmcservice/alertsapi/tests.py +++ b/src/service/clmcservice/alertsapi/tests.py @@ -69,6 +69,32 @@ class TestAlertsConfigurationAPI(object): testing.tearDown() + @pytest.mark.parametrize("sfc_id, sfci_id, policy_id, trigger_id, task_id, topic_id", [ + ("MSDemo", "MSDemo-premium", "requests_diff", "low_requests", "094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388", "094f23d6e948c78e9fa215528973fb3aeefa5525898626c9ea049dc8e87a7388"), + ("sfc", "sfc_1", "missing_measurements", "no_latency_measurements", "1019ab70402a98905ff9e950c36d3c13a8468db8f7b8196f4ee69d6c39947fe5", "1019ab70402a98905ff9e950c36d3c13a8468db8f7b8196f4ee69d6c39947fe5"), + ("disney.sfc.flame.eu", "disney.sfc.flame.eu-premium", "rtt_deviation", "increase_in_rtt", "8b069cc10571f887ff6c3a14aea11e68e664ddde5bc6af08d88058865510af93", "8b069cc10571f887ff6c3a14aea11e68e664ddde5bc6af08d88058865510af93"), + ("vrt/novel/sfc", "vrt/novel/sfc-prototype", "deadmen_measurement", "missing_storage_measurements", "8c1aba1c61c184809d648e4ab323b9b48606847bb2e3d54bfbdf34d8a7db91d1", "8c1aba1c61c184809d648e4ab323b9b48606847bb2e3d54bfbdf34d8a7db91d1"), + ("vrt/novel/sfc", "vrt/novel/sfc-deployment", "deadmen_measurement", "missing_storage_measurements", "a61dbe20cbef19be384982b51e22d83f23c4e10aeede172ef8646c515b836f7b", "a61dbe20cbef19be384982b51e22d83f23c4e10aeede172ef8646c515b836f7b") + ]) + def test_alerts_hash_getter(self, sfc_id, sfci_id, policy_id, trigger_id, task_id, topic_id): + """ + Tests the GET method for retrieving the task and topic ID given the sfc, sfc instance, policy id and trigger id. + """ + + request = testing.DummyRequest() + request.params["sfc"] = sfc_id + request.params["sfci"] = sfci_id + request.params["policy"] = policy_id + request.params["trigger"] = trigger_id + + response = AlertsConfigurationAPI(request).get_alerts_hash() + + assert response["task_identifier"] == task_id, "Incorrect task identifier returned" + assert response["task_api_endpoint"] == "/kapacitor/v1/tasks/{0}".format(task_id), "Incorrect task API endpoint returned." + assert response["topic_identifier"] == topic_id, "Incorrect topic identifier returned" + assert response["topic_api_endpoint"] == "/kapacitor/v1/alerts/topics/{0}".format(topic_id), "Incorrect topic API endpoint returned" + assert response["topic_handlers_api_endpoint"] == "/kapacitor/v1/alerts/topics/{0}/handlers".format(topic_id), "Incorrect topic handlers API endpoint returned" + def test_alerts_config_tosca_parsing(self): """ Tests that what we consider a valid/invalid alerts specification is successfully/unsuccessfully parsed by the TOSCA-parser. diff --git a/src/service/clmcservice/alertsapi/views.py b/src/service/clmcservice/alertsapi/views.py index 4afba33..3449067 100644 --- a/src/service/clmcservice/alertsapi/views.py +++ b/src/service/clmcservice/alertsapi/views.py @@ -57,6 +57,31 @@ class AlertsConfigurationAPI(object): self.request = request + @view_config(route_name='alerts_configuration', request_method='GET') + def get_alerts_hash(self): + + for param in ("sfc", "sfci", "policy", "trigger"): + if param not in self.request.params: + raise HTTPBadRequest("Missing url query string parameter {0}.".format(param)) + + sfc = self.request.params["sfc"] + sfci = self.request.params["sfci"] + policy = self.request.params["policy"] + trigger = self.request.params["trigger"] + + # generate topic and alert identifiers + topic_id = "{0}\n{1}\n{2}\n{3}".format(sfc, sfci, policy, trigger) + topic_id = self.get_hash(topic_id) + alert_id = topic_id + + return { + "task_identifier": alert_id, + "task_api_endpoint": "/kapacitor/v1/tasks/{0}".format(alert_id), + "topic_identifier": topic_id, + "topic_api_endpoint": "/kapacitor/v1/alerts/topics/{0}".format(topic_id), + "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/{0}/handlers".format(topic_id) + } + @view_config(route_name='alerts_configuration', request_method='POST') def post_alerts_specification(self): """ -- GitLab