From ed52f41039484239203ad114b287b2efd0920111 Mon Sep 17 00:00:00 2001 From: Imdad Ahad Date: Fri, 27 Jan 2017 12:21:08 +0000 Subject: [PATCH] Add, init and config performance platform client to prepare/upload daily notification stats --- app/__init__.py | 3 +- app/clients/performance_platform/__init__.py | 0 .../performance_platform_client.py | 57 +++++++++++++++ app/config.py | 5 ++ .../app/clients/test_performance_platform.py | 71 +++++++++++++++++++ 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 app/clients/performance_platform/__init__.py create mode 100644 app/clients/performance_platform/performance_platform_client.py create mode 100644 tests/app/clients/test_performance_platform.py diff --git a/app/__init__.py b/app/__init__.py index a13dacd8b..e9a528072 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,5 @@ import os import uuid -import json from flask import Flask, _request_ctx_stack from flask import request, url_for, g, jsonify @@ -18,6 +17,7 @@ from app.clients.email.aws_ses import AwsSesClient from app.clients.sms.firetext import FiretextClient from app.clients.sms.loadtesting import LoadtestingClient from app.clients.sms.mmg import MMGClient +from app.clients.performance_platform.performance_platform_client import PerformancePlatformClient from app.encryption import Encryption @@ -34,6 +34,7 @@ aws_ses_client = AwsSesClient() encryption = Encryption() statsd_client = StatsdClient() redis_store = RedisClient() +performance_platform_client = PerformancePlatformClient() clients = Clients() diff --git a/app/clients/performance_platform/__init__.py b/app/clients/performance_platform/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/app/clients/performance_platform/performance_platform_client.py b/app/clients/performance_platform/performance_platform_client.py new file mode 100644 index 000000000..f9f777a1b --- /dev/null +++ b/app/clients/performance_platform/performance_platform_client.py @@ -0,0 +1,57 @@ +import base64 +import json +from requests import request + +from flask import current_app + + +class PerformancePlatformClient: + + def init_app(self, app): + self.active = app.config.get('PERFORMANCE_PLATFORM_ENABLED') + if self.active: + self.bearer_token = app.config.get('PERFORMANCE_PLATFORM_TOKEN') + self.performance_platform_url = current_app.config.get('PERFORMANCE_PLATFORM_URL') + + def send_performance_stats(self, date, channel, count, period): + if self.active: + payload = { + '_timestamp': date, + 'service': 'govuk-notify', + 'channel': channel, + 'count': count, + 'dataType': 'notifications', + 'period': period + } + self._add_id_for_payload(payload) + self._send_stats_to_performance_platform(payload) + + def _send_stats_to_performance_platform(self, payload): + headers = { + 'Content-Type': "application/json", + 'Authorization': 'Bearer {}'.format(self.bearer_token) + } + resp = request( + "POST", + self.performance_platform_url, + data=json.dumps(payload), + headers=headers + ) + + if resp.status_code != 200: + current_app.logger.error( + "Performance platform update request failed with {} '{}'".format( + resp.status_code, + resp.json()) + ) + + def _add_id_for_payload(self, payload): + payload_string = '{}{}{}{}{}'.format( + payload['_timestamp'], + payload['service'], + payload['channel'], + payload['dataType'], + payload['period'] + ) + _id = base64.b64encode(payload_string.encode('utf-8')) + payload.update({'_id': _id.decode('utf-8')}) diff --git a/app/config.py b/app/config.py index 8d10051ef..cedaf235c 100644 --- a/app/config.py +++ b/app/config.py @@ -50,6 +50,11 @@ class Config(object): REDIS_URL = os.getenv('REDIS_URL') REDIS_ENABLED = os.getenv('REDIS_ENABLED') == '1' + # Performance platform + PERFORMANCE_PLATFORM_ENABLED = os.getenv('PERFORMANCE_PLATFORM_ENABLED') == '1' + PERFORMANCE_PLATFORM_URL = os.getenv('PERFORMANCE_PLATFORM_URL') + PERFORMANCE_PLATFORM_TOKEN = os.getenv('PERFORMANCE_PLATFORM_TOKEN') + # Logging DEBUG = False LOGGING_STDOUT_JSON = os.getenv('LOGGING_STDOUT_JSON') == '1' diff --git a/tests/app/clients/test_performance_platform.py b/tests/app/clients/test_performance_platform.py new file mode 100644 index 000000000..b6caad468 --- /dev/null +++ b/tests/app/clients/test_performance_platform.py @@ -0,0 +1,71 @@ +import requests_mock +import pytest + +from app.clients.performance_platform.performance_platform_client import PerformancePlatformClient + + +@pytest.fixture(scope='function') +def client(mocker): + client = PerformancePlatformClient() + current_app = mocker.Mock(config={ + 'PERFORMANCE_PLATFORM_ENABLED': True, + 'PERFORMANCE_PLATFORM_URL': 'performance-platform-url', + 'PERFORMANCE_PLATFORM_TOKEN': 'token' + }) + client.init_app(current_app) + return client + + +def test_should_not_call_if_not_enabled(notify_api, client, mocker): + mocker.patch.object(client, '_send_stats_to_performance_platform') + client.active = False + client.send_performance_stats( + date='2016-10-16T00:00:00+00:00', + channel='sms', + count=142, + period='day' + ) + + client._send_stats_to_performance_platform.assert_not_called() + + +def test_should_call_if_enabled(notify_api, client, mocker): + mocker.patch.object(client, '_send_stats_to_performance_platform') + client.send_performance_stats( + date='2016-10-16T00:00:00+00:00', + channel='sms', + count=142, + period='day' + ) + + assert client._send_stats_to_performance_platform.call_count == 1 + + +def test_send_platform_stats_creates_correct_call(notify_api, client): + with requests_mock.Mocker() as request_mock: + request_mock.post( + client.performance_platform_url, + json={}, + status_code=200 + ) + client.send_performance_stats( + date='2016-10-16T00:00:00+00:00', + channel='sms', + count=142, + period='day' + ) + + assert request_mock.call_count == 1 + + assert request_mock.request_history[0].url == client.performance_platform_url + assert request_mock.request_history[0].method == 'POST' + + request_args = request_mock.request_history[0].json() + assert request_args['dataType'] == 'notifications' + assert request_args['service'] == 'govuk-notify' + assert request_args['period'] == 'day' + assert request_args['channel'] == 'sms' + assert request_args['_timestamp'] == '2016-10-16T00:00:00+00:00' + assert request_args['count'] == 142 + expected_base64_id = 'MjAxNi0xMC0xNlQwMDowMDowMCswMDowMGdvdnVrLW5vdGlmeXNtc25vdGlmaWNhdGlvbnNkYXk=' + assert request_args['_id'] == expected_base64_id