Skip to content

Commit f713a3c

Browse files
committed
work in review suggestions
1 parent 8c5cdf7 commit f713a3c

File tree

2 files changed

+76
-84
lines changed

2 files changed

+76
-84
lines changed

localstack-core/localstack/services/sns/v2/models.py

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,21 @@
1-
import json
21
from typing import TypedDict
32

4-
from localstack.aws.api import RequestContext
53
from localstack.aws.api.sns import TopicAttributesMap
64
from localstack.services.stores import (
75
AccountRegionBundle,
86
BaseStore,
97
CrossRegionAttribute,
108
LocalAttribute,
119
)
12-
from localstack.utils.aws.arns import sns_topic_arn
1310
from localstack.utils.tagging import TaggingService
1411

1512

1613
class Topic(TypedDict, total=True):
1714
arn: str
1815
name: str
19-
region: str
20-
account_id: str
2116
attributes: TopicAttributesMap
2217

2318

24-
def create_topic(name: str, attributes: dict, context: RequestContext) -> Topic:
25-
topic_arn = sns_topic_arn(
26-
topic_name=name, region_name=context.region, account_id=context.account_id
27-
)
28-
topic: Topic = {
29-
"name": name,
30-
"arn": topic_arn,
31-
"region": context.region,
32-
"account_id": context.account_id,
33-
"attributes": {},
34-
}
35-
attrs = default_attributes(topic)
36-
attrs.update(attributes or {})
37-
topic["attributes"] = attrs
38-
39-
return topic
40-
41-
42-
def default_attributes(topic: Topic) -> TopicAttributesMap:
43-
default_attributes = {
44-
"DisplayName": "",
45-
"Owner": topic["account_id"],
46-
"Policy": create_default_topic_policy(topic),
47-
"SubscriptionsConfirmed": "0",
48-
"SubscriptionsDeleted": "0",
49-
"SubscriptionsPending": "0",
50-
"TopicArn": topic["arn"],
51-
}
52-
if topic["name"].endswith(".fifo"):
53-
default_attributes.update(
54-
{
55-
"ContentBasedDeduplication": "false",
56-
"FifoTopic": "false",
57-
"SignatureVersion": "2",
58-
}
59-
)
60-
return default_attributes
61-
62-
63-
def create_default_topic_policy(topic: Topic) -> str:
64-
return json.dumps(
65-
{
66-
"Version": "2008-10-17",
67-
"Id": "__default_policy_ID",
68-
"Statement": [
69-
{
70-
"Effect": "Allow",
71-
"Sid": "__default_statement_ID",
72-
"Principal": {"AWS": "*"},
73-
"Action": [
74-
"SNS:GetTopicAttributes",
75-
"SNS:SetTopicAttributes",
76-
"SNS:AddPermission",
77-
"SNS:RemovePermission",
78-
"SNS:DeleteTopic",
79-
"SNS:Subscribe",
80-
"SNS:ListSubscriptionsByTopic",
81-
"SNS:Publish",
82-
],
83-
"Resource": topic["arn"],
84-
"Condition": {"StringEquals": {"AWS:SourceOwner": topic["account_id"]}},
85-
}
86-
],
87-
}
88-
)
89-
90-
9119
class SnsStore(BaseStore):
9220
topics: dict[str, Topic] = LocalAttribute(default=dict)
9321

localstack-core/localstack/services/sns/v2/provider.py

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import logging
23
import re
34

@@ -19,7 +20,7 @@
1920
topicARN,
2021
topicName,
2122
)
22-
from localstack.services.sns.v2.models import SnsStore, Topic, create_topic, sns_stores
23+
from localstack.services.sns.v2.models import SnsStore, Topic, sns_stores
2324
from localstack.utils.aws.arns import ArnData, parse_arn, sns_topic_arn
2425
from localstack.utils.collections import PaginatedList
2526

@@ -41,18 +42,18 @@ def create_topic(
4142
**kwargs,
4243
) -> CreateTopicResponse:
4344
store = self.get_store(context.account_id, context.region)
44-
topic_ARN = sns_topic_arn(
45+
topic_arn = sns_topic_arn(
4546
topic_name=name, region_name=context.region, account_id=context.account_id
4647
)
47-
topic: Topic = store.topics.get(topic_ARN)
48+
topic: Topic = store.topics.get(topic_arn)
4849
attributes = attributes or {}
4950
if topic:
5051
attrs = topic["attributes"]
5152
for k, v in attributes.values():
5253
if not attrs.get(k) or not attrs.get(k) == v:
5354
# TODO:
5455
raise InvalidParameterException("Fix this Exception message and type")
55-
return CreateTopicResponse(TopicArn=topic_ARN)
56+
return CreateTopicResponse(TopicArn=topic_arn)
5657

5758
attributes = attributes or {}
5859
if attributes.get("FifoTopic") and attributes["FifoTopic"].lower() == "true":
@@ -64,19 +65,16 @@ def create_topic(
6465
)
6566
else:
6667
# AWS does not seem to save explicit settings of fifo = false
67-
try:
68-
attributes.pop("FifoTopic", None)
69-
except KeyError:
70-
pass
68+
attributes.pop("FifoTopic", None)
7169
name_match = re.match(SNS_TOPIC_NAME_PATTERN, name)
7270
if not name_match:
7371
raise InvalidParameterException("Invalid parameter: Topic Name")
7472

75-
topic = create_topic(name=name, attributes=attributes, context=context)
76-
store.topics[topic_ARN] = topic
73+
topic = _create_topic(name=name, attributes=attributes, context=context)
74+
store.topics[topic_arn] = topic
7775
# todo: tags
7876

79-
return CreateTopicResponse(TopicArn=topic_ARN)
77+
return CreateTopicResponse(TopicArn=topic_arn)
8078

8179
def get_topic_attributes(
8280
self, context: RequestContext, topic_arn: topicARN, **kwargs
@@ -122,12 +120,13 @@ def set_topic_attributes(
122120
def get_store(account_id: str, region: str) -> SnsStore:
123121
return sns_stores[account_id][region]
124122

123+
# TODO: reintroduce multi-region parameter (latest before final migration from v1)
125124
@staticmethod
126125
def _get_topic(arn: str, context: RequestContext) -> Topic:
127126
"""
128127
:param arn: the Topic ARN
129128
:param context: the RequestContext of the request
130-
:return: the Moto model Topic
129+
:return: the model Topic
131130
"""
132131
arn_data = parse_and_validate_topic_arn(arn)
133132
if context.region != arn_data["region"]:
@@ -148,3 +147,68 @@ def parse_and_validate_topic_arn(topic_arn: str | None) -> ArnData:
148147
raise InvalidParameterException(
149148
f"Invalid parameter: TopicArn Reason: An ARN must have at least 6 elements, not {count}"
150149
)
150+
151+
152+
def _create_topic(name: str, attributes: dict, context: RequestContext) -> Topic:
153+
topic_arn = sns_topic_arn(
154+
topic_name=name, region_name=context.region, account_id=context.account_id
155+
)
156+
topic: Topic = {
157+
"name": name,
158+
"arn": topic_arn,
159+
"attributes": {},
160+
}
161+
attrs = _default_attributes(topic, context)
162+
attrs.update(attributes or {})
163+
topic["attributes"] = attrs
164+
165+
return topic
166+
167+
168+
def _default_attributes(topic: Topic, context: RequestContext) -> TopicAttributesMap:
169+
default_attributes = {
170+
"DisplayName": "",
171+
"Owner": context.account_id,
172+
"Policy": _create_default_topic_policy(topic, context),
173+
"SubscriptionsConfirmed": "0",
174+
"SubscriptionsDeleted": "0",
175+
"SubscriptionsPending": "0",
176+
"TopicArn": topic["arn"],
177+
}
178+
if topic["name"].endswith(".fifo"):
179+
default_attributes.update(
180+
{
181+
"ContentBasedDeduplication": "false",
182+
"FifoTopic": "false",
183+
"SignatureVersion": "2",
184+
}
185+
)
186+
return default_attributes
187+
188+
189+
def _create_default_topic_policy(topic: Topic, context: RequestContext) -> str:
190+
return json.dumps(
191+
{
192+
"Version": "2008-10-17",
193+
"Id": "__default_policy_ID",
194+
"Statement": [
195+
{
196+
"Effect": "Allow",
197+
"Sid": "__default_statement_ID",
198+
"Principal": {"AWS": "*"},
199+
"Action": [
200+
"SNS:GetTopicAttributes",
201+
"SNS:SetTopicAttributes",
202+
"SNS:AddPermission",
203+
"SNS:RemovePermission",
204+
"SNS:DeleteTopic",
205+
"SNS:Subscribe",
206+
"SNS:ListSubscriptionsByTopic",
207+
"SNS:Publish",
208+
],
209+
"Resource": topic["arn"],
210+
"Condition": {"StringEquals": {"AWS:SourceOwner": context.account_id}},
211+
}
212+
],
213+
}
214+
)

0 commit comments

Comments
 (0)