Help language development. Donate to The Perl Foundation
Description of an AWS Simple Notification Service message.
use Cro::HTTP::Router; use Cro::HTTP::Server; use AWS::SNS::Notification; my $app = route { post -> 'sns-message' { # The SNS message has a content-type of 'text/plain' so this will be raw JSON request-body -> $json { my $notification = AWS::SNS::Notification.from-json($json); # Check this is a valid notification if $notification.verify-signature { if $notification.is-notification { # Do something with the $notification.message # The format of which depends on the source - an S3 notification will be a JSON String for instance } else { # This is subscribe or unsubscribe confirmation request # so perform the confirmation $notification.respond; } } else { bad-request 'text/plain', 'Fake notification'; } } } }; my Cro::Service $service = Cro::HTTP::Server.new(:host<127.0.0.1>, :port<7798>, application => $app); $service.start; react { whenever signal(SIGINT) { $service.stop; exit; } }
Alternatively you can derive a body parser using Cro::HTTP::BodyParser::JSONClass :
use Cro::HTTP::Router; use Cro::HTTP::Server; use AWS::SNS::Notification; use Cro::HTTP::BodyParser::JSONClass; class SNSBodyParser does Cro::HTTP::BodyParser::JSONClass[AWS::SNS::Notification] { use Cro::HTTP::Message; method is-applicable(Cro::HTTP::Message $message --> Bool ) { $message.header('x-amz-sns-message-type').defined && $message.header('x-amz-sns-message-id').defined; } } my $app = route { body-parser SNSBodyParser; post -> 'sns-message' { request-body -> $notification { # Check this is a valid notification if $notification.verify-signature { if $notification.is-notification { # Do something with the $notification.message # The format of which depends on the source - an S3 notification will be a JSON String for instance } else { # This is subscribe or unsubscribe confirmation request # so perform the confirmation $notification.respond; } } else { bad-request 'text/plain', 'Fake notification'; } } } }; my Cro::Service $service = Cro::HTTP::Server.new(:host<127.0.0.1>, :port<7798>, application => $app); $service.start; react { whenever signal(SIGINT) { $service.stop; exit; } }
This class describes an AWS Simple Notification Service message that may be delivered by HTTPS or by a message queue or somesuch.
The class provides for parsing the JSON payload for the message, verifying the signature of the message against the signing key and responding if necessary to a Subscribe or Unsubscribe confirmation.
The actual message sent by the source application is accessed through the .message
accessor - so for instance in the case of an S3 notification this will be a JSON string which will need to be decoded for further processing.
Assuming you have a working rakudo installation you can install this with zef :
zef install AWS::SNS::Notification
Or from a local clone of the distribution
zef install AWS::SNS::Notification
If you have an feedback/suggestions/patches please send them via Github
This library is free software. Please see the LICENCE file in the distribution for details.
© Jonathan Stowe 2021