packages feed

serverless-haskell 0.0.6 → 0.1.0

raw patch · 5 files changed

+183/−14 lines, 5 files

Files

serverless-haskell.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 8744fabb134bae654aeb0568028f9f99e96f2f7feeb7526d6c85b95685022f8e+-- hash: 9f8f42c39c47eb860db76ff109b447b37326ae914e1e88eaccbcb7f6734e00e8  name:           serverless-haskell-version:        0.0.6+version:        0.1.0 synopsis:       Deploying Haskell code onto AWS Lambda using Serverless description:    Utilities to help process the events from AWS Lambda when deployed with the serverless-haskell plugin. category:       AWS, Cloud, Network@@ -44,6 +44,7 @@   exposed-modules:       AWSLambda       AWSLambda.Events+      AWSLambda.Events.Embedded       AWSLambda.Events.KinesisEvent       AWSLambda.Events.Records       AWSLambda.Events.S3Event
src/AWSLambda/Events.hs view
@@ -10,41 +10,59 @@ import           AWSLambda.Events.S3Event import           AWSLambda.Events.SNSEvent +-- | Not yet implemented data DynamoDBEvent +-- | Not yet implemented data SESEvent +-- | Not yet implemented data CognitoEvent +-- | Not yet implemented data CloudFormationEvent +-- | Not yet implemented data CloudWatchLogsEvent +-- | Not yet implemented data CloudWatchEventsEvent +-- | Not yet implemented data CodeCommitEvent +-- | Not yet implemented data ConfigEvent +-- | Not yet implemented data AlexaEvent +-- | Not yet implemented data LexEvent +-- | Not yet implemented data APIGatewayEvent +-- | Not yet implemented data IoTButtonEvent +-- | Not yet implemented data CloudFrontEvent +-- | Not yet implemented data FirehoseEvent +-- | Not yet implemented data InvokeEvent -data LambdaEvent+-- | Sum type for all possible Lambda events.+-- Parameterised on the type of SNS Events to be handled.+-- See @SNSEvent@ for details.+data LambdaEvent snsMessage   = S3 !S3Event   | DynamoDB !DynamoDBEvent   | KinesisStream !KinesisEvent-  | SNS !SNSEvent+  | SNS !(SNSEvent snsMessage)   | SES !SESEvent   | Cognito !CognitoEvent   | CloudFormation !CloudFormationEvent@@ -61,7 +79,14 @@   | Invoke !InvokeEvent   | Custom !Value -instance FromJSON LambdaEvent where-  parseJSON v = S3 <$> parseJSON v <|> pure (Custom v)+-- | Attempt to parse the various event types.+-- Any valid JSON that can't be parsed as a specific+-- event type will result in a 'Custom' value.+instance FromJSON snsMessage =>+         FromJSON (LambdaEvent snsMessage) where+  parseJSON v =+    try S3 v <|> try KinesisStream v <|> try SNS v <|> pure (Custom v)+    where+      try f = fmap f . parseJSON  $(makePrisms ''LambdaEvent)
+ src/AWSLambda/Events/Embedded.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE TemplateHaskell   #-}++{-|+Module: AWSLambda.Events.Embedded+Description: Type for a JSON value embedded within a JSON string value+-}+module AWSLambda.Events.Embedded where++import           Control.Lens.TH+import           Data.Aeson+import Data.Text.Encoding        (encodeUtf8)++-- | Type for a JSON value embedded within a JSON string value+newtype Embedded a = Embedded { _unEmbed :: a } deriving (Eq, Show)++instance FromJSON a =>+         FromJSON (Embedded a) where+  parseJSON =+    withText "Embedded JSON" $+    fmap Embedded . either fail pure . eitherDecodeStrict . encodeUtf8++$(makeLenses ''Embedded)
src/AWSLambda/Events/SNSEvent.hs view
@@ -27,8 +27,8 @@ $(deriveFromJSON (aesonDrop 3 pascalCase) ''MessageAttribute) $(makeLenses ''MessageAttribute) -data SNSMessage = SNSMessage-  { _smMessage           :: !Text+data SNSMessage message = SNSMessage+  { _smMessage           :: !message   , _smMessageAttributes :: !(HashMap Text MessageAttribute)   , _smMessageId         :: !Text   , _smSignature         :: !Text@@ -44,14 +44,20 @@ $(deriveFromJSON (aesonDrop 3 pascalCase) ''SNSMessage) $(makeLenses ''SNSMessage) -data SNSRecord = SNSRecord+data SNSRecord message = SNSRecord   { _srEventVersion         :: !Text   , _srEventSubscriptionArn :: !Text   , _srEventSource          :: !Text-  , _srSns                  :: !SNSMessage+  , _srSns                  :: !(SNSMessage message)   } deriving (Eq, Show)  $(deriveFromJSON (aesonDrop 3 pascalCase) ''SNSRecord) $(makeLenses ''SNSRecord) -type SNSEvent = RecordsEvent SNSRecord+-- | SNSEvent.+-- The 'message' type is parameterised. To treat it as a text value+-- use @SNSEvent Text@.+-- To extract an embedded event object use the 'Embedded' type.+-- E.g. @SNSEvent (Embedded S3Event)@ will treat the message+-- as an embedded S3Event.+type SNSEvent message = RecordsEvent (SNSRecord message)
test/AWSLambda/Events/SNSEventSpec.hs view
@@ -3,14 +3,19 @@  module AWSLambda.Events.SNSEventSpec where +import           AWSLambda.Events.Embedded import           AWSLambda.Events.Records+import           AWSLambda.Events.S3Event import           AWSLambda.Events.SNSEvent  import           Data.Aeson import           Data.ByteString.Lazy      (ByteString) import qualified Data.HashMap.Strict       as HashMap+import           Data.Text                 (Text) import           Data.Time.Calendar import           Data.Time.Clock+import           Network.AWS.S3            as S3+import           Network.AWS.Types         as AWS  import           Text.RawString.QQ @@ -18,9 +23,11 @@  spec :: Spec spec =-  describe "SNSEvent" $-    it "parses sample event" $+  describe "SNSEvent" $ do+    it "parses sample text event" $       decode sampleSNSJSON `shouldBe` Just sampleSNSEvent+    it "parses sample embedded S3 event" $+      decode sampleSNSS3JSON `shouldBe` Just sampleSNSS3Event  sampleSNSJSON :: ByteString sampleSNSJSON = [r|@@ -57,7 +64,7 @@ } |] -sampleSNSEvent :: SNSEvent+sampleSNSEvent :: SNSEvent Text sampleSNSEvent =   RecordsEvent     [ SNSRecord@@ -92,3 +99,109 @@         }       }     ]++sampleSNSS3JSON :: ByteString+sampleSNSS3JSON = [r|+{"Records":+  [+    {"EventSource":"aws:sns",+      "EventVersion":"1.0",+      "EventSubscriptionArn":"arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent:23e2d254-e8bb-4db5-92ce-d917e5aad090",+      "Sns":{+        "Type":"Notification",+        "MessageId":"89f6fe8b-a751-5dcd-8e0c-afbd75420455",+        "TopicArn":"arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent",+        "Subject":"Amazon S3 Notification",+        "Message": "{\"Records\":[{\"eventVersion\":\"2.0\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"ap-southeast-2\",\"eventTime\":\"2017-03-06T02:56:19.713Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:DFLKSDFLKJ987SDFLJJDJ:some-principal-id\"},\"requestParameters\":{\"sourceIPAddress\":\"192.168.0.1\"},\"responseElements\":{\"x-amz-request-id\":\"324098EDFLK0894F\",\"x-amz-id-2\":\"xsdSDF/pgAl401Fz3UIATJ5/didfljDSFDSFsdfkjsdfl8JdsfLSDF89ldsf7SDF898jsdfljiA=\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SomeS3Event:Created\",\"bucket\":{\"name\":\"some-bucket\",\"ownerIdentity\":{\"principalId\":\"A3O1SDFLKJIJXU\"},\"arn\":\"arn:aws:s3:::some-bucket\"},\"object\":{\"key\":\"path/to/some/object\",\"size\":53598442,\"eTag\":\"6b1f72b9e81e4d6fcd3e0c808e8477f8\",\"sequencer\":\"0058BCCFD25C798E7B\"}}}]}",+        "Timestamp":"2017-03-06T02:56:19.834Z",+        "SignatureVersion":"1",+        "Signature":"aybEgnTjKzSbC2puHxho7SUnYOje4SjBoCyt0Q13bMWyp7M64+EU6jzi7P01+gSIuBFyYPsHreSmyqGMRSxbFuzn7rG5JcVGN0901U3CRXdk42eh03je8evRvs/Oa7TJlhpCTEDDOScalCWbIH0RthYONQpPR01nEgaNKj3e8YVJqyRQV+4RbU3YWJOj+Spyi4u1hOC9PLUv4BH7U80nbhbOe9EwgX0zpeNU1WBRbEpqPoACm+7/uB0w79qFBKjB/Q7OWc1kASUZV9q8bz03yceoQeVvza0QGhPsnSXi49sn1mLWQOFS4KvgbJIC/Qk7H036ShrDioP6pP+UEg6kow==",+        "SigningCertUrl":"https://sns.ap-southeast-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem",+        "UnsubscribeUrl":"https://sns.ap-southeast-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent:23e2d254-e8bb-4db5-92ce-d917e5aad090",+        "MessageAttributes":{}+      }+    }+  ]+}+|]++sampleSNSS3Event :: SNSEvent (Embedded S3Event)+sampleSNSS3Event =+  RecordsEvent+  { _reRecords =+    [ SNSRecord+      { _srEventVersion = "1.0"+      , _srEventSubscriptionArn =+        "arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent:23e2d254-e8bb-4db5-92ce-d917e5aad090"+      , _srEventSource = "aws:sns"+      , _srSns =+        SNSMessage+        { _smMessage =+          Embedded+          { _unEmbed =+            RecordsEvent+            { _reRecords =+              [ S3EventNotification+                { _senAwsRegion = Sydney+                , _senEventName = S3ObjectCreatedPut+                , _senEventSource = "aws:s3"+                , _senEventTime = UTCTime (fromGregorian 2017 3 6) (picosecondsToDiffTime 10579713000000000)+                , _senEventVersion = "2.0"+                , _senRequestParameters =+                  RequestParametersEntity+                  { _rpeSourceIPAddress = "192.168.0.1"+                  }+                , _senResponseElements =+                  ResponseElementsEntity+                  { _reeXAmzId2 =+                    "xsdSDF/pgAl401Fz3UIATJ5/didfljDSFDSFsdfkjsdfl8JdsfLSDF89ldsf7SDF898jsdfljiA="+                  , _reeXAmzRequestId = "324098EDFLK0894F"+                  }+                , _senS3 =+                  S3Entity+                  { _seBucket =+                    S3BucketEntity+                    { _sbeArn = "arn:aws:s3:::some-bucket"+                    , _sbeName = BucketName "some-bucket"+                    , _sbeOwnerIdentity =+                      UserIdentityEntity+                      { _uiePrincipalId = "A3O1SDFLKJIJXU"+                      }+                    }+                  , _seConfigurationId = "SomeS3Event:Created"+                  , _seObject =+                    S3ObjectEntity+                    { _soeETag = Just (ETag "6b1f72b9e81e4d6fcd3e0c808e8477f8")+                    , _soeKey = ObjectKey "path/to/some/object"+                    , _soeSize = Just 53598442+                    , _soeSequencer = "0058BCCFD25C798E7B"+                    , _soeVersionId = Nothing+                    }+                  , _seS3SchemaVersion = "1.0"+                  }+                , _senUserIdentity =+                  UserIdentityEntity+                  { _uiePrincipalId =+                    "AWS:DFLKSDFLKJ987SDFLJJDJ:some-principal-id"+                  }+                }+              ]+            }+          }+        , _smMessageAttributes = HashMap.fromList []+        , _smMessageId = "89f6fe8b-a751-5dcd-8e0c-afbd75420455"+        , _smSignature =+          "aybEgnTjKzSbC2puHxho7SUnYOje4SjBoCyt0Q13bMWyp7M64+EU6jzi7P01+gSIuBFyYPsHreSmyqGMRSxbFuzn7rG5JcVGN0901U3CRXdk42eh03je8evRvs/Oa7TJlhpCTEDDOScalCWbIH0RthYONQpPR01nEgaNKj3e8YVJqyRQV+4RbU3YWJOj+Spyi4u1hOC9PLUv4BH7U80nbhbOe9EwgX0zpeNU1WBRbEpqPoACm+7/uB0w79qFBKjB/Q7OWc1kASUZV9q8bz03yceoQeVvza0QGhPsnSXi49sn1mLWQOFS4KvgbJIC/Qk7H036ShrDioP6pP+UEg6kow=="+        , _smSignatureVersion = "1"+        , _smSigningCertUrl =+          "https://sns.ap-southeast-2.amazonaws.com/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem"+        , _smSubject = "Amazon S3 Notification"+        , _smTimestamp = UTCTime (fromGregorian 2017 3 6) (picosecondsToDiffTime 10579834000000000)+        , _smTopicArn = "arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent"+        , _smType = "Notification"+        , _smUnsubscribeUrl =+          "https://sns.ap-southeast-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-southeast-2:012345678901:SomeSNSEvent:23e2d254-e8bb-4db5-92ce-d917e5aad090"+        }+      }+    ]+  }