Files
notifications-api/app/clients/cbc_proxy.py
Leo Hemsted bc3512467b send messages to multiple providers
at the moment only EE is enabled (this is set in app.config, but also,
only EE have a function defined for them so even if another provider was
enabled without changing the dict in cbc_proxy.py we won't trigger
anything). this commit just adds wrapper tasks that check what providers
are enabled, and invokes the send function for each provider.

The send function doesn't currently distinguish between providers for
now - as we only have EE set up. in the future we'll want to separate
the cbc_proxy_client into separate clients for separate providers.
Different providers have different lambda functions, and have different
requirements. For example, we know that the two different CBC software
solutions handle references to previous messages differently.
2020-11-19 15:50:37 +00:00

155 lines
4.0 KiB
Python

import json
import boto3
from app.models import BroadcastProviders
# The variable names in this file have specific meaning in a CAP message
#
# identifier is a unique field for each CAP message
#
# headline is a field which we are not sure if we will use
#
# description is the body of the message
# areas is a list of dicts, with the following items
# * description is a string which populates the areaDesc field
# * polygon is a list of lat/long pairs
#
# references is a whitespace separated list of message identifiers
# where each identifier is a previous sent message
# ie a Cancel message would have a unique identifier but have the identifier of
# the preceeding Alert message in the references field
class CBCProxyException(Exception):
pass
# Noop = no operation
class CBCProxyNoopClient:
def init_app(self, app):
pass
def send_canary(
self,
identifier,
):
pass
def send_link_test(
self,
identifier,
):
pass
def create_and_send_broadcast(
self,
identifier, headline, description, areas,
sent, expires,
):
pass
# We have not implementated updating a broadcast
def update_and_send_broadcast(
self,
identifier, references, headline, description, areas,
sent, expires,
):
pass
# We have not implemented cancelling a broadcast
def cancel_broadcast(
self,
identifier, references, headline, description, areas,
sent, expires,
):
pass
class CBCProxyClient:
provider_function_name_map = {
BroadcastProviders.EE: 'bt-ee-1-proxy',
}
def init_app(self, app):
self._lambda_client = boto3.client(
'lambda',
region_name='eu-west-2',
aws_access_key_id=app.config['CBC_PROXY_AWS_ACCESS_KEY_ID'],
aws_secret_access_key=app.config['CBC_PROXY_AWS_SECRET_ACCESS_KEY'],
)
def _invoke_lambda(self, function_name, payload):
payload_bytes = bytes(json.dumps(payload), encoding='utf8')
result = self._lambda_client.invoke(
FunctionName=function_name,
InvocationType='RequestResponse',
Payload=payload_bytes,
)
if result['StatusCode'] > 299:
raise CBCProxyException('Could not invoke lambda')
if 'FunctionError' in result:
raise CBCProxyException('Function exited with unhandled exception')
return result
def send_canary(
self,
identifier,
):
"""
canary - a specific lambda that does not connect to a provider, but just confirms the connectivity between
Notify and the CBC proxy AWS account
"""
self._invoke_lambda(function_name='canary', payload={'identifier': identifier})
def send_link_test(
self,
identifier,
provider,
):
"""
link test - open up a connection to a specific provider, and send them an xml payload with a <msgType> of
test.
"""
payload = {'message_type': 'test', 'identifier': identifier}
self._invoke_lambda(function_name='bt-ee-1-proxy', payload=payload)
def create_and_send_broadcast(
self,
identifier, headline, description, areas,
sent, expires,
):
payload = {
'message_type': 'alert',
'identifier': identifier,
'headline': headline,
'description': description,
'areas': areas,
'sent': sent,
'expires': expires,
}
self._invoke_lambda(function_name='bt-ee-1-proxy', payload=payload)
# We have not implementated updating a broadcast
def update_and_send_broadcast(
self,
identifier, references, headline, description, areas,
sent, expires,
):
pass
# We have not implemented cancelling a broadcast
def cancel_broadcast(
self,
identifier, references, headline, description, areas,
sent, expires,
):
pass