Merge pull request #3112 from alphagov/channel-restriction

Set broadcast channel as a service setting
This commit is contained in:
David McDonald
2021-02-03 11:46:04 +00:00
committed by GitHub
9 changed files with 233 additions and 26 deletions

View File

@@ -48,6 +48,10 @@ def send_broadcast_provider_message(broadcast_event_id, provider):
for polygon in broadcast_event.transmitted_areas["simple_polygons"]
]
channel = "test"
if broadcast_event.service.broadcast_channel:
channel = broadcast_event.service.broadcast_channel
cbc_proxy_provider_client = cbc_proxy_client.get_proxy(provider)
if broadcast_event.message_type == BroadcastEventMessageType.ALERT:
@@ -59,6 +63,7 @@ def send_broadcast_provider_message(broadcast_event_id, provider):
areas=areas,
sent=broadcast_event.sent_at_as_cap_datetime_string,
expires=broadcast_event.transmitted_finishes_at_as_cap_datetime_string,
channel=channel
)
elif broadcast_event.message_type == BroadcastEventMessageType.UPDATE:
cbc_proxy_provider_client.update_and_send_broadcast(
@@ -70,6 +75,13 @@ def send_broadcast_provider_message(broadcast_event_id, provider):
previous_provider_messages=broadcast_event.get_earlier_provider_messages(provider),
sent=broadcast_event.sent_at_as_cap_datetime_string,
expires=broadcast_event.transmitted_finishes_at_as_cap_datetime_string,
# We think an alert update should always go out on the same channel that created the alert
# We recognise there is a small risk with this code here that if the services channel was
# changed between an alert being sent out and then updated, then something might go wrong
# but we are relying on service channels changing almost never, and not mid incident
# We may consider in the future, changing this such that we store the channel a broadcast was
# sent on on the broadcast message itself and pick the value from there instead of the service
channel=channel
)
elif broadcast_event.message_type == BroadcastEventMessageType.CANCEL:
cbc_proxy_provider_client.cancel_broadcast(

View File

@@ -90,7 +90,7 @@ class CBCProxyClientBase(ABC):
pass
def create_and_send_broadcast(
self, identifier, headline, description, areas, sent, expires, message_number=None
self, identifier, headline, description, areas, sent, expires, channel, message_number=None
):
pass
@@ -98,11 +98,10 @@ class CBCProxyClientBase(ABC):
def update_and_send_broadcast(
self,
identifier, previous_provider_messages, headline, description, areas,
sent, expires, message_number=None
sent, expires, channel, message_number=None
):
pass
# We have not implemented cancelling a broadcast
def cancel_broadcast(
self,
identifier, previous_provider_messages, headline, description, areas,
@@ -198,7 +197,7 @@ class CBCProxyEE(CBCProxyClientBase):
self._invoke_lambda_with_failover(payload=payload)
def create_and_send_broadcast(
self, identifier, headline, description, areas, sent, expires, message_number=None
self, identifier, headline, description, areas, sent, expires, channel, message_number=None
):
payload = {
'message_type': 'alert',
@@ -210,7 +209,7 @@ class CBCProxyEE(CBCProxyClientBase):
'sent': sent,
'expires': expires,
'language': self.infer_language_from(description),
'channel': 'test',
'channel': channel,
}
self._invoke_lambda_with_failover(payload=payload)
@@ -259,7 +258,7 @@ class CBCProxyThree(CBCProxyClientBase):
self._invoke_lambda_with_failover(payload=payload)
def create_and_send_broadcast(
self, identifier, headline, description, areas, sent, expires, message_number=None
self, identifier, headline, description, areas, sent, expires, channel, message_number=None
):
payload = {
'message_type': 'alert',
@@ -271,7 +270,7 @@ class CBCProxyThree(CBCProxyClientBase):
'sent': sent,
'expires': expires,
'language': self.infer_language_from(description),
'channel': 'test',
'channel': channel,
}
self._invoke_lambda_with_failover(payload=payload)
@@ -319,7 +318,7 @@ class CBCProxyO2(CBCProxyClientBase):
self._invoke_lambda_with_failover(payload=payload)
def create_and_send_broadcast(
self, identifier, headline, description, areas, sent, expires, message_number=None
self, identifier, headline, description, areas, sent, expires, channel, message_number=None
):
payload = {
'message_type': 'alert',
@@ -331,7 +330,7 @@ class CBCProxyO2(CBCProxyClientBase):
'sent': sent,
'expires': expires,
'language': self.infer_language_from(description),
'channel': 'test',
'channel': channel,
}
self._invoke_lambda_with_failover(payload=payload)
@@ -381,7 +380,7 @@ class CBCProxyVodafone(CBCProxyClientBase):
self._invoke_lambda_with_failover(payload=payload)
def create_and_send_broadcast(
self, identifier, message_number, headline, description, areas, sent, expires,
self, identifier, message_number, headline, description, areas, sent, expires, channel
):
payload = {
'message_type': 'alert',
@@ -394,7 +393,7 @@ class CBCProxyVodafone(CBCProxyClientBase):
'sent': sent,
'expires': expires,
'language': self.infer_language_from(description),
'channel': 'test',
'channel': channel,
}
self._invoke_lambda_with_failover(payload=payload)

View File

@@ -505,6 +505,7 @@ class Service(db.Model, Versioned):
backref=db.backref('services', lazy='dynamic'))
allowed_broadcast_provider = association_proxy('service_broadcast_provider_restriction', 'provider')
broadcast_channel = association_proxy('service_broadcast_settings', 'channel')
@classmethod
def from_json(cls, data):
@@ -2519,6 +2520,39 @@ class BroadcastProviderMessageNumber(db.Model):
)
class ServiceBroadcastSettings(db.Model):
"""
For the moment, broadcasts services CAN have a row in this table which will configure which broadcast
channel they will send to. If they don't then we will assume they should send to the test channel.
There should only be one row per service in this table, and this is enforced by
the service_id being a primary key.
TODO: We should enforce that every broadcast service will have a row in this table. We will need to do
this when the admin turns a service into a broadcast service, it inserts a row into this table and adds
the service permission for broadcasts for the service. Once that is up and running, we then should write
a DB migration to create rows for all broadcast services that do not have one yet in this table.
TODO: Move functionality on the ServiceBroadcastProviderRestriction into this table and remove the
ServiceBroadcastProviderRestriction table
"""
__tablename__ = "service_broadcast_settings"
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), primary_key=True, nullable=False)
service = db.relationship(Service, backref=db.backref("service_broadcast_settings", uselist=False))
channel = db.Column(
db.String(255), db.ForeignKey('broadcast_channel_types.name'), nullable=False
)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.datetime.utcnow)
class BroadcastChannelTypes(db.Model):
__tablename__ = 'broadcast_channel_types'
name = db.Column(db.String(255), primary_key=True)
class ServiceBroadcastProviderRestriction(db.Model):
"""
Most services don't send broadcasts. Of those that do, most send to all broadcast providers.

View File

@@ -271,6 +271,7 @@ class ServiceSchema(BaseSchema, UUIDsAsStringsMixin):
'reply_to_email_addresses',
'returned_letters',
'service_broadcast_provider_restriction',
'service_broadcast_settings',
'service_notification_stats',
'service_provider_stats',
'service_sms_senders',