From e47ec55d0374c09a59819622070c53e79f4fd34d Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Tue, 17 Jul 2018 18:28:54 +0100 Subject: [PATCH] Removes old round-trip-time API endpoint --- src/service/clmcservice/__init__.py | 1 - .../clmcservice/aggregationapi/utilities.py | 23 ---- .../clmcservice/aggregationapi/views.py | 110 +----------------- 3 files changed, 3 insertions(+), 131 deletions(-) diff --git a/src/service/clmcservice/__init__.py b/src/service/clmcservice/__init__.py index 9f25df6..ff5cee8 100644 --- a/src/service/clmcservice/__init__.py +++ b/src/service/clmcservice/__init__.py @@ -57,7 +57,6 @@ def main(global_config, **settings): # add routes of the aggregator API config.add_route('aggregator_config', '/aggregator/config') config.add_route('aggregator_controller', '/aggregator/control') - config.add_route('round_trip_time_query', '/query/round-trip-time') # add routes of the WHOAMI API config.add_route('whoami_endpoints', '/whoami/endpoints') diff --git a/src/service/clmcservice/aggregationapi/utilities.py b/src/service/clmcservice/aggregationapi/utilities.py index bc55125..2375300 100644 --- a/src/service/clmcservice/aggregationapi/utilities.py +++ b/src/service/clmcservice/aggregationapi/utilities.py @@ -43,10 +43,6 @@ MALFORMED_FLAG = 'malformed' # Attribute for storing the flag, which shows whet COMMENT_ATTRIBUTE = 'comment' COMMENT_VALUE = 'Aggregator is running in a malformed state - it uses an old version of the configuration. Please, restart it so that the updated configuration is used.' -# the attributes of the JSON response body that are expected when querying round trip time -ROUND_TRIP_ATTRIBUTES = ('media_service', 'start_timestamp', 'end_timestamp') - - URL_REGEX = compile( r'^https?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain, e.g. example.domain.com @@ -108,25 +104,6 @@ def validate_action_content(content): return content -def validate_round_trip_query_params(params): - """ - A utility function to validate a dictionary of parameters. - - :param params: the params dict to validate - :return: the validated parameters dictionary - :raise AssertionError: if the argument is not a valid json content - """ - - global ROUND_TRIP_ATTRIBUTES - - assert len(params) == len(ROUND_TRIP_ATTRIBUTES), "Content mustn't contain more attributes than the required ones." - - for attribute in ROUND_TRIP_ATTRIBUTES: - assert attribute in params, "Required attribute not found in the request content." - - return params - - def validate_conf_file(conf_file_path): """ Validates the aggregator's configuration file - checks for existence of the file path, whether it can be parsed as a configuration file and diff --git a/src/service/clmcservice/aggregationapi/views.py b/src/service/clmcservice/aggregationapi/views.py index 9088eed..154e351 100644 --- a/src/service/clmcservice/aggregationapi/views.py +++ b/src/service/clmcservice/aggregationapi/views.py @@ -23,12 +23,10 @@ """ from pyramid.view import view_defaults, view_config -from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError -from influxdb import InfluxDBClient -from urllib.parse import urlparse +from pyramid.httpexceptions import HTTPBadRequest from subprocess import Popen -from clmcservice.aggregationapi.utilities import validate_config_content, validate_action_content, validate_round_trip_query_params, \ - CONF_OBJECT, CONF_FILE_ATTRIBUTE, AGGREGATOR_CONFIG_SECTION, CONFIG_ATTRIBUTES, ROUND_TRIP_ATTRIBUTES, RUNNING_FLAG, PROCESS_ATTRIBUTE, MALFORMED_FLAG, COMMENT_ATTRIBUTE, COMMENT_VALUE +from clmcservice.aggregationapi.utilities import validate_config_content, validate_action_content, \ + CONF_OBJECT, CONF_FILE_ATTRIBUTE, AGGREGATOR_CONFIG_SECTION, CONFIG_ATTRIBUTES, RUNNING_FLAG, PROCESS_ATTRIBUTE, MALFORMED_FLAG, COMMENT_ATTRIBUTE, COMMENT_VALUE import os import os.path import sys @@ -252,105 +250,3 @@ class AggregatorController(object): # check if the process is started before trying to terminate it - process.poll() only returns something if the process has terminated, hence we check for a None value return process is not None and process.poll() is None - - -@view_defaults(route_name='round_trip_time_query', renderer='json') -class RoundTripTimeQuery(object): - - # TODO This API endpoint has not been tested, neither has the formula used to calculate round trip time. - - """ - A class-based view for querying the round trip time in a given range. - """ - - def __init__(self, request): - """ - Initialises the instance of the view with the request argument. - - :param request: client's call request - """ - - self.request = request - - @view_config(request_method="GET") - def get(self): - """ - A GET API call for the averaged round trip time of a specific media service over a given time range. - - :return: A JSON response with the round trip time and its contributing parts. - """ - - params = {} - for attribute in ROUND_TRIP_ATTRIBUTES: - if attribute in self.request.params: - params[attribute] = self.request.params.get(attribute) - - try: - params = validate_round_trip_query_params(params) - - conf = self.request.registry.settings[CONF_OBJECT] - if conf is None: - raise HTTPBadRequest("You must configure the aggregator before making a round trip time query. Send a PUT request to /aggregator/config with a JSON body of the configuration.") - - aggregator_config_data = {config_attribute: conf[AGGREGATOR_CONFIG_SECTION][config_attribute] for config_attribute in CONFIG_ATTRIBUTES} - aggregator_config_data['aggregator_report_period'] = int(aggregator_config_data['aggregator_report_period']) - - media_service = params.get(ROUND_TRIP_ATTRIBUTES[0]) - start_timestamp = params.get(ROUND_TRIP_ATTRIBUTES[1]) - end_timestamp = params.get(ROUND_TRIP_ATTRIBUTES[2]) - influx_db_name = aggregator_config_data.get(CONFIG_ATTRIBUTES[1]) - influx_db_url = aggregator_config_data.get(CONFIG_ATTRIBUTES[2]) - - url_object = urlparse(influx_db_url) - try: - db_client = InfluxDBClient(host=url_object.hostname, port=url_object.port, database=influx_db_name, timeout=10) - query = 'SELECT mean(*) FROM "{0}"."autogen"."e2e_delays" WHERE time >= {1} and time < {2} and sf_instance = \'{3}\''.format( - influx_db_name, start_timestamp, end_timestamp, media_service) - log.info("Executing query: {0}".format(query)) - result = db_client.query(query) - - actual_result = next(result.get_points(), None) - if actual_result is None: - return {"result": None} - else: - forward_latency = actual_result.get("mean_delay_forward") - reverse_latency = actual_result.get("mean_delay_reverse") - service_delay = actual_result.get("mean_delay_service") - request_size = actual_result.get("mean_avg_request_size") - response_size = actual_result.get("mean_avg_response_size") - bandwidth = actual_result.get("mean_avg_bandwidth") - - rtt = self.calculate_round_trip_time(forward_latency, reverse_latency, service_delay, request_size, response_size, bandwidth) - return {"result": rtt} - except Exception as e: - msg = "Cannot instantiate connection with database {0} on url {1}.".format(influx_db_name, influx_db_url) - log.info(msg) - log.error(type(e)) - log.error(e) - log.error(e.args) - - raise HTTPInternalServerError(msg) - - except AssertionError: - raise HTTPBadRequest('Bad request content - must be in JSON format: {"media_service": value, "start_timestamp": value, "end_timestamp": value}.') - - @staticmethod - def calculate_round_trip_time(forward_latency, reverse_latency, service_delay, request_size, response_size, bandwidth, packet_size=1500, packet_header_size=50): - """ - Calculates the round trip time given the list of arguments. - - :param forward_latency: network latency in forward direction (s) - :param reverse_latency: network latency in reverse direction (s) - :param service_delay: media service delay (s) - :param request_size: request size (bytes) - :param response_size: response size (bytes) - :param bandwidth: network bandwidth (Mb/s) - :param packet_size: size of packet (bytes) - :param packet_header_size: size of the header of the packet (bytes) - :return: the calculated round trip time - """ - - forward_data_delay = (8/10**6) * (request_size / bandwidth) * (packet_size / (packet_size - packet_header_size)) - reverse_data_delay = (8/10**6) * (response_size / bandwidth) * (packet_size / (packet_size - packet_header_size)) - - return forward_latency + forward_data_delay + service_delay + reverse_latency + reverse_data_delay -- GitLab