Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ exec: true # Enable running commands in your container.
publish:
topics:
- name: givesOtherdogs
- name: mytopic
fifo: true
- name: yourtopic
fifo:
content_based_deduplication: true
- name: nonfifotopic
fifo: false

subscribe:
queue:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ Metadata:
publish:
topics:
- name: givesOtherdogs
- name: mytopic
fifo: true
- name: yourtopic
fifo:
content_based_deduplication: true
- name: nonfifotopic
fifo: false

subscribe:
queue:
Expand Down Expand Up @@ -151,7 +158,7 @@ Resources:
- Name: COPILOT_SERVICE_NAME
Value: !Sub '${WorkloadName}'
- Name: COPILOT_SNS_TOPIC_ARNS
Value: '{"givesOtherdogs":"arn:aws:sns:us-west-2:123456789123:my-app-test-dogworker-givesOtherdogs"}'
Value: '{"givesOtherdogs":"arn:aws:sns:us-west-2:123456789123:my-app-test-dogworker-givesOtherdogs","mytopic":"arn:aws:sns:us-west-2:123456789123:my-app-test-dogworker-mytopic.fifo","nonfifotopic":"arn:aws:sns:us-west-2:123456789123:my-app-test-dogworker-nonfifotopic","yourtopic":"arn:aws:sns:us-west-2:123456789123:my-app-test-dogworker-yourtopic.fifo"}'
- Name: COPILOT_QUEUE_URI
Value: !Ref EventsQueue
- Name: COPILOT_TOPIC_QUEUE_URIS
Expand Down Expand Up @@ -283,6 +290,9 @@ Resources:
Action: 'sns:Publish'
Resource:
- !Ref givesOtherdogsSNSTopic
- !Ref mytopicSNSTopic
- !Ref yourtopicSNSTopic
- !Ref nonfifotopicSNSTopic
DynamicDesiredCountAction:
Metadata:
'aws:copilot:description': "A custom resource returning the ECS service's running task count"
Expand Down Expand Up @@ -926,6 +936,84 @@ Resources:
Condition:
StringEquals:
"sns:Protocol": "sqs"
mytopicSNSTopic:
Metadata:
'aws:copilot:description': 'A FIFO SNS topic to broadcast mytopic events'
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub '${AWS::StackName}-mytopic.fifo'
FifoTopic: true
KmsMasterKeyId: 'alias/aws/sns'
mytopicSNSTopicPolicy:
Type: AWS::SNS::TopicPolicy
DependsOn: mytopicSNSTopic
Properties:
Topics:
- !Ref mytopicSNSTopic
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root'
Action:
- sns:Subscribe
Resource: !Ref mytopicSNSTopic
Condition:
StringEquals:
"sns:Protocol": "sqs"
yourtopicSNSTopic:
Metadata:
'aws:copilot:description': 'A FIFO SNS topic to broadcast yourtopic events'
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub '${AWS::StackName}-yourtopic.fifo'
FifoTopic: true
ContentBasedDeduplication: true
KmsMasterKeyId: 'alias/aws/sns'
yourtopicSNSTopicPolicy:
Type: AWS::SNS::TopicPolicy
DependsOn: yourtopicSNSTopic
Properties:
Topics:
- !Ref yourtopicSNSTopic
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root'
Action:
- sns:Subscribe
Resource: !Ref yourtopicSNSTopic
Condition:
StringEquals:
"sns:Protocol": "sqs"
nonfifotopicSNSTopic:
Metadata:
'aws:copilot:description': 'A SNS topic to broadcast nonfifotopic events'
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub '${AWS::StackName}-nonfifotopic'
KmsMasterKeyId: 'alias/aws/sns'
nonfifotopicSNSTopicPolicy:
Type: AWS::SNS::TopicPolicy
DependsOn: nonfifotopicSNSTopic
Properties:
Topics:
- !Ref nonfifotopicSNSTopic
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root'
Action:
- sns:Subscribe
Resource: !Ref nonfifotopicSNSTopic
Condition:
StringEquals:
"sns:Protocol": "sqs"
AddonsStack:
Metadata:
'aws:copilot:description': 'An Addons CloudFormation Stack for your additional AWS resources'
Expand Down
24 changes: 17 additions & 7 deletions internal/pkg/deploy/cloudformation/stack/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,14 +803,24 @@ func convertPublish(topics []manifest.Topic, accountID, region, app, env, svc st
var publishers template.PublishOpts
// convert the topics to template Topics
for _, topic := range topics {
var fifoConfig *template.FIFOTopicConfig
if topic.FIFO.IsEnabled() {
fifoConfig = &template.FIFOTopicConfig{}
Comment thread
paragbhingre marked this conversation as resolved.
if !topic.FIFO.Advanced.IsEmpty() {
fifoConfig = &template.FIFOTopicConfig{
ContentBasedDeduplication: topic.FIFO.Advanced.ContentBasedDeduplication,
}
}
}
publishers.Topics = append(publishers.Topics, &template.Topic{
Name: topic.Name,
AccountID: accountID,
Partition: partition.ID(),
Region: region,
App: app,
Env: env,
Svc: svc,
Name: topic.Name,
FIFOTopicConfig: fifoConfig,
AccountID: accountID,
Partition: partition.ID(),
Region: region,
App: app,
Env: env,
Svc: svc,
})
}

Expand Down
48 changes: 46 additions & 2 deletions internal/pkg/deploy/cloudformation/stack/transformers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1403,10 +1403,11 @@ func Test_convertPublish(t *testing.T) {
},
},
},
"valid publish with fifo and standard topics": {
"valid publish with fifo enabled and standard topics": {
inTopics: []manifest.Topic{
{
Name: aws.String("topic1"),
FIFO: manifest.FIFOTopicAdvanceConfigOrBool{Enable: aws.Bool(true)},
},
{
Name: aws.String("topic2"),
Expand All @@ -1415,7 +1416,50 @@ func Test_convertPublish(t *testing.T) {
wanted: &template.PublishOpts{
Topics: []*template.Topic{
{
Name: aws.String("topic1"),
Name: aws.String("topic1"),
FIFOTopicConfig: &template.FIFOTopicConfig{},
AccountID: accountId,
Partition: partition,
Region: region,
App: app,
Env: env,
Svc: svc,
},
{

Name: aws.String("topic2"),
FIFOTopicConfig: nil,
AccountID: accountId,
Partition: partition,
Region: region,
App: app,
Env: env,
Svc: svc,
},
},
},
},
"valid publish with advanced fifo and standard topics": {
inTopics: []manifest.Topic{
{
Name: aws.String("topic1"),
FIFO: manifest.FIFOTopicAdvanceConfigOrBool{
Advanced: manifest.FIFOTopicAdvanceConfig{
ContentBasedDeduplication: aws.Bool(true),
},
},
},
{
Name: aws.String("topic2"),
},
},
wanted: &template.PublishOpts{
Topics: []*template.Topic{
{
Name: aws.String("topic1"),
FIFOTopicConfig: &template.FIFOTopicConfig{
ContentBasedDeduplication: aws.Bool(true),
},
AccountID: accountId,
Partition: partition,
Region: region,
Expand Down
18 changes: 17 additions & 1 deletion internal/pkg/manifest/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,23 @@ func (p PublishConfig) validate() error {

// validate returns nil if Topic is configured correctly.
func (t Topic) validate() error {
return validatePubSubName(aws.StringValue(t.Name))
if err := validatePubSubName(aws.StringValue(t.Name)); err != nil {
return err
}
return t.FIFO.validate()
}

// validate returns nil if FIFOTopicAdvanceConfigOrBool is configured correctly.
func (f FIFOTopicAdvanceConfigOrBool) validate() error {
if f.IsEmpty() {
return nil
}
return f.Advanced.validate()
}

// validate returns nil if FIFOTopicAdvanceConfig is configured correctly.
func (a FIFOTopicAdvanceConfig) validate() error {
return nil
}

// validate returns nil if SubscribeConfig is configured correctly.
Expand Down
26 changes: 26 additions & 0 deletions internal/pkg/manifest/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2702,6 +2702,32 @@ func TestTopic_validate(t *testing.T) {
},
wanted: errors.New(`"name" can only contain letters, numbers, underscores, and hyphens`),
},
"should not return an error if name is valid": {
in: Topic{
Name: aws.String("validtopic"),
},
wanted: nil,
},
"should not return an error if name is valid with fifo enabled": {
in: Topic{
Name: aws.String("validtopic"),
FIFO: FIFOTopicAdvanceConfigOrBool{
Enable: aws.Bool(true),
},
},
wanted: nil,
},
"should not return an error if name is valid with advanced fifo config": {
in: Topic{
Name: aws.String("validtopic"),
FIFO: FIFOTopicAdvanceConfigOrBool{
Advanced: FIFOTopicAdvanceConfig{
ContentBasedDeduplication: aws.Bool(true),
},
},
},
wanted: nil,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
Expand Down
48 changes: 47 additions & 1 deletion internal/pkg/manifest/workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,53 @@ type PublishConfig struct {

// Topic represents the configurable options for setting up a SNS Topic.
type Topic struct {
Name *string `yaml:"name"`
Name *string `yaml:"name"`
FIFO FIFOTopicAdvanceConfigOrBool `yaml:"fifo"`
}

// FIFOTopicAdvanceConfigOrBool represents the configurable options for fifo topics.
type FIFOTopicAdvanceConfigOrBool struct {
Enable *bool
Advanced FIFOTopicAdvanceConfig
}

// IsEmpty returns true if the FifoAdvanceConfigOrBool struct has all nil values.
func (f *FIFOTopicAdvanceConfigOrBool) IsEmpty() bool {
return f.Enable == nil && f.Advanced.IsEmpty()
}

// IsEnabled returns true if the FIFO is enabled on the SQS queue.
func (f *FIFOTopicAdvanceConfigOrBool) IsEnabled() bool {
return aws.BoolValue(f.Enable) || !f.Advanced.IsEmpty()
}

// FIFOTopicAdvanceConfig represents the advanced fifo topic config.
type FIFOTopicAdvanceConfig struct {
ContentBasedDeduplication *bool `yaml:"content_based_deduplication"`
}

// IsEmpty returns true if the FifoAdvanceConfig struct has all nil values.
func (a *FIFOTopicAdvanceConfig) IsEmpty() bool {
return a.ContentBasedDeduplication == nil
}

// UnmarshalYAML overrides the default YAML unmarshaling logic for the FIFOTopicAdvanceConfigOrBool
// struct, allowing it to perform more complex unmarshaling behavior.
// This method implements the yaml.Unmarshaler (v3) interface.
func (t *FIFOTopicAdvanceConfigOrBool) UnmarshalYAML(value *yaml.Node) error {
if err := value.Decode(&t.Advanced); err != nil {
var yamlTypeErr *yaml.TypeError
if !errors.As(err, &yamlTypeErr) {
return err
}
}
if !t.Advanced.IsEmpty() {
return nil
}
if err := value.Decode(&t.Enable); err != nil {
return errUnmarshalFifoConfig
}
return nil
}

// NetworkConfig represents options for network connection to AWS resources within a VPC.
Expand Down
46 changes: 46 additions & 0 deletions internal/pkg/manifest/workload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,52 @@ topics:
},
},
},
"Valid publish yaml with fifo topic enabled": {
inContent: `
topics:
- name: tests
fifo: true
`,
wantedPublish: PublishConfig{
Topics: []Topic{
{
Name: aws.String("tests"),
FIFO: FIFOTopicAdvanceConfigOrBool{
Enable: aws.Bool(true),
},
},
},
},
},
"Valid publish yaml with advanced fifo topic": {
inContent: `
topics:
- name: tests
fifo:
content_based_deduplication: true
`,
wantedPublish: PublishConfig{
Topics: []Topic{
{
Name: aws.String("tests"),
FIFO: FIFOTopicAdvanceConfigOrBool{
Advanced: FIFOTopicAdvanceConfig{
ContentBasedDeduplication: aws.Bool(true),
},
},
},
},
},
},
"Invalid publish yaml with advanced fifo topic": {
inContent: `
topics:
- name: tests
fifo: apple
`,
wantedErr: errors.New(`unable to unmarshal "fifo" field into boolean or compose-style map`),
},

"Error when unmarshalable": {
inContent: `
topics: abc
Expand Down
Loading