From bb5a4d1aad26e62b025c134fba3bb1952f771130 Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Mon, 25 Feb 2019 13:45:32 +0000 Subject: [PATCH] Updates graph_monitor API endpoint to also save the request identifier and the pipeline process identifier --- scripts/clmc-service/graph-pipeline.sh | 5 -- src/service/clmcservice/graphapi/tests.py | 10 ++- src/service/clmcservice/graphapi/views.py | 4 ++ src/service/clmcservice/models/__init__.py | 3 + .../clmcservice/models/graphapi_models.py | 70 +++++++++++++++++++ 5 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/service/clmcservice/models/graphapi_models.py diff --git a/scripts/clmc-service/graph-pipeline.sh b/scripts/clmc-service/graph-pipeline.sh index 1f03150..dfd348f 100644 --- a/scripts/clmc-service/graph-pipeline.sh +++ b/scripts/clmc-service/graph-pipeline.sh @@ -37,11 +37,6 @@ read query_period db_name results_measurement <<< ${fields} JSON_CONFIG=$(echo ${JSON_CONFIG} | jq 'del(.query_period, .results_measurement_name)') -# TODO this shouldn't be in the script maybe move it to the clmc isntall script -echo "Building network subgraph..." -response=$(curl -s -X POST http://${CLMC_IP}/clmc-service/graph/network) -echo ${response} - while true do echo "Building temporal graph..." diff --git a/src/service/clmcservice/graphapi/tests.py b/src/service/clmcservice/graphapi/tests.py index 78ec6b5..521bbe9 100644 --- a/src/service/clmcservice/graphapi/tests.py +++ b/src/service/clmcservice/graphapi/tests.py @@ -23,11 +23,12 @@ """ from json import dumps -import pytest from unittest.mock import patch, Mock, PropertyMock +import pytest from pyramid import testing -from clmcservice.graphapi.views import GraphAPI from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound, HTTPInternalServerError +from clmcservice.graphapi.views import GraphAPI +from clmcservice.models import MonitoringProcess class TestGraphAPI(object): @@ -533,6 +534,10 @@ class TestGraphAPI(object): pid_property_mock.assert_called_once_with() # assert that the process ID attribute was called and saved returncode_property_mock.assert_called_once_with() # assert that the process return code attribute was called to check if the process has started successfully + # check that the process ID was saved + assert MonitoringProcess.exists(uuid_mock.return_value), "Request identifier was not saved during the request processing" + assert MonitoringProcess.get(uuid_mock.return_value) == pid_property_mock.return_value, "Incorrect PID was saved during the request processing" + # check erroneous behaviour returncode_property_mock.return_value = -1 request = testing.DummyRequest() @@ -548,7 +553,6 @@ class TestGraphAPI(object): pid_property_mock.assert_called_with() # assert that the process ID attribute was called and saved returncode_property_mock.assert_called_with() # assert that the process return code attribute was called to check if the process has started successfully - @staticmethod def check_exist_relationship(relationships_tuple, graph, uuid): """ diff --git a/src/service/clmcservice/graphapi/views.py b/src/service/clmcservice/graphapi/views.py index e562bdf..fd95327 100644 --- a/src/service/clmcservice/graphapi/views.py +++ b/src/service/clmcservice/graphapi/views.py @@ -25,6 +25,7 @@ from clmcservice.graphapi.utilities import validate_build_request_body, validate_monitor_request_body, RTT_CYPHER_QUERY_TEMPLATE, \ build_network_graph, delete_network_graph, build_temporal_subgraph, delete_temporal_subgraph, validate_graph_rtt_params, find_node_with_possible_types +from clmcservice.models import MonitoringProcess from influxdb import InfluxDBClient from py2neo import Graph from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound, HTTPServiceUnavailable, HTTPNotImplemented, HTTPInternalServerError @@ -372,6 +373,9 @@ class GraphAPI(object): if process_return_code is None: # process has started running log.info("Started a graph pipeline process for SFC {0} with PID {1}".format(sfc, process_pid)) + + MonitoringProcess.add({"request_id": request_uuid, "process_id": process_pid}) + return {"database": database_name, "uuid": request_uuid} else: # a valid returned code was returned, hence the process has terminated one way or another - we do not expect this since the pipeline script must be continuously running log.warning("Graph pipeline process for SFC {0} with PID {1} has finished executing unexpectedly with return code {2}".format(sfc, process_pid, process_return_code)) diff --git a/src/service/clmcservice/models/__init__.py b/src/service/clmcservice/models/__init__.py index bdf3774..345922d 100644 --- a/src/service/clmcservice/models/__init__.py +++ b/src/service/clmcservice/models/__init__.py @@ -1,2 +1,5 @@ from .meta import DBSession + +from .graphapi_models import MonitoringProcess +# NOTE: all ORM models defined in this package must be imported here (in the __init__.py file) - Pyramid and SQLAlchemy specific approach from .whoami_models import ServiceFunctionEndpoint diff --git a/src/service/clmcservice/models/graphapi_models.py b/src/service/clmcservice/models/graphapi_models.py new file mode 100644 index 0000000..33e1b5c --- /dev/null +++ b/src/service/clmcservice/models/graphapi_models.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 +""" +// © University of Southampton IT Innovation Centre, 2018 +// +// Copyright in this software belongs to University of Southampton +// IT Innovation Centre of Gamma House, Enterprise Road, +// Chilworth Science Park, Southampton, SO16 7NS, UK. +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Nikolay Stanchev +// Created Date : 02-07-2018 +// Created for Project : FLAME +""" + + +class _MonitoringProcess: + """ + Container-like class used to store key value pairs between graph pipelines request identifiers and process identifiers. + The class is declared as "pseudo-private" and is ought to be initialised only in this module and exposed as a singleton. + """ + + def __init__(self): + + self.__pipelines = {} + + def add(self, instance): + """ + Adds a new key-value pair to the container representing a request ID mapped to a PID. + + :param instance: JSON representation of key value pair - e.g. {"request_id": <reequest uuid>, "process_id": <process ID>} + """ + + self.__pipelines[instance["request_id"]] = instance["process_id"] + + def get(self, request_id): + """ + Gets the data associated with a request identifier - currently the data is just the process identifier. + + :param request_id: the request identifier to check + + :return: the PID for this request ID or None if it doesn't exist + """ + + return self.__pipelines.get(request_id) + + def exists(self, request_id): + """ + Checks if a request ID is associated to a given process ID + + :param request_id: the request identifier to check + + :return: True or False + """ + + return request_id in self.__pipelines + + +# Only initialise the class here, this instance is imported in models/__init__.py so that it behaves like the other ORM models, +# the container's interface mimics the interface of the other ORM models +MonitoringProcess = _MonitoringProcess() -- GitLab