Skip to content
This repository was archived by the owner on Aug 30, 2023. It is now read-only.

Commit 05ea16c

Browse files
author
Stephen Cefali
authored
fix(plugins): Add MessageGroup to SQS (#502)
* fix(plugins): Add MessageGroup to SQS
1 parent 85a3c0f commit 05ea16c

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

src/sentry_plugins/amazon_sqs/plugin.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import boto3
66
from botocore.client import ClientError
7-
87
from sentry_plugins.base import CorePluginMixin
98
from sentry.plugins.bases.data_forwarding import DataForwardingPlugin
109
from sentry_plugins.utils import get_secret_field_config
@@ -43,13 +42,21 @@ def get_config(self, project, **kwargs):
4342
get_secret_field_config(
4443
name="secret_key", label="Secret Key", secret=self.get_option("secret_key", project)
4544
),
45+
{
46+
"name": "message_group_id",
47+
"label": "Message Group ID",
48+
"type": "text",
49+
"required": False,
50+
"placeholder": "Required for FIFO queues, exclude for standard queues",
51+
},
4652
]
4753

4854
def forward_event(self, event, payload):
4955
queue_url = self.get_option("queue_url", event.project)
5056
access_key = self.get_option("access_key", event.project)
5157
secret_key = self.get_option("secret_key", event.project)
5258
region = self.get_option("region", event.project)
59+
message_group_id = self.get_option("message_group_id", event.project)
5360

5461
if not all((queue_url, access_key, secret_key, region)):
5562
return
@@ -68,7 +75,20 @@ def forward_event(self, event, payload):
6875
aws_secret_access_key=secret_key,
6976
region_name=region,
7077
)
71-
client.send_message(QueueUrl=queue_url, MessageBody=message)
78+
79+
message = {"QueueUrl": queue_url, "MessageBody": message}
80+
81+
# need a MessageGroupId for FIFO queues
82+
# note that if MessageGroupId is specified for non-FIFO, this will fail
83+
if message_group_id:
84+
from uuid import uuid4
85+
86+
message["MessageGroupId"] = message_group_id
87+
# if content based de-duplication is not enabled, we need to provide a
88+
# MessageDeduplicationId
89+
message["MessageDeduplicationId"] = uuid4().hex
90+
91+
client.send_message(**message)
7292
except ClientError as e:
7393
if e.message.startswith("An error occurred (AccessDenied)"):
7494
# If there's an issue with the user's token then we can't do
@@ -92,6 +112,27 @@ def forward_event(self, event, payload):
92112
},
93113
)
94114
return False
115+
elif e.message.endswith("must contain the parameter MessageGroupId."):
116+
metrics_name = "sentry_plugins.amazon_sqs.missing_message_group_id"
117+
logger.info(
118+
metrics_name,
119+
extra={
120+
"queue_url": queue_url,
121+
"access_key": access_key,
122+
"region": region,
123+
"project_id": event.project.id,
124+
"organization_id": event.project.organization_id,
125+
"message_group_id": message_group_id,
126+
},
127+
)
128+
metrics.incr(
129+
metrics_name,
130+
tags={
131+
"project_id": event.project_id,
132+
"organization_id": event.project.organization_id,
133+
},
134+
)
135+
return False
95136
raise
96137

97138
return True

tests/amazon_sqs/test_plugin.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,41 @@ def test_token_error(self, mock_client, logger):
7777
assert (
7878
logger.info.call_args_list[0][0][0] == "sentry_plugins.amazon_sqs.access_token_invalid"
7979
)
80+
81+
@patch("sentry_plugins.amazon_sqs.plugin.logger")
82+
@patch("boto3.client")
83+
def test_message_group_error(self, mock_client, logger):
84+
mock_client.return_value.send_message.side_effect = ClientError(
85+
{
86+
"Error": {
87+
"Code": "MissingParameter",
88+
"Message": "The request must contain the parameter MessageGroupId.",
89+
}
90+
},
91+
"SendMessage",
92+
)
93+
94+
self.run_test()
95+
96+
assert len(logger.info.call_args_list) == 1
97+
assert (
98+
logger.info.call_args_list[0][0][0]
99+
== "sentry_plugins.amazon_sqs.missing_message_group_id"
100+
)
101+
102+
@patch("uuid.uuid4")
103+
@patch("boto3.client")
104+
def test_pass_message_group_id(self, mock_client, mock_uuid):
105+
class uuid(object):
106+
hex = "some-uuid"
107+
108+
mock_uuid.return_value = uuid
109+
self.plugin.set_option("message_group_id", "my_group", self.project)
110+
event = self.run_test()
111+
112+
mock_client.return_value.send_message.assert_called_once_with(
113+
QueueUrl="https://sqs-us-east-1.amazonaws.com/12345678/myqueue",
114+
MessageBody=json.dumps(self.plugin.get_event_payload(event)),
115+
MessageGroupId="my_group",
116+
MessageDeduplicationId="some-uuid",
117+
)

0 commit comments

Comments
 (0)