├── .gitignore ├── Gopkg.toml ├── vendor └── github.com │ └── aws │ └── aws-lambda-go │ ├── LICENSE-SUMMARY │ ├── events │ ├── cloudwatch_events.go │ ├── autoscaling.go │ ├── kinesis.go │ ├── sns.go │ ├── config.go │ ├── sqs.go │ ├── firehose.go │ ├── s3.go │ ├── cloudwatch_logs.go │ ├── epoch_time.go │ ├── ses.go │ ├── lex.go │ ├── codepipeline_job.go │ ├── cognito.go │ ├── code_commit.go │ ├── dynamodb.go │ ├── apigw.go │ └── attributevalue.go │ ├── LICENSE-LAMBDACODE │ ├── lambda │ ├── messages │ │ └── messages.go │ ├── entry.go │ ├── function.go │ ├── panic.go │ └── handler.go │ ├── lambdacontext │ └── context.go │ └── LICENSE ├── worker └── main.go ├── Gopkg.lock ├── serverless.yml ├── README.md └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | /.serverless/ 2 | /bin/ 3 | /node_modules/ 4 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | [[constraint]] 2 | name = "github.com/aws/aws-lambda-go" 3 | branch = "master" 4 | 5 | [prune] 6 | go-tests = true 7 | unused-packages = true 8 | non-go = true 9 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/LICENSE-SUMMARY: -------------------------------------------------------------------------------- 1 | Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Lambda functions are made available under a modified MIT license. 4 | See LICENSE-LAMBDACODE for details. 5 | 6 | The remainder of the project is made available under the terms of the 7 | Apache License, version 2.0. See LICENSE for details. 8 | -------------------------------------------------------------------------------- /worker/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/aws/aws-lambda-go/events" 9 | "github.com/aws/aws-lambda-go/lambda" 10 | ) 11 | 12 | func main() { 13 | lambda.Start(handler) 14 | } 15 | 16 | func handler(ctx context.Context, sqsEvent events.SQSEvent) error { 17 | if len(sqsEvent.Records) == 0 { 18 | return errors.New("No SQS message passed to function") 19 | } 20 | 21 | for _, msg := range sqsEvent.Records { 22 | fmt.Printf("Got SQS message %q with body %q\n", msg.MessageId, msg.Body) 23 | } 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | branch = "master" 6 | name = "github.com/aws/aws-lambda-go" 7 | packages = [ 8 | "events", 9 | "lambda", 10 | "lambda/messages", 11 | "lambdacontext" 12 | ] 13 | revision = "3574a030467ca312f135e64a4a1bf293a216febd" 14 | 15 | [solve-meta] 16 | analyzer-name = "dep" 17 | analyzer-version = 1 18 | inputs-digest = "c9eacef813550a26b5fbace219e45cf19192c793b8a869e667e78c3ba76bbcee" 19 | solver-name = "gps-cdcl" 20 | solver-version = 1 21 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | --- 2 | frameworkVersion: ">=1.28.0 <2.0.0" 3 | 4 | service: lambda-sqs-example 5 | 6 | provider: 7 | name: aws 8 | runtime: go1.x 9 | stage: ${opt:stage, 'staging'} 10 | region: ${env:AWS_REGION} 11 | 12 | package: 13 | exclude: 14 | - ./** 15 | include: 16 | - ./bin/** 17 | 18 | functions: 19 | worker: 20 | handler: bin/worker 21 | timeout: 25 22 | reservedConcurrency: 10 23 | events: 24 | - sqs: 25 | arn: 26 | Fn::GetAtt: 27 | - SQSQueue 28 | - Arn 29 | batchSize: 1 30 | 31 | resources: 32 | Resources: 33 | SQSQueue: 34 | Type: AWS::SQS::Queue 35 | Properties: 36 | QueueName: ${self:service}-${self:provider.stage} 37 | VisibilityTimeout: 30 38 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/cloudwatch_events.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "time" 6 | ) 7 | 8 | // CloudWatchEvent is the outer structure of an event sent via CloudWatch Events. 9 | // For examples of events that come via CloudWatch Events, see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html 10 | type CloudWatchEvent struct { 11 | Version string `json:"version"` 12 | ID string `json:"id"` 13 | DetailType string `json:"detail-type"` 14 | Source string `json:"source"` 15 | AccountID string `json:"account"` 16 | Time time.Time `json:"time"` 17 | Region string `json:"region"` 18 | Resources []string `json:"resources"` 19 | Detail json.RawMessage `json:"detail"` 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/autoscaling.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // AutoScalingEvent struct is used to parse the json for auto scaling event types // 8 | type AutoScalingEvent struct { 9 | Version string `json:"version"` // The version of event data 10 | ID string `json:"id"` // The unique ID of the event 11 | DetailType string `json:"detail-type"` //Details about event type 12 | Source string `json:"source"` //Source of the event 13 | AccountID string `json:"account"` //AccountId 14 | Time time.Time `json:"time"` //Event timestamp 15 | Region string `json:"region"` //Region of event 16 | Resources []string `json:"resources"` //Information about resources impacted by event 17 | Detail map[string]interface{} `json:"detail"` 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/LICENSE-LAMBDACODE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | software and associated documentation files (the "Software"), to deal in the Software 5 | without restriction, including without limitation the rights to use, copy, modify, 6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 10 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 11 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 12 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 13 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lambda SQS Example using Serverless Framework and Go 2 | 3 | As of June 2018, it's possible to use Amazon SQS to trigger AWS Lambda functions. 4 | 5 | This sample project demonstrates how to use this feature with the Serverless Framework and Go. 6 | 7 | ## Usage 8 | 9 | ```console 10 | make deploy 11 | 12 | echo '{"Records":[{"messageID":"1","body":"Hello"},{"messageID":"2","body":"World"}]}' | sls invoke -f worker 13 | 14 | sls logs -f worker 15 | ``` 16 | 17 | Which should output something like this: 18 | 19 | ``` 20 | START RequestId: bdf5c92f-8a6d-11e8-ad3a-f1cb42f29439 Version: $LATEST 21 | Got SQS message "1" with body "Hello" 22 | Got SQS message "2" with body "World" 23 | END RequestId: bdf5c92f-8a6d-11e8-ad3a-f1cb42f29439 24 | ``` 25 | 26 | ## Resources 27 | 28 | - https://aws.amazon.com/blogs/aws/aws-lambda-adds-amazon-simple-queue-service-to-supported-event-sources/ 29 | - https://github.com/aws/aws-lambda-go/commit/02a038f1708ade8d5fd6a28ee309c388008fe770 30 | - https://serverless.com/blog/aws-lambda-sqs-serverless-integration/ 31 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambda/messages/messages.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package messages 4 | 5 | type PingRequest struct { 6 | } 7 | 8 | type PingResponse struct { 9 | } 10 | 11 | type InvokeRequest_Timestamp struct { 12 | Seconds int64 13 | Nanos int64 14 | } 15 | 16 | type InvokeRequest struct { 17 | Payload []byte 18 | RequestId string 19 | XAmznTraceId string 20 | Deadline InvokeRequest_Timestamp 21 | InvokedFunctionArn string 22 | CognitoIdentityId string 23 | CognitoIdentityPoolId string 24 | ClientContext []byte 25 | } 26 | 27 | type InvokeResponse struct { 28 | Payload []byte 29 | Error *InvokeResponse_Error 30 | } 31 | 32 | type InvokeResponse_Error struct { 33 | Message string 34 | Type string 35 | StackTrace []*InvokeResponse_Error_StackFrame 36 | ShouldExit bool 37 | } 38 | 39 | type InvokeResponse_Error_StackFrame struct { 40 | Path string `json:"path"` 41 | Line int32 `json:"line"` 42 | Label string `json:"label"` 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/kinesis.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | type KinesisEvent struct { 6 | Records []KinesisEventRecord `json:"Records"` 7 | } 8 | 9 | type KinesisEventRecord struct { 10 | AwsRegion string `json:"awsRegion"` 11 | EventID string `json:"eventID"` 12 | EventName string `json:"eventName"` 13 | EventSource string `json:"eventSource"` 14 | EventSourceArn string `json:"eventSourceARN"` 15 | EventVersion string `json:"eventVersion"` 16 | InvokeIdentityArn string `json:"invokeIdentityArn"` 17 | Kinesis KinesisRecord `json:"kinesis"` 18 | } 19 | 20 | type KinesisRecord struct { 21 | ApproximateArrivalTimestamp SecondsEpochTime `json:"approximateArrivalTimestamp"` 22 | Data []byte `json:"data"` 23 | EncryptionType string `json:"encryptionType,omitempty"` 24 | PartitionKey string `json:"partitionKey"` 25 | SequenceNumber string `json:"sequenceNumber"` 26 | KinesisSchemaVersion string `json:"kinesisSchemaVersion"` 27 | } 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ENV = staging 2 | FUNCS = $(subst /,,$(dir $(wildcard */main.go))) 3 | SERVICE = $(shell awk '/^service:/ {print $$2}' serverless.yml) 4 | 5 | staging: ENV=staging 6 | staging: deploy 7 | 8 | production: ENV=production 9 | production: deploy 10 | 11 | deploy: test build 12 | serverless deploy --stage $(ENV) --verbose 13 | 14 | deploy_funcs = $(FUNCS:%=deploy-%) 15 | 16 | $(deploy_funcs): deploy-%: test-% build-% 17 | serverless deploy function --function $(@:deploy-%=%) --stage $(ENV) --verbose 18 | 19 | destroy: 20 | serverless remove --stage $(ENV) --verbose 21 | 22 | logs_funcs = $(FUNCS:%=logs-%) 23 | 24 | $(logs_funcs): 25 | serverless logs --function $(@:logs-%=%) --stage $(ENV) --tail --no-color 26 | 27 | url: 28 | @aws cloudformation describe-stacks --stack-name $(SERVICE)-$(ENV) \ 29 | --query "Stacks[0].Outputs[?OutputKey == 'ServiceEndpoint'].OutputValue" \ 30 | --output text 31 | 32 | build_funcs = $(FUNCS:%=build-%) 33 | 34 | build: $(build_funcs) 35 | 36 | $(build_funcs): 37 | GOOS=linux GOARCH=amd64 go build -o bin/$(@:build-%=%) ./$(@:build-%=%) 38 | 39 | test: 40 | go vet ./... 41 | go test -v -cover ./... 42 | 43 | test_funcs = $(FUNCS:%=test-%) 44 | 45 | $(test_funcs): 46 | go vet ./$(@:test-%=%) 47 | go test -v -cover ./$(@:test-%=%) 48 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/sns.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | type SNSEvent struct { 10 | Records []SNSEventRecord `json:"Records"` 11 | } 12 | 13 | type SNSEventRecord struct { 14 | EventVersion string `json:"EventVersion"` 15 | EventSubscriptionArn string `json:"EventSubscriptionArn"` 16 | EventSource string `json:"EventSource"` 17 | SNS SNSEntity `json:"Sns"` 18 | } 19 | 20 | type SNSEntity struct { 21 | Signature string `json:"Signature"` 22 | MessageID string `json:"MessageId"` 23 | Type string `json:"Type"` 24 | TopicArn string `json:"TopicArn"` 25 | MessageAttributes map[string]interface{} `json:"MessageAttributes"` 26 | SignatureVersion string `json:"SignatureVersion"` 27 | Timestamp time.Time `json:"Timestamp"` 28 | SigningCertURL string `json:"SigningCertUrl"` 29 | Message string `json:"Message"` 30 | UnsubscribeURL string `json:"UnsubscribeUrl"` 31 | Subject string `json:"Subject"` 32 | } 33 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/config.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // ConfigEvent contains data from an event sent from AWS Config 6 | type ConfigEvent struct { 7 | AccountID string `json:"accountId"` // The ID of the AWS account that owns the rule 8 | ConfigRuleArn string `json:"configRuleArn"` // The ARN that AWS Config assigned to the rule 9 | ConfigRuleID string `json:"configRuleId"` 10 | ConfigRuleName string `json:"configRuleName"` // The name that you assigned to the rule that caused AWS Config to publish the event 11 | EventLeftScope bool `json:"eventLeftScope"` // A boolean value that indicates whether the AWS resource to be evaluated has been removed from the rule's scope 12 | ExecutionRoleArn string `json:"executionRoleArn"` 13 | InvokingEvent string `json:"invokingEvent"` // If the event is published in response to a resource configuration change, this value contains a JSON configuration item 14 | ResultToken string `json:"resultToken"` // A token that the function must pass to AWS Config with the PutEvaluations call 15 | RuleParameters string `json:"ruleParameters"` // Key/value pairs that the function processes as part of its evaluation logic 16 | Version string `json:"version"` 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/sqs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | type SQSEvent struct { 6 | Records []SQSMessage `json:"Records"` 7 | } 8 | 9 | type SQSMessage struct { 10 | MessageId string `json:"messageId"` 11 | ReceiptHandle string `json:"receiptHandle"` 12 | Body string `json:"body"` 13 | Md5OfBody string `json:"md5OfBody"` 14 | Md5OfMessageAttributes string `json:"md5OfMessageAttributes"` 15 | Attributes map[string]string `json:"attributes"` 16 | MessageAttributes map[string]SQSMessageAttribute `json:"messageAttributes"` 17 | EventSourceARN string `json:"eventSourceARN"` 18 | EventSource string `json:"eventSource"` 19 | AWSRegion string `json:"awsRegion"` 20 | } 21 | 22 | type SQSMessageAttribute struct { 23 | StringValue *string `json:"stringValue,omitempty"` 24 | BinaryValue []byte `json:"binaryValue,omitempty"` 25 | StringListValues []string `json:"stringListValues"` 26 | BinaryListValues [][]byte `json:"binaryListValues"` 27 | DataType string `json:"dataType"` 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/firehose.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // KinesisFirehoseEvent represents the input event from Amazon Kinesis Firehose. It is used as the input parameter. 6 | type KinesisFirehoseEvent struct { 7 | InvocationID string `json:"invocationId"` 8 | DeliveryStreamArn string `json:"deliveryStreamArn"` 9 | Region string `json:"region"` 10 | Records []KinesisFirehoseEventRecord `json:"records"` 11 | } 12 | 13 | type KinesisFirehoseEventRecord struct { 14 | RecordID string `json:"recordId"` 15 | ApproximateArrivalTimestamp MilliSecondsEpochTime `json:"approximateArrivalTimestamp"` 16 | Data []byte `json:"data"` 17 | } 18 | 19 | // Constants used for describing the transformation result 20 | const ( 21 | KinesisFirehoseTransformedStateOk = "Ok" 22 | KinesisFirehoseTransformedStateDropped = "Dropped" 23 | KinesisFirehoseTransformedStateProcessingFailed = "ProcessingFailed" 24 | ) 25 | 26 | type KinesisFirehoseResponse struct { 27 | Records []KinesisFirehoseResponseRecord `json:"records"` 28 | } 29 | 30 | type KinesisFirehoseResponseRecord struct { 31 | RecordID string `json:"recordId"` 32 | Result string `json:"result"` // The status of the transformation. May be TransformedStateOk, TransformedStateDropped or TransformedStateProcessingFailed 33 | Data []byte `json:"data"` 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/s3.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | type S3Event struct { 10 | Records []S3EventRecord `json:"Records"` 11 | } 12 | 13 | type S3EventRecord struct { 14 | EventVersion string `json:"eventVersion"` 15 | EventSource string `json:"eventSource"` 16 | AWSRegion string `json:"awsRegion"` 17 | EventTime time.Time `json:"eventTime"` 18 | EventName string `json:"eventName"` 19 | PrincipalID S3UserIdentity `json:"userIdentity"` 20 | RequestParameters S3RequestParameters `json:"requestParameters"` 21 | ResponseElements map[string]string `json:"responseElements"` 22 | S3 S3Entity `json:"s3"` 23 | } 24 | 25 | type S3UserIdentity struct { 26 | PrincipalID string `json:"principalId"` 27 | } 28 | 29 | type S3RequestParameters struct { 30 | SourceIPAddress string `json:"sourceIPAddress"` 31 | } 32 | 33 | type S3Entity struct { 34 | SchemaVersion string `json:"s3SchemaVersion"` 35 | ConfigurationID string `json:"configurationId"` 36 | Bucket S3Bucket `json:"bucket"` 37 | Object S3Object `json:"object"` 38 | } 39 | 40 | type S3Bucket struct { 41 | Name string `json:"name"` 42 | OwnerIdentity S3UserIdentity `json:"ownerIdentity"` 43 | Arn string `json:"arn"` 44 | } 45 | 46 | type S3Object struct { 47 | Key string `json:"key"` 48 | Size int64 `json:"size"` 49 | URLDecodedKey string `json:"urlDecodedKey"` 50 | VersionID string `json:"versionId"` 51 | ETag string `json:"eTag"` 52 | Sequencer string `json:"sequencer"` 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/cloudwatch_logs.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "encoding/base64" 7 | "encoding/json" 8 | ) 9 | 10 | // CloudwatchLogsEvent represents raw data from a cloudwatch logs event 11 | type CloudwatchLogsEvent struct { 12 | AWSLogs CloudwatchLogsRawData `json:"awslogs"` 13 | } 14 | 15 | // CloudwatchLogsRawData contains gzipped base64 json representing the bulk 16 | // of a cloudwatch logs event 17 | type CloudwatchLogsRawData struct { 18 | Data string `json:"data"` 19 | } 20 | 21 | // Parse returns a struct representing a usable CloudwatchLogs event 22 | func (c CloudwatchLogsRawData) Parse() (d CloudwatchLogsData, err error) { 23 | data, err := base64.StdEncoding.DecodeString(c.Data) 24 | if err != nil { 25 | return 26 | } 27 | 28 | zr, err := gzip.NewReader(bytes.NewBuffer(data)) 29 | if err != nil { 30 | return 31 | } 32 | 33 | buf := &bytes.Buffer{} 34 | buf.ReadFrom(zr) 35 | 36 | err = json.Unmarshal(buf.Bytes(), &d) 37 | return 38 | } 39 | 40 | // CloudwatchLogsData is an unmarshal'd, ungzip'd, cloudwatch logs event 41 | type CloudwatchLogsData struct { 42 | Owner string `json:"owner"` 43 | LogGroup string `json:"logGroup"` 44 | LogStream string `json:"logStream"` 45 | SubscriptionFilters []string `json:"subscriptionFilters"` 46 | MessageType string `json:"messageType"` 47 | LogEvents []CloudwatchLogsLogEvent `json:"logEvents"` 48 | } 49 | 50 | // LogEvent represents a log entry from cloudwatch logs 51 | type CloudwatchLogsLogEvent struct { 52 | ID string `json:"id"` 53 | Timestamp int64 `json:"timestamp"` 54 | Message string `json:"message"` 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/epoch_time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "encoding/json" 7 | "time" 8 | ) 9 | 10 | // SecondsEpochTime serializes a time.Time in JSON as a UNIX epoch time in seconds 11 | type SecondsEpochTime struct { 12 | time.Time 13 | } 14 | 15 | // MilliSecondsEpochTime serializes a time.Time in JSON as a UNIX epoch time in milliseconds. 16 | type MilliSecondsEpochTime struct { 17 | time.Time 18 | } 19 | 20 | const secondsToNanoSecondsFactor = 1000000000 21 | const milliSecondsToNanoSecondsFactor = 1000000 22 | 23 | func (e SecondsEpochTime) MarshalJSON() ([]byte, error) { 24 | // UnixNano() returns the epoch in nanoseconds 25 | unixTime := float64(e.UnixNano()) / float64(secondsToNanoSecondsFactor) 26 | return json.Marshal(unixTime) 27 | } 28 | 29 | func (e *SecondsEpochTime) UnmarshalJSON(b []byte) error { 30 | var epoch float64 31 | err := json.Unmarshal(b, &epoch) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | epochSec := int64(epoch) 37 | epochNano := int64((epoch - float64(epochSec)) * float64(secondsToNanoSecondsFactor)) 38 | 39 | // time.Unix(sec, nsec) expects the epoch integral seconds in the first parameter 40 | // and remaining nanoseconds in the second parameter 41 | *e = SecondsEpochTime{time.Unix(epochSec, epochNano)} 42 | return nil 43 | } 44 | 45 | func (e MilliSecondsEpochTime) MarshalJSON() ([]byte, error) { 46 | // UnixNano() returns the epoch in nanoseconds 47 | unixTimeMs := e.UnixNano() / milliSecondsToNanoSecondsFactor 48 | return json.Marshal(unixTimeMs) 49 | } 50 | 51 | func (e *MilliSecondsEpochTime) UnmarshalJSON(b []byte) error { 52 | var epoch int64 53 | err := json.Unmarshal(b, &epoch) 54 | if err != nil { 55 | return err 56 | } 57 | *e = MilliSecondsEpochTime{time.Unix(epoch/1000, (epoch%1000)*1000000)} 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambda/entry.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package lambda 4 | 5 | import ( 6 | "log" 7 | "net" 8 | "net/rpc" 9 | "os" 10 | ) 11 | 12 | // Start takes a handler and talks to an internal Lambda endpoint to pass requests to the handler. If the 13 | // handler does not match one of the supported types an appropriate error message will be returned to the caller. 14 | // Start blocks, and does not return after being called. 15 | // 16 | // Rules: 17 | // 18 | // * handler must be a function 19 | // * handler may take between 0 and two arguments. 20 | // * if there are two arguments, the first argument must satisfy the "context.Context" interface. 21 | // * handler may return between 0 and two arguments. 22 | // * if there are two return values, the second argument must be an error. 23 | // * if there is one return value it must be an error. 24 | // 25 | // Valid function signatures: 26 | // 27 | // func () 28 | // func () error 29 | // func (TIn) error 30 | // func () (TOut, error) 31 | // func (TIn) (TOut, error) 32 | // func (context.Context) error 33 | // func (context.Context, TIn) error 34 | // func (context.Context) (TOut, error) 35 | // func (context.Context, TIn) (TOut, error) 36 | // 37 | // Where "TIn" and "TOut" are types compatible with the "encoding/json" standard library. 38 | // See https://golang.org/pkg/encoding/json/#Unmarshal for how deserialization behaves 39 | func Start(handler interface{}) { 40 | wrappedHandler := newHandler(handler) 41 | StartHandler(wrappedHandler) 42 | } 43 | 44 | // StartHandler takes in a Handler wrapper interface which can be implemented either by a 45 | // custom function or a struct. 46 | // 47 | // Handler implementation requires a single "Invoke()" function: 48 | // 49 | // func Invoke(context.Context, []byte) ([]byte, error) 50 | func StartHandler(handler Handler) { 51 | port := os.Getenv("_LAMBDA_SERVER_PORT") 52 | lis, err := net.Listen("tcp", "localhost:"+port) 53 | if err != nil { 54 | log.Fatal(err) 55 | } 56 | function := new(Function) 57 | function.handler = handler 58 | err = rpc.Register(function) 59 | if err != nil { 60 | log.Fatal("failed to register handler function") 61 | } 62 | rpc.Accept(lis) 63 | log.Fatal("accept should not have returned") 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/ses.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import "time" 4 | 5 | // SimpleEmailEvent is the outer structure of an event sent via SES. 6 | type SimpleEmailEvent struct { 7 | Records []SimpleEmailRecord `json:"Records"` 8 | } 9 | 10 | type SimpleEmailRecord struct { 11 | EventVersion string `json:"eventVersion"` 12 | EventSource string `json:"eventSource"` 13 | SES SimpleEmailService `json:"ses"` 14 | } 15 | 16 | type SimpleEmailService struct { 17 | Mail SimpleEmailMessage `json:"mail"` 18 | Receipt SimpleEmailReceipt `json:"receipt"` 19 | } 20 | 21 | type SimpleEmailMessage struct { 22 | CommonHeaders SimpleEmailCommonHeaders `json:"commonHeaders"` 23 | Source string `json:"source"` 24 | Timestamp time.Time `json:"timestamp"` 25 | Destination []string `json:"destination"` 26 | Headers []SimpleEmailHeader `json:"headers"` 27 | HeadersTruncated bool `json:"headersTruncated"` 28 | MessageID string `json:"messageId"` 29 | } 30 | 31 | type SimpleEmailReceipt struct { 32 | Recipients []string `json:"recipients"` 33 | Timestamp time.Time `json:"timestamp"` 34 | SpamVerdict SimpleEmailVerdict `json:"spamVerdict"` 35 | DKIMVerdict SimpleEmailVerdict `json:"dkimVerdict"` 36 | SPFVerdict SimpleEmailVerdict `json:"spfVerdict"` 37 | VirusVerdict SimpleEmailVerdict `json:"virusVerdict"` 38 | Action SimpleEmailReceiptAction `json:"action"` 39 | ProcessingTimeMillis int64 `json:"processingTimeMillis"` 40 | } 41 | 42 | type SimpleEmailHeader struct { 43 | Name string `json:"name"` 44 | Value string `json:"value"` 45 | } 46 | 47 | type SimpleEmailCommonHeaders struct { 48 | From []string `json:"from"` 49 | To []string `json:"to"` 50 | ReturnPath string `json:"returnPath"` 51 | MessageID string `json:"messageId"` 52 | Date string `json:"date"` 53 | Subject string `json:"subject"` 54 | } 55 | 56 | type SimpleEmailReceiptAction struct { 57 | Type string `json:"type"` 58 | InvocationType string `json:"invocationType"` 59 | FunctionArn string `json:"functionArn"` 60 | } 61 | 62 | type SimpleEmailVerdict struct { 63 | Status string `json:"status"` 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambda/function.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package lambda 4 | 5 | import ( 6 | "context" 7 | "encoding/json" 8 | "reflect" 9 | "time" 10 | 11 | "github.com/aws/aws-lambda-go/lambda/messages" 12 | "github.com/aws/aws-lambda-go/lambdacontext" 13 | ) 14 | 15 | type Function struct { 16 | handler Handler 17 | } 18 | 19 | func (fn *Function) Ping(req *messages.PingRequest, response *messages.PingResponse) error { 20 | *response = messages.PingResponse{} 21 | return nil 22 | } 23 | 24 | func (fn *Function) Invoke(req *messages.InvokeRequest, response *messages.InvokeResponse) error { 25 | defer func() { 26 | if err := recover(); err != nil { 27 | panicInfo := getPanicInfo(err) 28 | response.Error = &messages.InvokeResponse_Error{ 29 | Message: panicInfo.Message, 30 | Type: getErrorType(err), 31 | StackTrace: panicInfo.StackTrace, 32 | ShouldExit: true, 33 | } 34 | } 35 | }() 36 | 37 | deadline := time.Unix(req.Deadline.Seconds, req.Deadline.Nanos).UTC() 38 | invokeContext, cancel := context.WithDeadline(context.Background(), deadline) 39 | defer cancel() 40 | 41 | lc := &lambdacontext.LambdaContext{ 42 | AwsRequestID: req.RequestId, 43 | InvokedFunctionArn: req.InvokedFunctionArn, 44 | Identity: lambdacontext.CognitoIdentity{ 45 | CognitoIdentityID: req.CognitoIdentityId, 46 | CognitoIdentityPoolID: req.CognitoIdentityPoolId, 47 | }, 48 | } 49 | if len(req.ClientContext) > 0 { 50 | if err := json.Unmarshal(req.ClientContext, &lc.ClientContext); err != nil { 51 | response.Error = lambdaErrorResponse(err) 52 | return nil 53 | } 54 | } 55 | invokeContext = lambdacontext.NewContext(invokeContext, lc) 56 | 57 | invokeContext = context.WithValue(invokeContext, "x-amzn-trace-id", req.XAmznTraceId) 58 | 59 | payload, err := fn.handler.Invoke(invokeContext, req.Payload) 60 | if err != nil { 61 | response.Error = lambdaErrorResponse(err) 62 | return nil 63 | } 64 | response.Payload = payload 65 | return nil 66 | } 67 | 68 | func getErrorType(err interface{}) string { 69 | errorType := reflect.TypeOf(err) 70 | if errorType.Kind() == reflect.Ptr { 71 | return errorType.Elem().Name() 72 | } 73 | return errorType.Name() 74 | } 75 | 76 | func lambdaErrorResponse(invokeError error) *messages.InvokeResponse_Error { 77 | var errorName string 78 | if errorType := reflect.TypeOf(invokeError); errorType.Kind() == reflect.Ptr { 79 | errorName = errorType.Elem().Name() 80 | } else { 81 | errorName = errorType.Name() 82 | } 83 | return &messages.InvokeResponse_Error{ 84 | Message: invokeError.Error(), 85 | Type: errorName, 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/lex.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type LexEvent struct { 4 | MessageVersion string `json:"messageVersion,omitempty"` 5 | InvocationSource string `json:"invocationSource,omitempty"` 6 | UserID string `json:"userId,omitempty"` 7 | InputTranscript string `json:"inputTranscript,omitempty"` 8 | SessionAttributes map[string]string `json:"sessionAttributes,omitempty"` 9 | RequestAttributes map[string]string `json:"requestAttributes,omitempty"` 10 | Bot *LexBot `json:"bot,omitempty"` 11 | OutputDialogMode string `json:"outputDialogMode,omitempty"` 12 | CurrentIntent *LexCurrentIntent `json:"currentIntent,omitempty"` 13 | DialogAction *LexDialogAction `json:"dialogAction,omitempty"` 14 | } 15 | 16 | type LexBot struct { 17 | Name string `json:"name,omitempty"` 18 | Alias string `json:"alias,omitempty"` 19 | Version string `json:"version,omitempty"` 20 | } 21 | 22 | type LexCurrentIntent struct { 23 | Name string `json:"name,omitempty"` 24 | Slots Slots `json:"slots,omitempty"` 25 | SlotDetails map[string]SlotDetail `json:"slotDetails,omitempty"` 26 | ConfirmationStatus string `json:"confirmationStatus,omitempty"` 27 | } 28 | 29 | type SlotDetail struct { 30 | Resolutions []map[string]string `json:"resolutions,omitempty"` 31 | OriginalValue string `json:"originalValue,omitempty"` 32 | } 33 | 34 | type LexDialogAction struct { 35 | Type string `json:"type,omitempty"` 36 | FulfillmentState string `json:"fulfillmentState,omitempty"` 37 | Message map[string]string `json:"message,omitempty"` 38 | IntentName string `json:"intentName,omitempty"` 39 | Slots Slots `json:"slots,omitempty"` 40 | SlotToElicit string `json:"slotToElicit,omitempty"` 41 | ResponseCard *LexResponseCard `json:"responseCard,omitempty"` 42 | } 43 | 44 | type Slots map[string]string 45 | 46 | type LexResponseCard struct { 47 | Version int64 `json:"version,omitempty"` 48 | ContentType string `json:"contentType,omitempty"` 49 | GenericAttachments []Attachment `json:"genericAttachments,omitempty"` 50 | } 51 | 52 | type Attachment struct { 53 | Title string `json:"title,omitempty"` 54 | SubTitle string `json:"subTitle,omitempty"` 55 | ImageURL string `json:"imageUrl,omitempty"` 56 | AttachmentLinkURL string `json:"attachmentLinkUrl,omitempty"` 57 | Buttons []map[string]string `json:"buttons,omitempty"` 58 | } 59 | 60 | func (h *LexEvent) Clear() { 61 | h.Bot = nil 62 | h.CurrentIntent = nil 63 | h.DialogAction = nil 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambda/panic.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package lambda 4 | 5 | import ( 6 | "fmt" 7 | "runtime" 8 | "strings" 9 | 10 | "github.com/aws/aws-lambda-go/lambda/messages" 11 | ) 12 | 13 | type panicInfo struct { 14 | Message string // Value passed to panic call, converted to string 15 | StackTrace []*messages.InvokeResponse_Error_StackFrame // Stack trace of the panic 16 | } 17 | 18 | func getPanicInfo(value interface{}) panicInfo { 19 | message := getPanicMessage(value) 20 | stack := getPanicStack() 21 | 22 | return panicInfo{Message: message, StackTrace: stack} 23 | } 24 | 25 | func getPanicMessage(value interface{}) string { 26 | return fmt.Sprintf("%v", value) 27 | } 28 | 29 | var defaultErrorFrameCount = 32 30 | 31 | func getPanicStack() []*messages.InvokeResponse_Error_StackFrame { 32 | s := make([]uintptr, defaultErrorFrameCount) 33 | const framesToHide = 3 // this (getPanicStack) -> getPanicInfo -> handler defer func 34 | n := runtime.Callers(framesToHide, s) 35 | if n == 0 { 36 | return make([]*messages.InvokeResponse_Error_StackFrame, 0) 37 | } 38 | 39 | s = s[:n] 40 | 41 | return convertStack(s) 42 | } 43 | 44 | func convertStack(s []uintptr) []*messages.InvokeResponse_Error_StackFrame { 45 | var converted []*messages.InvokeResponse_Error_StackFrame 46 | frames := runtime.CallersFrames(s) 47 | 48 | for { 49 | frame, more := frames.Next() 50 | 51 | formattedFrame := formatFrame(frame) 52 | converted = append(converted, formattedFrame) 53 | 54 | if !more { 55 | break 56 | } 57 | } 58 | return converted 59 | } 60 | 61 | func formatFrame(inputFrame runtime.Frame) *messages.InvokeResponse_Error_StackFrame { 62 | path := inputFrame.File 63 | line := int32(inputFrame.Line) 64 | label := inputFrame.Function 65 | 66 | // Strip GOPATH from path by counting the number of seperators in label & path 67 | // 68 | // For example given this: 69 | // GOPATH = /home/user 70 | // path = /home/user/src/pkg/sub/file.go 71 | // label = pkg/sub.Type.Method 72 | // 73 | // We want to set: 74 | // path = pkg/sub/file.go 75 | // label = Type.Method 76 | 77 | i := len(path) 78 | for n, g := 0, strings.Count(label, "/")+2; n < g; n++ { 79 | i = strings.LastIndex(path[:i], "/") 80 | if i == -1 { 81 | // Something went wrong and path has less seperators than we expected 82 | // Abort and leave i as -1 to counteract the +1 below 83 | break 84 | } 85 | } 86 | 87 | path = path[i+1:] // Trim the initial / 88 | 89 | // Strip the path from the function name as it's already in the path 90 | label = label[strings.LastIndex(label, "/")+1:] 91 | // Likewise strip the package name 92 | label = label[strings.Index(label, ".")+1:] 93 | 94 | return &messages.InvokeResponse_Error_StackFrame{ 95 | Path: path, 96 | Line: line, 97 | Label: label, 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/codepipeline_job.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // CodePipelineEvent contains data from an event sent from AWS Codepipeline 6 | type CodePipelineEvent struct { 7 | CodePipelineJob CodePipelineJob `json:"CodePipeline.job"` 8 | } 9 | 10 | // CodePipelineJob represents a job from an AWS CodePipeline event 11 | type CodePipelineJob struct { 12 | ID string `json:"id"` 13 | AccountID string `json:"accountId"` 14 | Data CodePipelineData `json:"data"` 15 | } 16 | 17 | // CodePipelineData represents a job from an AWS CodePipeline event 18 | type CodePipelineData struct { 19 | ActionConfiguration CodePipelineActionConfiguration `json:"actionConfiguration"` 20 | InputArtifacts []CodePipelineInputArtifact `json:"inputArtifacts"` 21 | OutPutArtifacts []CodePipelineOutputArtifact `json:"outputArtifacts"` 22 | ArtifactCredentials CodePipelineArtifactCredentials `json:"artifactCredentials"` 23 | ContinuationToken string `json:"continuationToken"` 24 | } 25 | 26 | // CodePipelineActionConfiguration represents an Action Configuration 27 | type CodePipelineActionConfiguration struct { 28 | Configuration CodePipelineConfiguration `json:"configuration"` 29 | } 30 | 31 | // CodePipelineConfiguration represents a configuration for an Action Configuration 32 | type CodePipelineConfiguration struct { 33 | FunctionName string `json:"FunctionName"` 34 | UserParameters string `json:"UserParameters"` 35 | } 36 | 37 | // CodePipelineInputArtifact represents an input artifact 38 | type CodePipelineInputArtifact struct { 39 | Location CodePipelineInputLocation `json:"location"` 40 | Revision *string `json:"revision"` 41 | Name string `json:"name"` 42 | } 43 | 44 | // CodePipelineInputLocation represents a input location 45 | type CodePipelineInputLocation struct { 46 | S3Location CodePipelineS3Location `json:"s3Location"` 47 | LocationType string `json:"type"` 48 | } 49 | 50 | // CodePipelineS3Location represents an s3 input location 51 | type CodePipelineS3Location struct { 52 | BucketName string `json:"bucketName"` 53 | ObjectKey string `json:"objectKey"` 54 | } 55 | 56 | // CodePipelineOutputArtifact represents an output artifact 57 | type CodePipelineOutputArtifact struct { 58 | Location CodePipelineInputLocation `json:"location"` 59 | Revision *string `json:"revision"` 60 | Name string `json:"name"` 61 | } 62 | 63 | // CodePipelineOutputLocation represents a output location 64 | type CodePipelineOutputLocation struct { 65 | S3Location CodePipelineS3Location `json:"s3Location"` 66 | LocationType string `json:"type"` 67 | } 68 | 69 | // CodePipelineArtifactCredentials represents CodePipeline artifact credentials 70 | type CodePipelineArtifactCredentials struct { 71 | SecretAccessKey string `json:"secretAccessKey"` 72 | SessionToken string `json:"sessionToken"` 73 | AccessKeyID string `json:"accessKeyId"` 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambdacontext/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Helpers for accessing context information from an Invoke request. Context information 4 | // is stored in a https://golang.org/pkg/context/#Context. The functions FromContext and NewContext 5 | // are used to retrieving and inserting an isntance of LambdaContext. 6 | 7 | package lambdacontext 8 | 9 | import ( 10 | "context" 11 | "os" 12 | "strconv" 13 | ) 14 | 15 | // LogGroupName is the name of the log group that contains the log streams of the current Lambda Function 16 | var LogGroupName string 17 | 18 | // LogStreamName name of the log stream that the current Lambda Function's logs will be sent to 19 | var LogStreamName string 20 | 21 | // FunctionName the name of the current Lambda Function 22 | var FunctionName string 23 | 24 | // MemoryLimitInMB is the configured memory limit for the current instance of the Lambda Function 25 | var MemoryLimitInMB int 26 | 27 | // FunctionVersion is the published version of the current instance of the Lambda Function 28 | var FunctionVersion string 29 | 30 | func init() { 31 | LogGroupName = os.Getenv("AWS_LAMBDA_LOG_GROUP_NAME") 32 | LogStreamName = os.Getenv("AWS_LAMBDA_LOG_STREAM_NAME") 33 | FunctionName = os.Getenv("AWS_LAMBDA_FUNCTION_NAME") 34 | if limit, err := strconv.Atoi(os.Getenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")); err != nil { 35 | MemoryLimitInMB = 0 36 | } else { 37 | MemoryLimitInMB = limit 38 | } 39 | FunctionVersion = os.Getenv("AWS_LAMBDA_FUNCTION_VERSION") 40 | } 41 | 42 | // ClientApplication is metadata about the calling application. 43 | type ClientApplication struct { 44 | InstallationID string `json:"installation_id"` 45 | AppTitle string `json:"app_title"` 46 | AppVersionCode string `json:"app_version_code"` 47 | AppPackageName string `json:"app_package_name"` 48 | } 49 | 50 | // ClientContext is information about the client application passed by the calling application. 51 | type ClientContext struct { 52 | Client ClientApplication 53 | Env map[string]string `json:"env"` 54 | Custom map[string]string `json:"custom"` 55 | } 56 | 57 | // CognitoIdentity is the cognito identity used by the calling application. 58 | type CognitoIdentity struct { 59 | CognitoIdentityID string 60 | CognitoIdentityPoolID string 61 | } 62 | 63 | // LambdaContext is the set of metadata that is passed for every Invoke. 64 | type LambdaContext struct { 65 | AwsRequestID string 66 | InvokedFunctionArn string 67 | Identity CognitoIdentity 68 | ClientContext ClientContext 69 | } 70 | 71 | // An unexported type to be used as the key for types in this package. 72 | // This prevents collisions with keys defined in other packages. 73 | type key struct{} 74 | 75 | // The key for a LambdaContext in Contexts. 76 | // Users of this package must use lambdacontext.NewContext and lambdacontext.FromContext 77 | // instead of using this key directly. 78 | var contextKey = &key{} 79 | 80 | // NewContext returns a new Context that carries value lc. 81 | func NewContext(parent context.Context, lc *LambdaContext) context.Context { 82 | return context.WithValue(parent, contextKey, lc) 83 | } 84 | 85 | // FromContext returns the LambdaContext value stored in ctx, if any. 86 | func FromContext(ctx context.Context) (*LambdaContext, bool) { 87 | lc, ok := ctx.Value(contextKey).(*LambdaContext) 88 | return lc, ok 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/cognito.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // CognitoEvent contains data from an event sent from AWS Cognito Sync 6 | type CognitoEvent struct { 7 | DatasetName string `json:"datasetName"` 8 | DatasetRecords map[string]CognitoDatasetRecord `json:"datasetRecords"` 9 | EventType string `json:"eventType"` 10 | IdentityID string `json:"identityId"` 11 | IdentityPoolID string `json:"identityPoolId"` 12 | Region string `json:"region"` 13 | Version int `json:"version"` 14 | } 15 | 16 | // CognitoDatasetRecord represents a record from an AWS Cognito Sync event 17 | type CognitoDatasetRecord struct { 18 | NewValue string `json:"newValue"` 19 | OldValue string `json:"oldValue"` 20 | Op string `json:"op"` 21 | } 22 | 23 | // CognitoEventUserPoolsPreSignup is sent by AWS Cognito User Pools when a user attempts to register 24 | // (sign up), allowing a Lambda to perform custom validation to accept or deny the registration request 25 | type CognitoEventUserPoolsPreSignup struct { 26 | CognitoEventUserPoolsHeader 27 | Request CognitoEventUserPoolsPreSignupRequest `json:"request"` 28 | Response CognitoEventUserPoolsPreSignupResponse `json:"response"` 29 | } 30 | 31 | // CognitoEventUserPoolsPostConfirmation is sent by AWS Cognito User Pools after a user is confirmed, 32 | // allowing the Lambda to send custom messages or add custom logic. 33 | type CognitoEventUserPoolsPostConfirmation struct { 34 | CognitoEventUserPoolsHeader 35 | Request CognitoEventUserPoolsPostConfirmationRequest `json:"request"` 36 | Response CognitoEventUserPoolsPostConfirmationResponse `json:"response"` 37 | } 38 | 39 | // CognitoEventUserPoolsCallerContext contains information about the caller 40 | type CognitoEventUserPoolsCallerContext struct { 41 | AWSSDKVersion string `json:"awsSdkVersion"` 42 | ClientID string `json:"clientId"` 43 | } 44 | 45 | // CognitoEventUserPoolsHeader contains common data from events sent by AWS Cognito User Pools 46 | type CognitoEventUserPoolsHeader struct { 47 | Version string `json:"version"` 48 | TriggerSource string `json:"triggerSource"` 49 | Region string `json:"region"` 50 | UserPoolID string `json:"userPoolId"` 51 | CallerContext CognitoEventUserPoolsCallerContext `json:"callerContext"` 52 | UserName string `json:"userName"` 53 | } 54 | 55 | // CognitoEventUserPoolsPreSignupRequest contains the request portion of a PreSignup event 56 | type CognitoEventUserPoolsPreSignupRequest struct { 57 | UserAttributes map[string]string `json:"userAttributes"` 58 | ValidationData map[string]string `json:"validationData"` 59 | } 60 | 61 | // CognitoEventUserPoolsPreSignupResponse contains the response portion of a PreSignup event 62 | type CognitoEventUserPoolsPreSignupResponse struct { 63 | AutoConfirmUser bool `json:"autoConfirmUser"` 64 | AutoVerifyEmail bool `json:"autoVerifyEmail"` 65 | AutoVerifyPhone bool `json:"autoVerifyPhone"` 66 | } 67 | 68 | // CognitoEventUserPoolsPostConfirmationRequest contains the request portion of a PostConfirmation event 69 | type CognitoEventUserPoolsPostConfirmationRequest struct { 70 | UserAttributes map[string]string `json:"userAttributes"` 71 | } 72 | 73 | // CognitoEventUserPoolsPostConfirmationResponse contains the response portion of a PostConfirmation event 74 | type CognitoEventUserPoolsPostConfirmationResponse struct { 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/code_commit.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | // CodeCommitEvent represents a CodeCommit event 10 | type CodeCommitEvent struct { 11 | Records []CodeCommitRecord `json:"Records"` 12 | } 13 | 14 | // String returns a string representation of this object. 15 | // Useful for testing and debugging. 16 | func (e CodeCommitEvent) String() string { 17 | return fmt.Sprintf("{Records: %v}", e.Records) 18 | } 19 | 20 | type CodeCommitEventTime time.Time 21 | 22 | // https://golang.org/pkg/time/#Parse 23 | const codeCommitEventTimeReference = "\"2006-01-2T15:04:05.000-0700\"" 24 | 25 | func (t *CodeCommitEventTime) MarshalJSON() ([]byte, error) { 26 | if t == nil { 27 | return nil, errors.New("CodeCommitEventTime cannot be nil") 28 | } 29 | 30 | gt := time.Time(*t) 31 | return []byte(gt.Format(codeCommitEventTimeReference)), nil 32 | } 33 | 34 | func (t *CodeCommitEventTime) UnmarshalJSON(data []byte) error { 35 | if t == nil { 36 | return errors.New("CodeCommitEventTime cannot be nil") 37 | } 38 | 39 | pt, err := time.Parse(codeCommitEventTimeReference, string(data)) 40 | if err == nil { 41 | *t = CodeCommitEventTime(pt) 42 | } 43 | return err 44 | } 45 | 46 | // represents a CodeCommit record 47 | type CodeCommitRecord struct { 48 | EventID string `json:"eventId"` 49 | EventVersion string `json:"eventVersion"` 50 | EventTime CodeCommitEventTime `json:"eventTime"` 51 | EventTriggerName string `json:"eventTriggerName"` 52 | EventPartNumber uint64 `json:"eventPartNumber"` 53 | CodeCommit CodeCommitCodeCommit `json:"codecommit"` 54 | EventName string `json:"eventName"` 55 | EventTriggerConfigId string `json:"eventTriggerConfigId"` 56 | EventSourceARN string `json:"eventSourceARN"` 57 | UserIdentityARN string `json:"userIdentityARN"` 58 | EventSource string `json:"eventSource"` 59 | AWSRegion string `json:"awsRegion"` 60 | EventTotalParts uint64 `json:"eventTotalParts"` 61 | } 62 | 63 | // String returns a string representation of this object. 64 | // Useful for testing and debugging. 65 | func (r CodeCommitRecord) String() string { 66 | return fmt.Sprintf( 67 | "{eventId: %v, eventVersion: %v, eventTime: %v, eventTriggerName: %v, "+ 68 | "eventPartNumber: %v, codeCommit: %v, eventName: %v, "+ 69 | "eventTriggerConfigId: %v, eventSourceARN: %v, userIdentityARN: %v, "+ 70 | "eventSource: %v, awsRegion: %v, eventTotalParts: %v}", 71 | r.EventID, r.EventVersion, r.EventTime, r.EventTriggerName, 72 | r.EventPartNumber, r.CodeCommit, r.EventName, 73 | r.EventTriggerConfigId, r.EventSourceARN, r.UserIdentityARN, 74 | r.EventSource, r.AWSRegion, r.EventTotalParts) 75 | } 76 | 77 | // CodeCommitCodeCommit represents a CodeCommit object in a record 78 | type CodeCommitCodeCommit struct { 79 | References []CodeCommitReference `json:"references"` 80 | } 81 | 82 | // String returns a string representation of this object. 83 | // Useful for testing and debugging. 84 | func (c CodeCommitCodeCommit) String() string { 85 | return fmt.Sprintf("{references: %v}", c.References) 86 | } 87 | 88 | // CodeCommitReference represents a Reference object in a CodeCommit object 89 | type CodeCommitReference struct { 90 | Commit string `json:"commit"` 91 | Ref string `json:"ref"` 92 | Created bool `json:"created,omitempty"` 93 | } 94 | 95 | // String returns a string representation of this object. 96 | // Useful for testing and debugging. 97 | func (r CodeCommitReference) String() string { 98 | return fmt.Sprintf( 99 | "{commit: %v, ref: %v, created: %v}", r.Commit, r.Ref, r.Created) 100 | } 101 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/lambda/handler.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package lambda 4 | 5 | import ( 6 | "context" 7 | "encoding/json" 8 | "fmt" 9 | "reflect" 10 | ) 11 | 12 | type Handler interface { 13 | Invoke(ctx context.Context, payload []byte) ([]byte, error) 14 | } 15 | 16 | // lambdaHandler is the generic function type 17 | type lambdaHandler func(context.Context, []byte) (interface{}, error) 18 | 19 | // Invoke calls the handler, and serializes the response. 20 | // If the underlying handler returned an error, or an error occurs during serialization, error is returned. 21 | func (handler lambdaHandler) Invoke(ctx context.Context, payload []byte) ([]byte, error) { 22 | response, err := handler(ctx, payload) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | responseBytes, err := json.Marshal(response) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | return responseBytes, nil 33 | } 34 | 35 | func errorHandler(e error) lambdaHandler { 36 | return func(ctx context.Context, event []byte) (interface{}, error) { 37 | return nil, e 38 | } 39 | } 40 | 41 | func validateArguments(handler reflect.Type) (bool, error) { 42 | handlerTakesContext := false 43 | if handler.NumIn() > 2 { 44 | return false, fmt.Errorf("handlers may not take more than two arguments, but handler takes %d", handler.NumIn()) 45 | } else if handler.NumIn() > 0 { 46 | contextType := reflect.TypeOf((*context.Context)(nil)).Elem() 47 | argumentType := handler.In(0) 48 | handlerTakesContext = argumentType.Implements(contextType) 49 | if handler.NumIn() > 1 && !handlerTakesContext { 50 | return false, fmt.Errorf("handler takes two arguments, but the first is not Context. got %s", argumentType.Kind()) 51 | } 52 | } 53 | 54 | return handlerTakesContext, nil 55 | } 56 | 57 | func validateReturns(handler reflect.Type) error { 58 | errorType := reflect.TypeOf((*error)(nil)).Elem() 59 | if handler.NumOut() > 2 { 60 | return fmt.Errorf("handler may not return more than two values") 61 | } else if handler.NumOut() > 1 { 62 | if !handler.Out(1).Implements(errorType) { 63 | return fmt.Errorf("handler returns two values, but the second does not implement error") 64 | } 65 | } else if handler.NumOut() == 1 { 66 | if !handler.Out(0).Implements(errorType) { 67 | return fmt.Errorf("handler returns a single value, but it does not implement error") 68 | } 69 | } 70 | return nil 71 | } 72 | 73 | // newHandler Creates the base lambda handler, which will do basic payload unmarshaling before defering to handlerSymbol. 74 | // If handlerSymbol is not a valid handler, the returned function will be a handler that just reports the validation error. 75 | func newHandler(handlerSymbol interface{}) lambdaHandler { 76 | if handlerSymbol == nil { 77 | return errorHandler(fmt.Errorf("handler is nil")) 78 | } 79 | handler := reflect.ValueOf(handlerSymbol) 80 | handlerType := reflect.TypeOf(handlerSymbol) 81 | if handlerType.Kind() != reflect.Func { 82 | return errorHandler(fmt.Errorf("handler kind %s is not %s", handlerType.Kind(), reflect.Func)) 83 | } 84 | 85 | takesContext, err := validateArguments(handlerType) 86 | if err != nil { 87 | return errorHandler(err) 88 | } 89 | 90 | if err := validateReturns(handlerType); err != nil { 91 | return errorHandler(err) 92 | } 93 | 94 | return func(ctx context.Context, payload []byte) (interface{}, error) { 95 | // construct arguments 96 | var args []reflect.Value 97 | if takesContext { 98 | args = append(args, reflect.ValueOf(ctx)) 99 | } 100 | if (handlerType.NumIn() == 1 && !takesContext) || handlerType.NumIn() == 2 { 101 | eventType := handlerType.In(handlerType.NumIn() - 1) 102 | event := reflect.New(eventType) 103 | 104 | if err := json.Unmarshal(payload, event.Interface()); err != nil { 105 | return nil, err 106 | } 107 | 108 | args = append(args, event.Elem()) 109 | } 110 | 111 | response := handler.Call(args) 112 | 113 | // convert return values into (interface{}, error) 114 | var err error 115 | if len(response) > 0 { 116 | if errVal, ok := response[len(response)-1].Interface().(error); ok { 117 | err = errVal 118 | } 119 | } 120 | var val interface{} 121 | if len(response) > 1 { 122 | val = response[0].Interface() 123 | } 124 | 125 | return val, err 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/dynamodb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // The DynamoDBEvent stream event handled to Lambda 6 | // http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-ddb-update 7 | type DynamoDBEvent struct { 8 | Records []DynamoDBEventRecord `json:"Records"` 9 | } 10 | 11 | // DynamoDbEventRecord stores information about each record of a DynamoDb stream event 12 | type DynamoDBEventRecord struct { 13 | // The region in which the GetRecords request was received. 14 | AWSRegion string `json:"awsRegion"` 15 | 16 | // The main body of the stream record, containing all of the DynamoDB-specific 17 | // fields. 18 | Change DynamoDBStreamRecord `json:"dynamodb"` 19 | 20 | // A globally unique identifier for the event that was recorded in this stream 21 | // record. 22 | EventID string `json:"eventID"` 23 | 24 | // The type of data modification that was performed on the DynamoDB table: 25 | // 26 | // * INSERT - a new item was added to the table. 27 | // 28 | // * MODIFY - one or more of an existing item's attributes were modified. 29 | // 30 | // * REMOVE - the item was deleted from the table 31 | EventName string `json:"eventName"` 32 | 33 | // The AWS service from which the stream record originated. For DynamoDB Streams, 34 | // this is aws:dynamodb. 35 | EventSource string `json:"eventSource"` 36 | 37 | // The version number of the stream record format. This number is updated whenever 38 | // the structure of Record is modified. 39 | // 40 | // Client applications must not assume that eventVersion will remain at a particular 41 | // value, as this number is subject to change at any time. In general, eventVersion 42 | // will only increase as the low-level DynamoDB Streams API evolves. 43 | EventVersion string `json:"eventVersion"` 44 | 45 | // The event source ARN of DynamoDB 46 | EventSourceArn string `json:"eventSourceARN"` 47 | 48 | // Items that are deleted by the Time to Live process after expiration have 49 | // the following fields: 50 | // 51 | // * Records[].userIdentity.type 52 | // 53 | // "Service" 54 | // 55 | // * Records[].userIdentity.principalId 56 | // 57 | // "dynamodb.amazonaws.com" 58 | UserIdentity *DynamoDBUserIdentity `json:"userIdentity,omitempty"` 59 | } 60 | 61 | type DynamoDBUserIdentity struct { 62 | Type string `json:"type"` 63 | PrincipalID string `json:"principalId"` 64 | } 65 | 66 | // A description of a single data modification that was performed on an item 67 | // in a DynamoDB table. 68 | type DynamoDBStreamRecord struct { 69 | 70 | // The approximate date and time when the stream record was created, in UNIX 71 | // epoch time (http://www.epochconverter.com/) format. 72 | ApproximateCreationDateTime SecondsEpochTime `json:"ApproximateCreationDateTime,omitempty"` 73 | 74 | // The primary key attribute(s) for the DynamoDB item that was modified. 75 | Keys map[string]DynamoDBAttributeValue `json:"Keys,omitempty"` 76 | 77 | // The item in the DynamoDB table as it appeared after it was modified. 78 | NewImage map[string]DynamoDBAttributeValue `json:"NewImage,omitempty"` 79 | 80 | // The item in the DynamoDB table as it appeared before it was modified. 81 | OldImage map[string]DynamoDBAttributeValue `json:"OldImage,omitempty"` 82 | 83 | // The sequence number of the stream record. 84 | SequenceNumber string `json:"SequenceNumber"` 85 | 86 | // The size of the stream record, in bytes. 87 | SizeBytes int64 `json:"SizeBytes"` 88 | 89 | // The type of data from the modified DynamoDB item that was captured in this 90 | // stream record. 91 | StreamViewType string `json:"StreamViewType"` 92 | } 93 | 94 | type DynamoDBKeyType string 95 | 96 | const ( 97 | DynamoDBKeyTypeHash DynamoDBKeyType = "HASH" 98 | DynamoDBKeyTypeRange DynamoDBKeyType = "RANGE" 99 | ) 100 | 101 | type DynamoDBOperationType string 102 | 103 | const ( 104 | DynamoDBOperationTypeInsert DynamoDBOperationType = "INSERT" 105 | DynamoDBOperationTypeModify DynamoDBOperationType = "MODIFY" 106 | DynamoDBOperationTypeRemove DynamoDBOperationType = "REMOVE" 107 | ) 108 | 109 | type DynamoDBSharedIteratorType string 110 | 111 | const ( 112 | DynamoDBShardIteratorTypeTrimHorizon DynamoDBSharedIteratorType = "TRIM_HORIZON" 113 | DynamoDBShardIteratorTypeLatest DynamoDBSharedIteratorType = "LATEST" 114 | DynamoDBShardIteratorTypeAtSequenceNumber DynamoDBSharedIteratorType = "AT_SEQUENCE_NUMBER" 115 | DynamoDBShardIteratorTypeAfterSequenceNumber DynamoDBSharedIteratorType = "AFTER_SEQUENCE_NUMBER" 116 | ) 117 | 118 | type DynamoDBStreamStatus string 119 | 120 | const ( 121 | DynamoDBStreamStatusEnabling DynamoDBStreamStatus = "ENABLING" 122 | DynamoDBStreamStatusEnabled DynamoDBStreamStatus = "ENABLED" 123 | DynamoDBStreamStatusDisabling DynamoDBStreamStatus = "DISABLING" 124 | DynamoDBStreamStatusDisabled DynamoDBStreamStatus = "DISABLED" 125 | ) 126 | 127 | type DynamoDBStreamViewType string 128 | 129 | const ( 130 | DynamoDBStreamViewTypeNewImage DynamoDBStreamViewType = "NEW_IMAGE" // the entire item, as it appeared after it was modified. 131 | DynamoDBStreamViewTypeOldImage DynamoDBStreamViewType = "OLD_IMAGE" // the entire item, as it appeared before it was modified. 132 | DynamoDBStreamViewTypeNewAndOldImages DynamoDBStreamViewType = "NEW_AND_OLD_IMAGES" // both the new and the old item images of the item. 133 | DynamoDBStreamViewTypeKeysOnly DynamoDBStreamViewType = "KEYS_ONLY" // only the key attributes of the modified item. 134 | ) 135 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/apigw.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // APIGatewayProxyRequest contains data coming from the API Gateway proxy 6 | type APIGatewayProxyRequest struct { 7 | Resource string `json:"resource"` // The resource path defined in API Gateway 8 | Path string `json:"path"` // The url path for the caller 9 | HTTPMethod string `json:"httpMethod"` 10 | Headers map[string]string `json:"headers"` 11 | QueryStringParameters map[string]string `json:"queryStringParameters"` 12 | PathParameters map[string]string `json:"pathParameters"` 13 | StageVariables map[string]string `json:"stageVariables"` 14 | RequestContext APIGatewayProxyRequestContext `json:"requestContext"` 15 | Body string `json:"body"` 16 | IsBase64Encoded bool `json:"isBase64Encoded,omitempty"` 17 | } 18 | 19 | // APIGatewayProxyResponse configures the response to be returned by API Gateway for the request 20 | type APIGatewayProxyResponse struct { 21 | StatusCode int `json:"statusCode"` 22 | Headers map[string]string `json:"headers"` 23 | Body string `json:"body"` 24 | IsBase64Encoded bool `json:"isBase64Encoded,omitempty"` 25 | } 26 | 27 | // APIGatewayProxyRequestContext contains the information to identify the AWS account and resources invoking the 28 | // Lambda function. It also includes Cognito identity information for the caller. 29 | type APIGatewayProxyRequestContext struct { 30 | AccountID string `json:"accountId"` 31 | ResourceID string `json:"resourceId"` 32 | Stage string `json:"stage"` 33 | RequestID string `json:"requestId"` 34 | Identity APIGatewayRequestIdentity `json:"identity"` 35 | ResourcePath string `json:"resourcePath"` 36 | Authorizer map[string]interface{} `json:"authorizer"` 37 | HTTPMethod string `json:"httpMethod"` 38 | APIID string `json:"apiId"` // The API Gateway rest API Id 39 | } 40 | 41 | // APIGatewayRequestIdentity contains identity information for the request caller. 42 | type APIGatewayRequestIdentity struct { 43 | CognitoIdentityPoolID string `json:"cognitoIdentityPoolId"` 44 | AccountID string `json:"accountId"` 45 | CognitoIdentityID string `json:"cognitoIdentityId"` 46 | Caller string `json:"caller"` 47 | APIKey string `json:"apiKey"` 48 | SourceIP string `json:"sourceIp"` 49 | CognitoAuthenticationType string `json:"cognitoAuthenticationType"` 50 | CognitoAuthenticationProvider string `json:"cognitoAuthenticationProvider"` 51 | UserArn string `json:"userArn"` 52 | UserAgent string `json:"userAgent"` 53 | User string `json:"user"` 54 | } 55 | 56 | // APIGatewayCustomAuthorizerRequestTypeRequestIdentity contains identity information for the request caller. 57 | type APIGatewayCustomAuthorizerRequestTypeRequestIdentity struct { 58 | APIKey string `json:"apiKey"` 59 | SourceIP string `json:"sourceIp"` 60 | } 61 | 62 | // APIGatewayCustomAuthorizerContext represents the expected format of an API Gateway custom authorizer response. 63 | // Deprecated. Code should be updated to use the Authorizer map from APIGatewayRequestIdentity. Ex: Authorizer["principalId"] 64 | type APIGatewayCustomAuthorizerContext struct { 65 | PrincipalID *string `json:"principalId"` 66 | StringKey *string `json:"stringKey,omitempty"` 67 | NumKey *int `json:"numKey,omitempty"` 68 | BoolKey *bool `json:"boolKey,omitempty"` 69 | } 70 | 71 | // APIGatewayCustomAuthorizerRequestTypeRequestContext represents the expected format of an API Gateway custom authorizer response. 72 | type APIGatewayCustomAuthorizerRequestTypeRequestContext struct { 73 | Path string `json:"path"` 74 | AccountID string `json:"accountId"` 75 | ResourceID string `json:"resourceId"` 76 | Stage string `json:"stage"` 77 | RequestID string `json:"requestId"` 78 | Identity APIGatewayCustomAuthorizerRequestTypeRequestIdentity `json:"identity"` 79 | ResourcePath string `json:"resourcePath"` 80 | HTTPMethod string `json:"httpMethod"` 81 | APIID string `json:"apiId"` 82 | } 83 | 84 | // APIGatewayCustomAuthorizerRequest contains data coming in to a custom API Gateway authorizer function. 85 | type APIGatewayCustomAuthorizerRequest struct { 86 | Type string `json:"type"` 87 | AuthorizationToken string `json:"authorizationToken"` 88 | MethodArn string `json:"methodArn"` 89 | } 90 | 91 | // APIGatewayCustomAuthorizerRequestTypeRequest contains data coming in to a custom API Gateway authorizer function. 92 | type APIGatewayCustomAuthorizerRequestTypeRequest struct { 93 | Type string `json:"type"` 94 | MethodArn string `json:"methodArn"` 95 | Resource string `json:"resource"` 96 | Path string `json:"path"` 97 | HTTPMethod string `json:"httpMethod"` 98 | Headers map[string]string `json:"headers"` 99 | QueryStringParameters map[string]string `json:"queryStringParameters"` 100 | PathParameters map[string]string `json:"pathParameters"` 101 | StageVariables map[string]string `json:"stageVariables"` 102 | RequestContext APIGatewayCustomAuthorizerRequestTypeRequestContext `json:"requestContext"` 103 | } 104 | 105 | // APIGatewayCustomAuthorizerResponse represents the expected format of an API Gateway authorization response. 106 | type APIGatewayCustomAuthorizerResponse struct { 107 | PrincipalID string `json:"principalId"` 108 | PolicyDocument APIGatewayCustomAuthorizerPolicy `json:"policyDocument"` 109 | Context map[string]interface{} `json:"context,omitempty"` 110 | UsageIdentifierKey string `json:"usageIdentifierKey,omitempty"` 111 | } 112 | 113 | // APIGatewayCustomAuthorizerPolicy represents an IAM policy 114 | type APIGatewayCustomAuthorizerPolicy struct { 115 | Version string 116 | Statement []IAMPolicyStatement 117 | } 118 | 119 | type IAMPolicyStatement struct { 120 | Action []string 121 | Effect string 122 | Resource []string 123 | } 124 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-lambda-go/events/attributevalue.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "bytes" 7 | "encoding/base64" 8 | "encoding/json" 9 | "errors" 10 | "fmt" 11 | "strconv" 12 | ) 13 | 14 | // DynamoDBAttributeValue provides convenient access for a value stored in DynamoDB. 15 | // For more information, please see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html 16 | type DynamoDBAttributeValue struct { 17 | value anyValue 18 | dataType DynamoDBDataType 19 | } 20 | 21 | // Binary provides access to an attribute of type Binary. 22 | // Method panics if the attribute is not of type Binary. 23 | func (av DynamoDBAttributeValue) Binary() []byte { 24 | av.ensureType(DataTypeBinary) 25 | return av.value.([]byte) 26 | } 27 | 28 | // Boolean provides access to an attribute of type Boolean. 29 | // Method panics if the attribute is not of type Boolean. 30 | func (av DynamoDBAttributeValue) Boolean() bool { 31 | av.ensureType(DataTypeBoolean) 32 | return av.value.(bool) 33 | } 34 | 35 | // BinarySet provides access to an attribute of type Binary Set. 36 | // Method panics if the attribute is not of type BinarySet. 37 | func (av DynamoDBAttributeValue) BinarySet() [][]byte { 38 | av.ensureType(DataTypeBinarySet) 39 | return av.value.([][]byte) 40 | } 41 | 42 | // List provides access to an attribute of type List. Each element 43 | // of the list is an DynamoDBAttributeValue itself. 44 | // Method panics if the attribute is not of type List. 45 | func (av DynamoDBAttributeValue) List() []DynamoDBAttributeValue { 46 | av.ensureType(DataTypeList) 47 | return av.value.([]DynamoDBAttributeValue) 48 | } 49 | 50 | // Map provides access to an attribute of type Map. They Keys are strings 51 | // and the values are DynamoDBAttributeValue instances. 52 | // Method panics if the attribute is not of type Map. 53 | func (av DynamoDBAttributeValue) Map() map[string]DynamoDBAttributeValue { 54 | av.ensureType(DataTypeMap) 55 | return av.value.(map[string]DynamoDBAttributeValue) 56 | } 57 | 58 | // Number provides access to an attribute of type Number. 59 | // DynamoDB sends the values as strings. For convenience please see also 60 | // the methods Integer() and Float(). 61 | // Method panics if the attribute is not of type Number. 62 | func (av DynamoDBAttributeValue) Number() string { 63 | av.ensureType(DataTypeNumber) 64 | return av.value.(string) 65 | } 66 | 67 | // Integer provides access to an attribute of type Number. 68 | // DynamoDB sends the values as strings. For convenience this method 69 | // provides conversion to int. If the value cannot be represented by 70 | // a signed integer, err.Err = ErrRange and the returned value is the maximum magnitude integer 71 | // of an int64 of the appropriate sign. 72 | // Method panics if the attribute is not of type Number. 73 | func (av DynamoDBAttributeValue) Integer() (int64, error) { 74 | s, err := strconv.ParseFloat(av.Number(), 64) 75 | return int64(s), err 76 | } 77 | 78 | // Float provides access to an attribute of type Number. 79 | // DynamoDB sends the values as strings. For convenience this method 80 | // provides conversion to float64. 81 | // The returned value is the nearest floating point number rounded using IEEE754 unbiased rounding. 82 | // If the number is more than 1/2 ULP away from the largest floating point number of the given size, 83 | // the value returned is ±Inf, err.Err = ErrRange. 84 | // Method panics if the attribute is not of type Number. 85 | func (av DynamoDBAttributeValue) Float() (float64, error) { 86 | s, err := strconv.ParseFloat(av.Number(), 64) 87 | return s, err 88 | } 89 | 90 | // NumberSet provides access to an attribute of type Number Set. 91 | // DynamoDB sends the numbers as strings. 92 | // Method panics if the attribute is not of type Number. 93 | func (av DynamoDBAttributeValue) NumberSet() []string { 94 | av.ensureType(DataTypeNumberSet) 95 | return av.value.([]string) 96 | } 97 | 98 | // String provides access to an attribute of type String. 99 | // Method panics if the attribute is not of type String. 100 | func (av DynamoDBAttributeValue) String() string { 101 | av.ensureType(DataTypeString) 102 | return av.value.(string) 103 | } 104 | 105 | // StringSet provides access to an attribute of type String Set. 106 | // Method panics if the attribute is not of type String Set. 107 | func (av DynamoDBAttributeValue) StringSet() []string { 108 | av.ensureType(DataTypeStringSet) 109 | return av.value.([]string) 110 | } 111 | 112 | // IsNull returns true if the attribute is of type Null. 113 | func (av DynamoDBAttributeValue) IsNull() bool { 114 | return av.value == nil 115 | } 116 | 117 | // DataType provides access to the DynamoDB type of the attribute 118 | func (av DynamoDBAttributeValue) DataType() DynamoDBDataType { 119 | return av.dataType 120 | } 121 | 122 | // NewBinaryAttribute creates an DynamoDBAttributeValue containing a Binary 123 | func NewBinaryAttribute(value []byte) DynamoDBAttributeValue { 124 | var av DynamoDBAttributeValue 125 | av.value = value 126 | av.dataType = DataTypeBinary 127 | return av 128 | } 129 | 130 | // NewBooleanAttribute creates an DynamoDBAttributeValue containing a Boolean 131 | func NewBooleanAttribute(value bool) DynamoDBAttributeValue { 132 | var av DynamoDBAttributeValue 133 | av.value = value 134 | av.dataType = DataTypeBoolean 135 | return av 136 | } 137 | 138 | // NewBinarySetAttribute creates an DynamoDBAttributeValue containing a BinarySet 139 | func NewBinarySetAttribute(value [][]byte) DynamoDBAttributeValue { 140 | var av DynamoDBAttributeValue 141 | av.value = value 142 | av.dataType = DataTypeBinarySet 143 | return av 144 | } 145 | 146 | // NewListAttribute creates an DynamoDBAttributeValue containing a List 147 | func NewListAttribute(value []DynamoDBAttributeValue) DynamoDBAttributeValue { 148 | var av DynamoDBAttributeValue 149 | av.value = value 150 | av.dataType = DataTypeList 151 | return av 152 | } 153 | 154 | // NewMapAttribute creates an DynamoDBAttributeValue containing a Map 155 | func NewMapAttribute(value map[string]DynamoDBAttributeValue) DynamoDBAttributeValue { 156 | var av DynamoDBAttributeValue 157 | av.value = value 158 | av.dataType = DataTypeMap 159 | return av 160 | } 161 | 162 | // NewNumberAttribute creates an DynamoDBAttributeValue containing a Number 163 | func NewNumberAttribute(value string) DynamoDBAttributeValue { 164 | var av DynamoDBAttributeValue 165 | av.value = value 166 | av.dataType = DataTypeNumber 167 | return av 168 | } 169 | 170 | // NewNullAttribute creates an DynamoDBAttributeValue containing a Null 171 | func NewNullAttribute() DynamoDBAttributeValue { 172 | var av DynamoDBAttributeValue 173 | av.dataType = DataTypeNull 174 | return av 175 | } 176 | 177 | // NewStringAttribute creates an DynamoDBAttributeValue containing a String 178 | func NewStringAttribute(value string) DynamoDBAttributeValue { 179 | var av DynamoDBAttributeValue 180 | av.value = value 181 | av.dataType = DataTypeString 182 | return av 183 | } 184 | 185 | // NewStringSetAttribute creates an DynamoDBAttributeValue containing a StringSet 186 | func NewStringSetAttribute(value []string) DynamoDBAttributeValue { 187 | var av DynamoDBAttributeValue 188 | av.value = value 189 | av.dataType = DataTypeStringSet 190 | return av 191 | } 192 | 193 | // DynamoDBDataType specifies the type supported natively by DynamoDB for an attribute 194 | type DynamoDBDataType int 195 | 196 | const ( 197 | DataTypeBinary DynamoDBDataType = iota 198 | DataTypeBoolean 199 | DataTypeBinarySet 200 | DataTypeList 201 | DataTypeMap 202 | DataTypeNumber 203 | DataTypeNumberSet 204 | DataTypeNull 205 | DataTypeString 206 | DataTypeStringSet 207 | ) 208 | 209 | type anyValue interface{} 210 | 211 | // UnsupportedDynamoDBTypeError is the error returned when trying to unmarshal a DynamoDB Attribute type not recognized by this library 212 | type UnsupportedDynamoDBTypeError struct { 213 | Type string 214 | } 215 | 216 | func (e UnsupportedDynamoDBTypeError) Error() string { 217 | return fmt.Sprintf("unsupported DynamoDB attribute type, %v", e.Type) 218 | } 219 | 220 | // IncompatibleDynamoDBTypeError is the error passed in a panic when calling an accessor for an incompatible type 221 | type IncompatibleDynamoDBTypeError struct { 222 | Requested DynamoDBDataType 223 | Actual DynamoDBDataType 224 | } 225 | 226 | func (e IncompatibleDynamoDBTypeError) Error() string { 227 | return fmt.Sprintf("accessor called for incompatible type, requested type %v but actual type was %v", e.Requested, e.Actual) 228 | } 229 | 230 | func (av *DynamoDBAttributeValue) ensureType(expectedType DynamoDBDataType) { 231 | if av.dataType != expectedType { 232 | panic(IncompatibleDynamoDBTypeError{Requested: expectedType, Actual: av.dataType}) 233 | } 234 | } 235 | 236 | // MarshalJSON implements custom marshaling to be used by the standard json/encoding package 237 | func (av DynamoDBAttributeValue) MarshalJSON() ([]byte, error) { 238 | 239 | var buff bytes.Buffer 240 | var err error 241 | var b []byte 242 | 243 | switch av.dataType { 244 | case DataTypeBinary: 245 | buff.WriteString(`{ "B":`) 246 | b, err = json.Marshal(av.value.([]byte)) 247 | buff.Write(b) 248 | 249 | case DataTypeBoolean: 250 | buff.WriteString(`{ "BOOL":`) 251 | b, err = json.Marshal(av.value.(bool)) 252 | buff.Write(b) 253 | 254 | case DataTypeBinarySet: 255 | buff.WriteString(`{ "BS":`) 256 | b, err = json.Marshal(av.value.([][]byte)) 257 | buff.Write(b) 258 | 259 | case DataTypeList: 260 | buff.WriteString(`{ "L":`) 261 | b, err = json.Marshal(av.value.([]DynamoDBAttributeValue)) 262 | buff.Write(b) 263 | 264 | case DataTypeMap: 265 | buff.WriteString(`{ "M":`) 266 | b, err = json.Marshal(av.value.(map[string]DynamoDBAttributeValue)) 267 | buff.Write(b) 268 | 269 | case DataTypeNumber: 270 | buff.WriteString(`{ "N":`) 271 | b, err = json.Marshal(av.value.(string)) 272 | buff.Write(b) 273 | 274 | case DataTypeNumberSet: 275 | buff.WriteString(`{ "NS":`) 276 | b, err = json.Marshal(av.value.([]string)) 277 | buff.Write(b) 278 | 279 | case DataTypeNull: 280 | buff.WriteString(`{ "NULL": true `) 281 | 282 | case DataTypeString: 283 | buff.WriteString(`{ "S":`) 284 | b, err = json.Marshal(av.value.(string)) 285 | buff.Write(b) 286 | 287 | case DataTypeStringSet: 288 | buff.WriteString(`{ "SS":`) 289 | b, err = json.Marshal(av.value.([]string)) 290 | buff.Write(b) 291 | } 292 | 293 | buff.WriteString(`}`) 294 | return buff.Bytes(), err 295 | } 296 | 297 | func unmarshalNull(target *DynamoDBAttributeValue) error { 298 | target.value = nil 299 | target.dataType = DataTypeNull 300 | return nil 301 | } 302 | 303 | func unmarshalString(target *DynamoDBAttributeValue, value interface{}) error { 304 | var ok bool 305 | target.value, ok = value.(string) 306 | target.dataType = DataTypeString 307 | if !ok { 308 | return errors.New("DynamoDBAttributeValue: S type should contain a string") 309 | } 310 | return nil 311 | } 312 | 313 | func unmarshalBinary(target *DynamoDBAttributeValue, value interface{}) error { 314 | stringValue, ok := value.(string) 315 | if !ok { 316 | return errors.New("DynamoDBAttributeValue: B type should contain a base64 string") 317 | } 318 | 319 | binaryValue, err := base64.StdEncoding.DecodeString(stringValue) 320 | if err != nil { 321 | return err 322 | } 323 | 324 | target.value = binaryValue 325 | target.dataType = DataTypeBinary 326 | return nil 327 | } 328 | 329 | func unmarshalBoolean(target *DynamoDBAttributeValue, value interface{}) error { 330 | booleanValue, ok := value.(bool) 331 | if !ok { 332 | return errors.New("DynamoDBAttributeValue: BOOL type should contain a boolean") 333 | } 334 | 335 | target.value = booleanValue 336 | target.dataType = DataTypeBoolean 337 | return nil 338 | } 339 | 340 | func unmarshalBinarySet(target *DynamoDBAttributeValue, value interface{}) error { 341 | list, ok := value.([]interface{}) 342 | if !ok { 343 | return errors.New("DynamoDBAttributeValue: BS type should contain a list of base64 strings") 344 | } 345 | 346 | binarySet := make([][]byte, len(list)) 347 | 348 | for index, element := range list { 349 | var err error 350 | elementString := element.(string) 351 | binarySet[index], err = base64.StdEncoding.DecodeString(elementString) 352 | if err != nil { 353 | return err 354 | } 355 | } 356 | 357 | target.value = binarySet 358 | target.dataType = DataTypeBinarySet 359 | return nil 360 | } 361 | 362 | func unmarshalList(target *DynamoDBAttributeValue, value interface{}) error { 363 | list, ok := value.([]interface{}) 364 | if !ok { 365 | return errors.New("DynamoDBAttributeValue: L type should contain a list") 366 | } 367 | 368 | DynamoDBAttributeValues := make([]DynamoDBAttributeValue, len(list)) 369 | for index, element := range list { 370 | 371 | elementMap, ok := element.(map[string]interface{}) 372 | if !ok { 373 | return errors.New("DynamoDBAttributeValue: element of a list is not an DynamoDBAttributeValue") 374 | } 375 | 376 | var elementDynamoDBAttributeValue DynamoDBAttributeValue 377 | err := unmarshalDynamoDBAttributeValueMap(&elementDynamoDBAttributeValue, elementMap) 378 | if err != nil { 379 | return errors.New("DynamoDBAttributeValue: unmarshal of child DynamoDBAttributeValue failed") 380 | } 381 | DynamoDBAttributeValues[index] = elementDynamoDBAttributeValue 382 | } 383 | target.value = DynamoDBAttributeValues 384 | target.dataType = DataTypeList 385 | return nil 386 | } 387 | 388 | func unmarshalMap(target *DynamoDBAttributeValue, value interface{}) error { 389 | m, ok := value.(map[string]interface{}) 390 | if !ok { 391 | return errors.New("DynamoDBAttributeValue: M type should contain a map") 392 | } 393 | 394 | DynamoDBAttributeValues := make(map[string]DynamoDBAttributeValue) 395 | for k, v := range m { 396 | 397 | elementMap, ok := v.(map[string]interface{}) 398 | if !ok { 399 | return errors.New("DynamoDBAttributeValue: element of a map is not an DynamoDBAttributeValue") 400 | } 401 | 402 | var elementDynamoDBAttributeValue DynamoDBAttributeValue 403 | err := unmarshalDynamoDBAttributeValueMap(&elementDynamoDBAttributeValue, elementMap) 404 | if err != nil { 405 | return errors.New("DynamoDBAttributeValue: unmarshal of child DynamoDBAttributeValue failed") 406 | } 407 | DynamoDBAttributeValues[k] = elementDynamoDBAttributeValue 408 | } 409 | target.value = DynamoDBAttributeValues 410 | target.dataType = DataTypeMap 411 | return nil 412 | } 413 | 414 | func unmarshalNumber(target *DynamoDBAttributeValue, value interface{}) error { 415 | var ok bool 416 | target.value, ok = value.(string) 417 | target.dataType = DataTypeNumber 418 | if !ok { 419 | return errors.New("DynamoDBAttributeValue: N type should contain a string") 420 | } 421 | return nil 422 | } 423 | 424 | func unmarshalNumberSet(target *DynamoDBAttributeValue, value interface{}) error { 425 | list, ok := value.([]interface{}) 426 | if !ok { 427 | return errors.New("DynamoDBAttributeValue: NS type should contain a list of strings") 428 | } 429 | 430 | numberSet := make([]string, len(list)) 431 | 432 | for index, element := range list { 433 | numberSet[index], ok = element.(string) 434 | if !ok { 435 | return errors.New("DynamoDBAttributeValue: NS type should contain a list of strings") 436 | } 437 | } 438 | 439 | target.value = numberSet 440 | target.dataType = DataTypeNumberSet 441 | return nil 442 | } 443 | 444 | func unmarshalStringSet(target *DynamoDBAttributeValue, value interface{}) error { 445 | list, ok := value.([]interface{}) 446 | if !ok { 447 | return errors.New("DynamoDBAttributeValue: SS type should contain a list of strings") 448 | } 449 | 450 | stringSet := make([]string, len(list)) 451 | 452 | for index, element := range list { 453 | stringSet[index], ok = element.(string) 454 | if !ok { 455 | return errors.New("DynamoDBAttributeValue: SS type should contain a list of strings") 456 | } 457 | } 458 | 459 | target.value = stringSet 460 | target.dataType = DataTypeStringSet 461 | return nil 462 | } 463 | 464 | func unmarshalDynamoDBAttributeValue(target *DynamoDBAttributeValue, typeLabel string, jsonValue interface{}) error { 465 | 466 | switch typeLabel { 467 | case "NULL": 468 | return unmarshalNull(target) 469 | case "B": 470 | return unmarshalBinary(target, jsonValue) 471 | case "BOOL": 472 | return unmarshalBoolean(target, jsonValue) 473 | case "BS": 474 | return unmarshalBinarySet(target, jsonValue) 475 | case "L": 476 | return unmarshalList(target, jsonValue) 477 | case "M": 478 | return unmarshalMap(target, jsonValue) 479 | case "N": 480 | return unmarshalNumber(target, jsonValue) 481 | case "NS": 482 | return unmarshalNumberSet(target, jsonValue) 483 | case "S": 484 | return unmarshalString(target, jsonValue) 485 | case "SS": 486 | return unmarshalStringSet(target, jsonValue) 487 | default: 488 | target.value = nil 489 | target.dataType = DataTypeNull 490 | return UnsupportedDynamoDBTypeError{typeLabel} 491 | } 492 | } 493 | 494 | // UnmarshalJSON unmarshals a JSON description of this DynamoDBAttributeValue 495 | func (av *DynamoDBAttributeValue) UnmarshalJSON(b []byte) error { 496 | var m map[string]interface{} 497 | 498 | err := json.Unmarshal(b, &m) 499 | if err != nil { 500 | return err 501 | } 502 | 503 | return unmarshalDynamoDBAttributeValueMap(av, m) 504 | } 505 | 506 | func unmarshalDynamoDBAttributeValueMap(target *DynamoDBAttributeValue, m map[string]interface{}) error { 507 | if m == nil { 508 | return errors.New("DynamoDBAttributeValue: does not contain a map") 509 | } 510 | 511 | if len(m) != 1 { 512 | return errors.New("DynamoDBAttributeValue: map must contain a single type") 513 | } 514 | 515 | for k, v := range m { 516 | return unmarshalDynamoDBAttributeValue(target, k, v) 517 | } 518 | 519 | return nil 520 | } 521 | --------------------------------------------------------------------------------