Entregando mensagens em formato ‘raw’ com AWS SNS

AWS User Group São Paulo
awsugsp
Published in
3 min readAug 20, 2017

Atualmente tenho trabalhado bastante com sistemas distribuídos e a dupla AWS SNS /SQS aparece em muitos deles. A finalidade óbvia é desacoplar diferentes serviços e jogar ‘nas costas’ da AWS parte da escalabilidade/confiabilidade. As mensagens que são trocadas entre os serviços são as mais diversas possíveis, como se pode imaginar, e algumas vezes o tamanho do que é transmitido (payload) importa muito. Neste artigo vou mostrar uma opção que tenho usado para tornar menores as mensagens entregues pelo SNS.

Sobre o que se trata este artigo? Trata-se de explorar sobre uma propriedade específica de assinatura de um tópico SNS.

IMPORTANTE: Os exemplos que vou mostrar daqui para frente utilizam a stack do AWS CloudFormation abaixo. Ela cria um tópico SNS, uma fila SQS e uma fila para DLQ.

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Stack para brincar com SNS, SQS'
Resources:
SampleDLQ:
Type: AWS::SQS::Queue
Properties:
DelaySeconds: '0'
VisibilityTimeout: '10'
MessageRetentionPeriod: '1209600'
SampleQueue:
Type: AWS::SQS::Queue
Properties:
DelaySeconds: '0'
VisibilityTimeout: '5'
RedrivePolicy:
deadLetterTargetArn: !GetAtt [SampleDLQ, Arn]
maxReceiveCount: '3'
SampleSNSTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !GetAtt [SampleQueue, Arn]
Protocol: sqs
SampleQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Id: SampleQueuePolicy
Statement:
- Sid: Allow-SendMessage-To-SampleQueue-From-SNS-Topic
Effect: Allow
Principal: '*'
Action:
- sqs:SendMessage
Resource: '*'
Condition:
ArnEquals:
aws:SourceArn: !Ref 'SampleSNSTopic'
Queues:
- !Ref 'SampleQueue'

Usar SNS/SQS normalmente implica em ter produtores e consumidores de dados. No exemplo deste artigo o produtor (uma aplicação console simples) publica a seguinte mensagem no tópico SNS:

{
"Prop1":"Value for property 1",
"Prop2":false,
"Prop3":1000
}

Considerando a stack criada, a notificação da fila SQS vai gerar a mensagem a ser consumida conforme mostra o trecho abaixo.

{
"Type" : "Notification",
"MessageId" : "400eb8e3-f4de-5fdd-b3a8-eaf01ccdafc5",
"TopicArn" : "arn:aws:sns:us-east-1:821038529621:SetSubscriptionAttrSamples-SampleSNSTopic-1DDY6BVXEJAHF",
"Message" : "{\"Prop1\":\"Value for property 1\",\"Prop2\":false,\"Prop3\":1000}",
"Timestamp" : "2017-08-20T19:41:07.849Z",
"SignatureVersion" : "1",
"Signature" : "iHDQO8T0JvX4BeBDscxWSRJw9Le026r3AvAjVZqUg2QZM4oVHZSX88dEXVO+dq5bQeFqjJkuAhRXw0k1D87blq/25cNkA6n4PBM8WcDC25KYhwOgRZOcRKiGZhF3tqSIXt6HnhPGD1jDYoSZlVagXhyRaTWcTLgFkGuM0cNhYt+VnNRYaIPqiN82dQx7JlR7+DGak6XXMn5WDgTvfxsxeEtvGAuWy9pIN2Vfn8j2qnguphcMpdu8ekjH/RtXeU3/iC6H/G74GOj3zueBL/BqQZ7pZpp8HdcYjT8Se3VFEsXECFNGPMLzVWLg40OTaJP1J9MhkOXPRALff0jyKakViA==",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-433026a4050d206028891664da859041.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:821038529621:SetSubscriptionAttrSamples-SampleSNSTopic-1DDY6BVXEJAHF:d8aef064-ddcb-4794-83a4-df155576c3f1"
}

Note que além da mensagem recebida (deixei em negrito no código), temos uma série de informações úteis. O id da mensagem, data e hora e assim por diante. O tamanho total desta mensagem na fila SQS é 1KB.

É possível configurar uma determinada assinatura do SNS para que a mensagem seja entregue em modo raw. Para tanto, nos detalhes do tópico SNS na assinatura específica, escolha ‘Edit subscription attributes’ e marque a opção Raw message delivery.

indicando que a mensagem deve ser entregue à fila SQS em formato raw

Com a assinatura configurada desta forma, temos que a mensagem entregue terá 59 bytes e o aspecto abaixo.

Mensagem na fila SQS em formato raw

Para fazer a mesma configuração via AWS CLI, basta saber o arn da assinatura SNS que você deseja configurar.

aws sns set-subscription-attributes --attribute-name RawMessageDelivery --attribute-value true --subscription-arn arn-assinatura-vai-aqui

O ideal seria conseguir fazer esta configuração via CloudFormation, não é verdade? Bem, eu ainda não encontrei uma forma de fazer isso. Caso você tenha esbarrado nisso e saiba como saber, dê um toque aí nos comentários. Vai ser muito bem vindo. :) Vi umas soluções utilizando ‘custom resources’, mas pelo menos em princípio me parece bem estranho. Não se trata de um recurso customizado…

Fontes utilizados neste artigo

Originally published at medium.com by Marcelo Palladino.

--

--

AWS User Group São Paulo
awsugsp

Comunidade para discussões, palestras e networking de Tecnologias AWS no Brasil e no mundo.