mirror of
https://github.com/GSA/notifications-api.git
synced 2026-01-31 23:26:23 -05:00
Merge pull request #448 from GSA/notify-api-390
notify-api-390 use moto to mock text sending.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
@@ -39,9 +40,15 @@ def check_sms_delivery_receipt(self, message_id, notification_id, sent_at):
|
|||||||
failure appears in the cloudwatch logs, so this should keep retrying until the log appears, or until
|
failure appears in the cloudwatch logs, so this should keep retrying until the log appears, or until
|
||||||
we run out of retries.
|
we run out of retries.
|
||||||
"""
|
"""
|
||||||
status, provider_response = aws_cloudwatch_client.check_sms(
|
# TODO the localstack cloudwatch doesn't currently have our log groups. Possibly create them with awslocal?
|
||||||
message_id, notification_id, sent_at
|
if aws_cloudwatch_client.is_localstack():
|
||||||
)
|
status = "success"
|
||||||
|
provider_response = "this is a fake successful localstack sms message"
|
||||||
|
else:
|
||||||
|
status, provider_response = aws_cloudwatch_client.check_sms(
|
||||||
|
message_id, notification_id, sent_at
|
||||||
|
)
|
||||||
|
|
||||||
if status == "success":
|
if status == "success":
|
||||||
status = NOTIFICATION_DELIVERED
|
status = NOTIFICATION_DELIVERED
|
||||||
elif status == "failure":
|
elif status == "failure":
|
||||||
@@ -73,8 +80,19 @@ def deliver_sms(self, notification_id):
|
|||||||
"Start sending SMS for notification id: {}".format(notification_id)
|
"Start sending SMS for notification id: {}".format(notification_id)
|
||||||
)
|
)
|
||||||
notification = notifications_dao.get_notification_by_id(notification_id)
|
notification = notifications_dao.get_notification_by_id(notification_id)
|
||||||
|
ansi_green = "\033[32m"
|
||||||
|
ansi_reset = "\033[0m"
|
||||||
|
|
||||||
if not notification:
|
if not notification:
|
||||||
raise NoResultFound()
|
raise NoResultFound()
|
||||||
|
if (
|
||||||
|
os.getenv("NOTIFY_ENVIRONMENT") == "development"
|
||||||
|
and "authentication code" in notification.content
|
||||||
|
):
|
||||||
|
current_app.logger.warning(
|
||||||
|
ansi_green + f"AUTHENTICATION CODE: {notification.content}" + ansi_reset
|
||||||
|
)
|
||||||
|
|
||||||
message_id = send_to_providers.send_sms_to_provider(notification)
|
message_id = send_to_providers.send_sms_to_provider(notification)
|
||||||
# We have to put it in UTC. For other timezones, the delay
|
# We have to put it in UTC. For other timezones, the delay
|
||||||
# will be ignored and it will fire immediately (although this probably only affects developer testing)
|
# will be ignored and it will fire immediately (although this probably only affects developer testing)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -14,13 +15,26 @@ class AwsCloudwatchClient(Client):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def init_app(self, current_app, *args, **kwargs):
|
def init_app(self, current_app, *args, **kwargs):
|
||||||
self._client = client(
|
if os.getenv("LOCALSTACK_ENDPOINT_URL"):
|
||||||
"logs",
|
self._client = client(
|
||||||
region_name=cloud_config.sns_region,
|
"logs",
|
||||||
aws_access_key_id=cloud_config.sns_access_key,
|
region_name=cloud_config.sns_region,
|
||||||
aws_secret_access_key=cloud_config.sns_secret_key,
|
aws_access_key_id=cloud_config.sns_access_key,
|
||||||
config=AWS_CLIENT_CONFIG,
|
aws_secret_access_key=cloud_config.sns_secret_key,
|
||||||
)
|
config=AWS_CLIENT_CONFIG,
|
||||||
|
endpoint_url=os.getenv("LOCALSTACK_ENDPOINT_URL"),
|
||||||
|
)
|
||||||
|
self._is_localstack = True
|
||||||
|
else:
|
||||||
|
self._client = client(
|
||||||
|
"logs",
|
||||||
|
region_name=cloud_config.sns_region,
|
||||||
|
aws_access_key_id=cloud_config.sns_access_key,
|
||||||
|
aws_secret_access_key=cloud_config.sns_secret_key,
|
||||||
|
config=AWS_CLIENT_CONFIG,
|
||||||
|
)
|
||||||
|
self._is_localstack = False
|
||||||
|
|
||||||
super(Client, self).__init__(*args, **kwargs)
|
super(Client, self).__init__(*args, **kwargs)
|
||||||
self.current_app = current_app
|
self.current_app = current_app
|
||||||
self._valid_sender_regex = re.compile(r"^\+?\d{5,14}$")
|
self._valid_sender_regex = re.compile(r"^\+?\d{5,14}$")
|
||||||
@@ -29,6 +43,9 @@ class AwsCloudwatchClient(Client):
|
|||||||
def name(self):
|
def name(self):
|
||||||
return "cloudwatch"
|
return "cloudwatch"
|
||||||
|
|
||||||
|
def is_localstack(self):
|
||||||
|
return self._is_localstack
|
||||||
|
|
||||||
def _get_log(self, my_filter, log_group_name, sent_at):
|
def _get_log(self, my_filter, log_group_name, sent_at):
|
||||||
# Check all cloudwatch logs from the time the notification was sent (currently 5 minutes previously) until now
|
# Check all cloudwatch logs from the time the notification was sent (currently 5 minutes previously) until now
|
||||||
now = round(time.time() * 1000)
|
now = round(time.time() * 1000)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from time import monotonic
|
from time import monotonic
|
||||||
|
|
||||||
@@ -16,13 +17,24 @@ class AwsSnsClient(SmsClient):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def init_app(self, current_app, *args, **kwargs):
|
def init_app(self, current_app, *args, **kwargs):
|
||||||
self._client = client(
|
if os.getenv("LOCALSTACK_ENDPOINT_URL"):
|
||||||
"sns",
|
self._client = client(
|
||||||
region_name=cloud_config.sns_region,
|
"sns",
|
||||||
aws_access_key_id=cloud_config.sns_access_key,
|
region_name=cloud_config.sns_region,
|
||||||
aws_secret_access_key=cloud_config.sns_secret_key,
|
aws_access_key_id=cloud_config.sns_access_key,
|
||||||
config=AWS_CLIENT_CONFIG,
|
aws_secret_access_key=cloud_config.sns_secret_key,
|
||||||
)
|
config=AWS_CLIENT_CONFIG,
|
||||||
|
endpoint_url=os.getenv("LOCALSTACK_ENDPOINT_URL"),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self._client = client(
|
||||||
|
"sns",
|
||||||
|
region_name=cloud_config.sns_region,
|
||||||
|
aws_access_key_id=cloud_config.sns_access_key,
|
||||||
|
aws_secret_access_key=cloud_config.sns_secret_key,
|
||||||
|
config=AWS_CLIENT_CONFIG,
|
||||||
|
)
|
||||||
|
|
||||||
super(SmsClient, self).__init__(*args, **kwargs)
|
super(SmsClient, self).__init__(*args, **kwargs)
|
||||||
self.current_app = current_app
|
self.current_app = current_app
|
||||||
self._valid_sender_regex = re.compile(r"^\+?\d{5,14}$")
|
self._valid_sender_regex = re.compile(r"^\+?\d{5,14}$")
|
||||||
|
|||||||
44
docs/localstack.md
Normal file
44
docs/localstack.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
How to Use Localstack in Your Development Work
|
||||||
|
==================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Install Docker Desktop (One-Time)
|
||||||
|
|
||||||
|
* https://docs.docker.com/desktop/install/mac-install/
|
||||||
|
|
||||||
|
|
||||||
|
### Install Localstack (One-Time)
|
||||||
|
|
||||||
|
* >pip install --upgrade localstack
|
||||||
|
* >localstack --version # should be 2.2.0 or later
|
||||||
|
|
||||||
|
|
||||||
|
### Add LOCALSTACK_ENDPOINT_URL to Your .env File (One-Time)
|
||||||
|
|
||||||
|
* Find the value in the sample.env file (# LOCALSTACK_ENDPOINT_URL=http://localhost:4566).
|
||||||
|
* Copy and uncomment it into your .env file
|
||||||
|
|
||||||
|
### Run with Localstack (Recurring)
|
||||||
|
|
||||||
|
#### Start Docker Desktop and localstack image
|
||||||
|
|
||||||
|
* Open Docker Desktop from Finder
|
||||||
|
* Images->Local->localstack/localstack click on the start button on the right hand side to get the localstack
|
||||||
|
docker image going
|
||||||
|
|
||||||
|
|
||||||
|
#### Start Localstack
|
||||||
|
|
||||||
|
* From your project directory in a separate terminal window, either:
|
||||||
|
* >localstack start
|
||||||
|
* >pipenv run localstack start
|
||||||
|
|
||||||
|
#### Proceed With Your Usual Development Activities
|
||||||
|
|
||||||
|
Assuming you followed all these steps and nothing went wrong, you should be running with localstack for SNS now.
|
||||||
|
You should be able to send an SMS message in the UI and observe it in the dashboard moving from Pending to Delivered
|
||||||
|
over a period of five minutes. And you should not receive a text message.
|
||||||
|
|
||||||
|
NOTE: You will still be prompted for a 2FA code when you log in. To get the code, look in the notification-api
|
||||||
|
logs for "AUTHENTICATION_CODE:".
|
||||||
@@ -16,6 +16,10 @@ AWS_US_TOLL_FREE_NUMBER=+18556438890
|
|||||||
# DATABASE_URL=postgresql://postgres:chummy@db:5432/notification_api
|
# DATABASE_URL=postgresql://postgres:chummy@db:5432/notification_api
|
||||||
# SQLALCHEMY_DATABASE_TEST_URI=postgresql://postgres:chummy@db:5432/test_notification_api
|
# SQLALCHEMY_DATABASE_TEST_URI=postgresql://postgres:chummy@db:5432/test_notification_api
|
||||||
|
|
||||||
|
|
||||||
|
# If you want to do local development with localstack copy this to your .env file and uncomment it
|
||||||
|
# LOCALSTACK_ENDPOINT_URL=http://localhost:4566
|
||||||
|
|
||||||
# Local direct setup, all overwritten in cloud.gov
|
# Local direct setup, all overwritten in cloud.gov
|
||||||
ADMIN_BASE_URL=http://localhost:6012
|
ADMIN_BASE_URL=http://localhost:6012
|
||||||
API_HOST_NAME=http://localhost:6011
|
API_HOST_NAME=http://localhost:6011
|
||||||
|
|||||||
Reference in New Issue
Block a user