├── .github ├── ISSUE_TEMPLATE │ └── feature_request.md └── workflows │ ├── build-lambda-zip.yml │ ├── codeql-analysis.yml │ ├── lint.yml │ └── tests.yml ├── .gitignore ├── .golangci.yml ├── LICENSE ├── LICENSE-LAMBDACODE ├── LICENSE-SUMMARY ├── README.md ├── cfn ├── README.md ├── event.go ├── event_test.go ├── response.go ├── response_test.go ├── testdata │ └── cloudformation-event.json ├── wrap.go └── wrap_test.go ├── cmd └── build-lambda-zip │ ├── main.go │ ├── main_test.go │ └── testdata │ ├── apigw.go │ └── noop.go ├── events ├── README.md ├── README_ALBTargetGroupEvents.md ├── README_ApiGatewayCustomAuthorizer.md ├── README_ApiGatewayEvent.md ├── README_AutoScaling.md ├── README_Chime_Bots.md ├── README_ClientVPN.md ├── README_CloudWatch_Logs.md ├── README_CodeBuild.md ├── README_CodeCommit.md ├── README_CodeDeploy.md ├── README_Cognito.md ├── README_Cognito_UserPools_CustomAuthLambdaTriggers.md ├── README_Cognito_UserPools_PostConfirmation.md ├── README_Cognito_UserPools_PreAuthentication.md ├── README_Cognito_UserPools_PreSignup.md ├── README_Cognito_UserPools_PreTokenGen.md ├── README_Config.md ├── README_Connect.md ├── README_DynamoDB.md ├── README_ECS_ContainerInstance.md ├── README_EventBridge_Events.md ├── README_Kinesis.md ├── README_KinesisDataAnalytics.md ├── README_KinesisFirehose.md ├── README_Lambda.md ├── README_Lex.md ├── README_S3.md ├── README_S3_Batch_Job.md ├── README_S3_Object_Lambda.md ├── README_SES.md ├── README_SNS.md ├── README_SQS.md ├── README_SecretsManager_SecretRotationEvent.md ├── activemq.go ├── activemq_test.go ├── alb.go ├── alb_test.go ├── apigw.go ├── apigw_test.go ├── appsync.go ├── appsync_test.go ├── attributevalue.go ├── attributevalue_test.go ├── autoscaling.go ├── autoscaling_test.go ├── chime_bot.go ├── chime_bot_test.go ├── clientvpn.go ├── clientvpn_test.go ├── cloudwatch_events.go ├── cloudwatch_events_test.go ├── cloudwatch_logs.go ├── cloudwatch_logs_test.go ├── code_commit.go ├── code_commit_test.go ├── codebuild.go ├── codebuild_test.go ├── codedeploy.go ├── codedeploy_test.go ├── codepipeline.go ├── codepipeline_cloudwatch.go ├── codepipeline_cloudwatch_test.go ├── codepipeline_job.go ├── codepipeline_job_test.go ├── codepipeline_test.go ├── cognito.go ├── cognito_test.go ├── config.go ├── config_test.go ├── connect.go ├── connect_test.go ├── duration.go ├── dynamodb.go ├── dynamodb_test.go ├── ecr_image_action.go ├── ecr_image_action_test.go ├── ecr_scan.go ├── ecr_scan_test.go ├── ecs_container_instance.go ├── ecs_container_instance_test.go ├── epoch_time.go ├── epoch_time_test.go ├── firehose.go ├── firehose_test.go ├── iam.go ├── iot.go ├── iot_1_click.go ├── iot_1_click_test.go ├── iot_button.go ├── iot_button_test.go ├── iot_deprecated.go ├── iot_preprovision_hook.go ├── iot_preprovision_hook_test.go ├── iot_test.go ├── kafka.go ├── kafka_test.go ├── kinesis.go ├── kinesis_analytics.go ├── kinesis_analytics_test.go ├── kinesis_test.go ├── lambda_function_urls.go ├── lambda_function_urls_test.go ├── lex.go ├── lex_test.go ├── rabbitmq.go ├── rabbitmq_test.go ├── s3.go ├── s3_batch_job.go ├── s3_batch_job_test.go ├── s3_object_lambda.go ├── s3_object_lambda_test.go ├── s3_test.go ├── secretsmanager.go ├── secretsmanager_test.go ├── ses.go ├── ses_test.go ├── sns.go ├── sns_test.go ├── sqs.go ├── sqs_test.go ├── streams.go ├── test │ ├── assert.go │ ├── jsonblobs.go │ ├── jsoncompare.go │ ├── jsonsyntax.go │ └── readjson.go ├── testdata │ ├── activemq-event.json │ ├── alb-lambda-target-request-headers-only.json │ ├── alb-lambda-target-request-multivalue-headers.json │ ├── alb-lambda-target-response.json │ ├── apigw-custom-auth-request-type-request.json │ ├── apigw-custom-auth-request.json │ ├── apigw-custom-auth-response.json │ ├── apigw-request.json │ ├── apigw-response.json │ ├── apigw-restapi-openapi-request.json │ ├── apigw-v2-custom-authorizer-v1-request.json │ ├── apigw-v2-custom-authorizer-v2-request.json │ ├── apigw-v2-request-iam.json │ ├── apigw-v2-request-jwt-authorizer.json │ ├── apigw-v2-request-lambda-authorizer.json │ ├── apigw-v2-request-no-authorizer.json │ ├── apigw-websocket-request-disconnect.json │ ├── apigw-websocket-request-send-message.json │ ├── apigw-websocket-request.json │ ├── appsync-identity-cognito.json │ ├── appsync-identity-iam.json │ ├── appsync-lambda-auth-request.json │ ├── appsync-lambda-auth-response.json │ ├── autoscaling-event-launch-successful.json │ ├── autoscaling-event-launch-unsuccessful.json │ ├── autoscaling-event-lifecycle-action.json │ ├── autoscaling-event-terminate-action.json │ ├── autoscaling-event-terminate-successful.json │ ├── autoscaling-event-terminate-unsuccessful.json │ ├── clientvpn-connectionhandler-request.json │ ├── cloudwatch-alarm-sns-payload-multiple-metrics.json │ ├── cloudwatch-alarm-sns-payload-single-metric.json │ ├── cloudwatch-logs-event.json │ ├── code-commit-event.json │ ├── codebuild-phase-change.json │ ├── codebuild-state-change.json │ ├── codedeploy-deployment-event.json │ ├── codedeploy-instance-event.json │ ├── codepipeline-action-execution-stage-change-event.json │ ├── codepipeline-execution-stage-change-event.json │ ├── codepipeline-execution-state-change-event.json │ ├── codepipeline-job-event.json │ ├── cognito-event-userpools-create-auth-challenge.json │ ├── cognito-event-userpools-custommessage.json │ ├── cognito-event-userpools-define-auth-challenge.json │ ├── cognito-event-userpools-migrateuser.json │ ├── cognito-event-userpools-postauthentication.json │ ├── cognito-event-userpools-postconfirmation.json │ ├── cognito-event-userpools-preauthentication.json │ ├── cognito-event-userpools-presignup.json │ ├── cognito-event-userpools-pretokengen-v2.json │ ├── cognito-event-userpools-pretokengen-v2_0.json │ ├── cognito-event-userpools-pretokengen.json │ ├── cognito-event-userpools-verify-auth-challenge.json │ ├── cognito-event.json │ ├── config-event.json │ ├── connect-event.json │ ├── dynamodb-event-malformed.2.json │ ├── dynamodb-event.json │ ├── dynamodb-time-window-event.json │ ├── ecr-image-push-event.json │ ├── ecr-image-scan-event.json │ ├── ecs-container-instance-state-change.json │ ├── iot-1-click-event.json │ ├── iot-button-event.json │ ├── iot-custom-auth-request.json │ ├── iot-custom-auth-response.json │ ├── iot-preprovision-hook-request.json │ ├── iot-preprovision-hook-response.json │ ├── kafka-event.json │ ├── kinesis-analytics-output-delivery-event.json │ ├── kinesis-analytics-output-delivery-response.json │ ├── kinesis-event.json │ ├── kinesis-firehose-event.json │ ├── kinesis-firehose-response.json │ ├── kinesis-time-window-event.json │ ├── lambda-urls-request.json │ ├── lambda-urls-response.json │ ├── lex-event.json │ ├── lex-response.json │ ├── rabbitmq-event.json │ ├── s3-batch-job-event-request-1.0.json │ ├── s3-batch-job-event-request-2.0.json │ ├── s3-batch-job-event-response.json │ ├── s3-event-with-decoded.json │ ├── s3-event.json │ ├── s3-object-lambda-event-get-object-assumed-role.json │ ├── s3-object-lambda-event-get-object-iam.json │ ├── s3-object-lambda-event-head-object-iam.json │ ├── s3-object-lambda-event-list-objects-iam.json │ ├── s3-object-lambda-event-list-objects-v2-iam.json │ ├── secretsmanager-secret-rotation-event.json │ ├── ses-lambda-event.json │ ├── ses-s3-event.json │ ├── ses-sns-event.json │ ├── sns-event.json │ └── sqs-event.json └── time_window.go ├── go.mod ├── go.sum ├── lambda ├── README.md ├── entry.go ├── entry_generic.go ├── entry_generic_test.go ├── entry_test.go ├── entry_with_no_rpc_test.go ├── entry_with_rpc_test.go ├── errors.go ├── extensions_api_client.go ├── handler.go ├── handler_test.go ├── handlertrace │ ├── trace.go │ └── trace_test.go ├── invoke_loop.go ├── invoke_loop_test.go ├── messages │ ├── README.md │ └── messages.go ├── panic.go ├── panic_test.go ├── rpc_function.go ├── rpc_function_test.go ├── runtime_api_client.go ├── runtime_api_client_test.go ├── sigterm.go ├── sigterm_test.go └── testdata │ ├── .gitignore │ ├── bench.sh │ ├── echo_handler.go │ └── sigterm.go ├── lambdacontext ├── README.md └── context.go └── lambdaurl ├── http_handler.go ├── http_handler_test.go └── testdata ├── function-url-domain-only-get-request-trailing-slash.json ├── function-url-domain-only-get-request.json ├── function-url-domain-only-request-with-base64-encoded-body.json ├── function-url-request-with-headers-and-cookies-and-text-body.json ├── gen-events.sh ├── lambdaurl.go └── testfunc ├── .gitignore ├── echo └── main.go ├── go.mod ├── go.sum ├── site └── main.go └── template.yaml /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/build-lambda-zip.yml: -------------------------------------------------------------------------------- 1 | name: go get build-lambda-zip 2 | on: 3 | push: 4 | branches: 5 | - master 6 | schedule: 7 | - cron: "7 7 * * *" 8 | 9 | jobs: 10 | thejob: 11 | runs-on: ${{ matrix.platform }} 12 | name: install build-lambda-zip on ${{ matrix.platform }} 13 | strategy: 14 | matrix: 15 | go-version: [1.12, 1.13] 16 | platform: [ubuntu-latest, macos-latest, windows-latest] 17 | steps: 18 | - name: Setup Go 19 | uses: actions/setup-go@v3 20 | with: 21 | go-version: ${{ matrix.go-version }} 22 | 23 | - name: go get 24 | env: 25 | GOPROXY: direct 26 | GO111MODULE: on 27 | run: | 28 | go env 29 | go get -u github.com/aws/aws-lambda-go/cmd/build-lambda-zip 30 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | on: 3 | push: 4 | pull_request: 5 | 6 | permissions: 7 | # Required: allow read access to the content for analysis. 8 | contents: read 9 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 10 | pull-requests: read 11 | # Optional: allow write access to checks to allow the action to annotate code in the PR. 12 | checks: write 13 | 14 | jobs: 15 | lint: 16 | name: run golangci-golint on the project 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: actions/setup-go@v5 21 | with: 22 | go-version: 'stable' 23 | - name: golangci-golint 24 | uses: golangci/golangci-lint-action@v6 25 | with: 26 | version: v1.64.5 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Go Dep 2 | vendor 3 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | disable-all: true 3 | enable: 4 | - gofmt 5 | - errcheck 6 | - gosimple 7 | - govet 8 | - ineffassign 9 | - staticcheck 10 | - typecheck 11 | - unused 12 | - stylecheck 13 | 14 | issues: 15 | exclude-dirs: 16 | # These were code-generated, and cannot be changed without breaking RPC compatibility. 17 | - lambda/messages 18 | 19 | linters-settings: 20 | staticcheck: 21 | checks: 22 | - all 23 | - '-SA1029' 24 | stylecheck: 25 | checks: 26 | - "all" 27 | initialisms: 28 | - "ACL" 29 | - "AMQP" 30 | - "API" 31 | - "ARN" 32 | - "ASCII" 33 | - "AWS" 34 | - "CPU" 35 | - "CSS" 36 | - "DB" 37 | - "DNS" 38 | - "EOF" 39 | - "GID" 40 | - "GUID" 41 | - "HTML" 42 | - "HTTP" 43 | - "HTTPS" 44 | - "IAM" 45 | - "ID" 46 | - "IP" 47 | - "JSON" 48 | - "MQTT" 49 | - "OTF" 50 | - "QPS" 51 | - "RAM" 52 | - "RPC" 53 | - "RTP" 54 | - "SIP" 55 | - "SLA" 56 | - "SMTP" 57 | - "SQL" 58 | - "SSH" 59 | - "TCP" 60 | - "TLS" 61 | - "TS" 62 | - "TTL" 63 | - "UDP" 64 | - "UI" 65 | - "UID" 66 | - "URI" 67 | - "URL" 68 | - "UTF8" 69 | - "UUID" 70 | - "VM" 71 | - "VPC" 72 | - "XML" 73 | - "XMPP" 74 | - "XSRF" 75 | - "XSS" 76 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cfn/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | CloudFormation has a different way of responding to most events due to the way stacks execute. 4 | 5 | It is best to catch all errors and ensure the correct response is sent to the pre-signed URL that comes with the event. 6 | 7 | To make this easier, a wrapper exists to allow the creation of custom resources without having to handle that. 8 | 9 | # Sample Function 10 | 11 | This sample will safely 'Echo' back anything given into the Echo parameter within the Custom Resource call. 12 | 13 | ```go 14 | 15 | import ( 16 | "context" 17 | "fmt" 18 | 19 | "github.com/aws/aws-lambda-go/cfn" 20 | "github.com/aws/aws-lambda-go/lambda" 21 | ) 22 | 23 | func echoResource(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { 24 | v, _ := event.ResourceProperties["Echo"].(string) 25 | 26 | data = map[string]interface{} { 27 | "Echo": v, 28 | } 29 | 30 | return 31 | } 32 | 33 | func main() { 34 | lambda.Start(cfn.LambdaWrap(echoResource)) 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /cfn/event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package cfn 4 | 5 | // RequestType represents the types of requests that 6 | // come from a CloudFormation stack being run 7 | type RequestType string 8 | 9 | const ( 10 | RequestCreate RequestType = "Create" 11 | RequestUpdate RequestType = "Update" 12 | RequestDelete RequestType = "Delete" 13 | ) 14 | 15 | // Event is a representation of a Custom Resource 16 | // request 17 | type Event struct { 18 | RequestType RequestType `json:"RequestType"` 19 | RequestID string `json:"RequestId"` 20 | ResponseURL string `json:"ResponseURL"` 21 | ResourceType string `json:"ResourceType"` 22 | PhysicalResourceID string `json:"PhysicalResourceId,omitempty"` 23 | LogicalResourceID string `json:"LogicalResourceId"` 24 | StackID string `json:"StackId"` 25 | ResourceProperties map[string]interface{} `json:"ResourceProperties"` 26 | OldResourceProperties map[string]interface{} `json:"OldResourceProperties,omitempty"` 27 | } 28 | -------------------------------------------------------------------------------- /cfn/event_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package cfn 4 | 5 | import ( 6 | "encoding/json" 7 | "io/ioutil" //nolint: staticcheck 8 | "testing" 9 | 10 | "github.com/aws/aws-lambda-go/events/test" 11 | ) 12 | 13 | func TestCloudFormationEventMarshaling(t *testing.T) { 14 | 15 | // read json from file 16 | inputJSON, err := ioutil.ReadFile("./testdata/cloudformation-event.json") 17 | if err != nil { 18 | t.Errorf("could not open test file. details: %v", err) 19 | } 20 | 21 | // de-serialize into Event 22 | var inputEvent Event 23 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 24 | t.Errorf("could not unmarshal event. details: %v", err) 25 | } 26 | 27 | // serialize to json 28 | outputJSON, err := json.Marshal(inputEvent) 29 | if err != nil { 30 | t.Errorf("could not marshal event. details: %v", err) 31 | } 32 | 33 | test.AssertJsonsEqual(t, inputJSON, outputJSON) 34 | } 35 | 36 | func TestCloudFormationMarshalingMalformedJson(t *testing.T) { 37 | test.TestMalformedJson(t, Event{}) 38 | } 39 | -------------------------------------------------------------------------------- /cfn/testdata/cloudformation-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "RequestType" : "Create", 3 | "ResponseURL" : "http://pre-signed-S3-url-for-response", 4 | "StackId" : "arn:aws:cloudformation:us-west-2:EXAMPLE/stack-name/guid", 5 | "RequestId" : "unique id for this create request", 6 | "ResourceType" : "Custom::TestResource", 7 | "LogicalResourceId" : "MyTestResource", 8 | "ResourceProperties" : { 9 | "Name" : "Value", 10 | "List" : [ "1", "2", "3" ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /cmd/build-lambda-zip/testdata/apigw.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "github.com/aws/aws-lambda-go/events" 9 | "github.com/aws/aws-lambda-go/lambda" 10 | ) 11 | 12 | func main() { 13 | lambda.Start(func(ctx context.Context, event events.APIGatewayV2HTTPRequest) (*events.APIGatewayProxyResponse, error) { 14 | return &events.APIGatewayProxyResponse{ 15 | Body: fmt.Sprintf("Hello %v", event), 16 | }, nil 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /cmd/build-lambda-zip/testdata/noop.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | "github.com/aws/aws-lambda-go/lambda" 8 | ) 9 | 10 | type BinaryHandler func(context.Context, []byte) ([]byte, error) 11 | 12 | func (bh BinaryHandler) Invoke(ctx context.Context, req []byte) ([]byte, error) { 13 | return bh(ctx, req) 14 | } 15 | 16 | func noop(ctx context.Context, req []byte) ([]byte, error) { 17 | return req, nil 18 | } 19 | 20 | func main() { 21 | lambda.StartHandler(BinaryHandler(noop)) 22 | } 23 | -------------------------------------------------------------------------------- /events/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/aws/aws-lambda-go/events.svg)](https://pkg.go.dev/github.com/aws/aws-lambda-go/events) 4 | 5 | This package provides input types for Lambda functions that process AWS events. 6 | 7 | # Samples 8 | 9 | [ALB Target Group Events](README_ALBTargetGroupEvents.md) 10 | 11 | [API Gateway](README_ApiGatewayEvent.md) 12 | 13 | [API Gateway Custom Authorizer](README_ApiGatewayCustomAuthorizer.md) 14 | 15 | [AppSync](README_AppSync.md) 16 | 17 | [AutoScaling](README_AutoScaling.md) 18 | 19 | [ClientVPN Connection Handler](README_ClientVPN.md) 20 | 21 | [CloudFormation Events](../cfn/README.md) 22 | 23 | [CloudWatch Events](README_CloudWatch_Events.md) 24 | 25 | [CloudWatch Logs](README_CloudWatch_Logs.md) 26 | 27 | [Chime Bot Events](README_Chime_Bots.md) 28 | 29 | [CodeBuild Events](README_CodeBuild.md) 30 | 31 | [CodeCommit Events](README_CodeCommit.md) 32 | 33 | [CodeDeploy Events](README_CodeDeploy.md) 34 | 35 | [Cognito Events](README_Cognito.md) 36 | 37 | [Cognito Custom Authentication](README_Cognito_UserPools_CustomAuthLambdaTriggers.md) 38 | 39 | [Cognito PostConfirmation](README_Cognito_UserPools_PostConfirmation.md) 40 | 41 | [Cognito PreAuthentication](README_Cognito_UserPools_PreAuthentication.md) 42 | 43 | [Cognito PreSignup](README_Cognito_UserPools_PreSignup.md) 44 | 45 | [Cognito PreTokenGen](README_Cognito_UserPools_PreTokenGen.md) 46 | 47 | [Config Events](README_Config.md) 48 | 49 | [Connect Events](README_Connect.md) 50 | 51 | [DynamoDB Events](README_DynamoDB.md) 52 | 53 | [Kinesis Events](README_Kinesis.md) 54 | 55 | [Kinesis Data Analytics Events](README_KinesisDataAnalytics.md) 56 | 57 | [Kinesis Firehose Events](README_KinesisFirehose.md) 58 | 59 | [Lambda Events](README_Lambda.md) 60 | 61 | [Lex Events](README_Lex.md) 62 | 63 | [S3 Events](README_S3.md) 64 | 65 | [S3 Batch Job Events](README_S3_Batch_Job.md) 66 | 67 | [SES Events](README_SES.md) 68 | 69 | [SNS Events](README_SNS.md) 70 | 71 | [SQS Events](README_SQS.md) 72 | -------------------------------------------------------------------------------- /events/README_ALBTargetGroupEvents.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | ALB Target Group events consist of a request that was routed to a Lambda function which is a registered target of an Application Load Balancer Target Group. When this happens, ALB expects the result of the function to be the response that ALB should respond with. 4 | 5 | https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html 6 | 7 | # Sample Function 8 | 9 | The following is a sample class and Lambda function that receives an ALB Target Group event as an input, writes some of the incoming data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 10 | 11 | ```go 12 | 13 | package main 14 | 15 | import ( 16 | "context" 17 | "fmt" 18 | 19 | "github.com/aws/aws-lambda-go/events" 20 | "github.com/aws/aws-lambda-go/lambda" 21 | ) 22 | 23 | func handleRequest(ctx context.Context, request events.ALBTargetGroupRequest) (events.ALBTargetGroupResponse, error) { 24 | fmt.Printf("Processing request data for traceId %s.\n", request.Headers["x-amzn-trace-id"]) 25 | fmt.Printf("Body size = %d.\n", len(request.Body)) 26 | 27 | fmt.Println("Headers:") 28 | for key, value := range request.Headers { 29 | fmt.Printf(" %s: %s\n", key, value) 30 | } 31 | 32 | return events.ALBTargetGroupResponse{Body: request.Body, StatusCode: 200, StatusDescription: "200 OK", IsBase64Encoded: false, Headers: map[string]string{}}, nil 33 | } 34 | 35 | func main() { 36 | lambda.Start(handleRequest) 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /events/README_ApiGatewayEvent.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | API Gateway events consist of a request that was routed to a Lambda function by API Gateway. When this happens, API Gateway expects the result of the function to be the response that API Gateway should respond with. 4 | 5 | # Sample Function 6 | 7 | The following is a sample class and Lambda function that receives Amazon API Gateway event record data as an input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 8 | 9 | ```go 10 | 11 | package main 12 | 13 | import ( 14 | "context" 15 | "fmt" 16 | 17 | "github.com/aws/aws-lambda-go/events" 18 | "github.com/aws/aws-lambda-go/lambda" 19 | ) 20 | 21 | func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { 22 | fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) 23 | fmt.Printf("Body size = %d.\n", len(request.Body)) 24 | 25 | fmt.Println("Headers:") 26 | for key, value := range request.Headers { 27 | fmt.Printf(" %s: %s\n", key, value) 28 | } 29 | 30 | return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil 31 | } 32 | 33 | func main() { 34 | lambda.Start(handleRequest) 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /events/README_AutoScaling.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives an Auto Scaling event as an input and logs the EC2 instance ID to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | "github.com/aws/aws-lambda-go/events" 11 | "github.com/aws/aws-lambda-go/lambda" 12 | ) 13 | 14 | func handler(ctx context.Context, autoScalingEvent events.AutoScalingEvent) { 15 | fmt.Printf("Instance-Id available in event is %s \n", autoScalingEvent.Detail["EC2InstanceId"]) 16 | } 17 | 18 | func main() { 19 | lambda.Start(handler) 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /events/README_ClientVPN.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives a Client VPN connection handler request as an input and then validates the IP address input and checks whether the connection source IP is on the allowed list defined as a map inside the function. If the source IP matches an allowed IP address it allows the access, otherwise an error message is presented to the user. Debug logs are generated to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | import ( 7 | "fmt" 8 | "log" 9 | "net" 10 | 11 | "encoding/json" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | var ( 18 | AllowedIPs = map[string]bool{ 19 | "10.11.12.13": true, 20 | } 21 | ) 22 | 23 | func handler(request events.ClientVPNConnectionHandlerRequest) (events.ClientVPNConnectionHandlerResponse, error) { 24 | requestJson, _ := json.MarshalIndent(request, "", " ") 25 | log.Printf("REQUEST: %s", requestJson) 26 | 27 | sourceIP := request.PublicIP 28 | if net.ParseIP(sourceIP) == nil { 29 | return events.ClientVPNConnectionHandlerResponse{}, fmt.Errorf("Invalid parameter PublicIP passed in request: %q", sourceIP) 30 | } 31 | 32 | log.Printf("SOURCE IP: %q", sourceIP) 33 | 34 | if allowed, ok := AllowedIPs[sourceIP]; ok && allowed { 35 | log.Printf("Allowing access from: %q", sourceIP) 36 | return events.ClientVPNConnectionHandlerResponse{ 37 | Allow: true, 38 | ErrorMsgOnFailedPostureCompliance: "", 39 | PostureComplianceStatuses: []string{}, 40 | SchemaVersion: "v1", 41 | }, nil 42 | } 43 | 44 | log.Printf("Blocking access from: %q", sourceIP) 45 | return events.ClientVPNConnectionHandlerResponse{ 46 | Allow: false, 47 | ErrorMsgOnFailedPostureCompliance: "You're trying to connect from an IP address that is not allowed.", 48 | PostureComplianceStatuses: []string{"BlockedSourceIP"}, 49 | SchemaVersion: "v1", 50 | }, nil 51 | } 52 | 53 | func main() { 54 | lambda.Start(handler) 55 | } 56 | ``` 57 | -------------------------------------------------------------------------------- /events/README_CloudWatch_Logs.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a Lambda function that receives Amazon CloudWatch Logs event record data as input and writes message part to Lambda's CloudWatch Logs. Note that by default anything written to Console will be logged as CloudWatch Logs events. 5 | 6 | ```go 7 | import ( 8 | "context" 9 | "fmt" 10 | 11 | "github.com/aws/aws-lambda-go/events" 12 | ) 13 | 14 | func handler(ctx context.Context, logsEvent events.CloudwatchLogsEvent) { 15 | data, _ := logsEvent.AWSLogs.Parse() 16 | for _, logEvent := range data.LogEvents { 17 | fmt.Printf("Message = %s\n", logEvent.Message) 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /events/README_CodeBuild.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives an Amazon CodeBuild event 4 | and writes it to standard output. 5 | 6 | ```go 7 | import ( 8 | "fmt" 9 | "github.com/aws/aws-lambda-go/events" 10 | ) 11 | 12 | func handleRequest(evt events.CodeBuildEvent) { 13 | fmt.Println(evt) 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /events/README_CodeCommit.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon CodeCommit event 4 | records input and prints them to `os.Stdout`.) 5 | 6 | ```go 7 | import ( 8 | "fmt" 9 | "github.com/aws/aws-lambda-go/events" 10 | ) 11 | 12 | func handleRequest(evt events.CodeCommitEvent) { 13 | for _, record := range evt.Records { 14 | fmt.Println(record) 15 | } 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /events/README_CodeDeploy.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives an Amazon CodeDeploy event 4 | and writes it to standard output. 5 | 6 | ```go 7 | import ( 8 | "fmt" 9 | "github.com/aws/aws-lambda-go/events" 10 | ) 11 | 12 | func handleRequest(evt events.CodeDeployEvent) { 13 | fmt.Println(evt) 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /events/README_Cognito.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Cognito Sync event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | 12 | "github.com/aws/aws-lambda-go/lambda" 13 | "github.com/aws/aws-lambda-go/events" 14 | ) 15 | 16 | func handler(cognitoEvent events.CognitoEvent) error { 17 | for datasetName, datasetRecord := range cognitoEvent.DatasetRecords { 18 | fmt.Printf("[%s -- %s] %s -> %s -> %s \n", 19 | cognitoEvent.EventType, 20 | datasetName, 21 | datasetRecord.OldValue, 22 | datasetRecord.Op, 23 | datasetRecord.NewValue) 24 | } 25 | return nil 26 | } 27 | 28 | func main() { 29 | lambda.Start(handler) 30 | } 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /events/README_Cognito_UserPools_PostConfirmation.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Cognito User Pools post-confirmation event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/lambda" 14 | "github.com/aws/aws-lambda-go/events" 15 | ) 16 | 17 | func handler(event events.CognitoEventUserPoolsPostConfirmation) (events.CognitoEventUserPoolsPostConfirmation, error) { 18 | fmt.Printf("PostConfirmation for user: %s\n", event.UserName) 19 | return event, nil 20 | } 21 | 22 | func main() { 23 | lambda.Start(handler) 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /events/README_Cognito_UserPools_PreAuthentication.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Cognito User Pools pre-authentication event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/lambda" 14 | "github.com/aws/aws-lambda-go/events" 15 | ) 16 | 17 | func handler(event events.CognitoEventUserPoolsPreAuthentication) (events.CognitoEventUserPoolsPreAuthentication, error) { 18 | fmt.Printf("PreAuthentication of user: %s\n", event.UserName) 19 | return event, nil 20 | } 21 | 22 | func main() { 23 | lambda.Start(handler) 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /events/README_Cognito_UserPools_PreSignup.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Cognito User Pools pre-signup event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | // handler is the lambda handler invoked by the `lambda.Start` function call 18 | func handler(event events.CognitoEventUserPoolsPreSignup) (events.CognitoEventUserPoolsPreSignup, error) { 19 | fmt.Printf("PreSignup of user: %s\n", event.UserName) 20 | event.Response.AutoConfirmUser = true 21 | return event, nil 22 | } 23 | 24 | func main() { 25 | lambda.Start(handler) 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /events/README_Cognito_UserPools_PreTokenGen.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Cognito User Pools pre-token-gen event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/lambda" 14 | "github.com/aws/aws-lambda-go/events" 15 | ) 16 | 17 | func handler(event events.CognitoEventUserPoolsPreTokenGen) (events.CognitoEventUserPoolsPreTokenGen, error) { 18 | fmt.Printf("PreTokenGen of user: %s\n", event.UserName) 19 | event.Response.ClaimsOverrideDetails.ClaimsToSuppress = []string{"family_name"} 20 | return event, nil 21 | } 22 | 23 | func main() { 24 | lambda.Start(handler) 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /events/README_Config.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives Amazon Config event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | import ( 8 | "strings" 9 | "github.com/aws/aws-lambda-go/events" 10 | ) 11 | 12 | func handleRequest(ctx context.Context, configEvent events.ConfigEvent) { 13 | fmt.Printf("AWS Config rule: %s\n", configEvent.ConfigRuleName) 14 | fmt.Printf("Invoking event JSON: %s\n", configEvent.InvokingEvent) 15 | fmt.Printf("Event version: %s\n", configEvent.Version) 16 | } 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /events/README_Connect.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that receives an Amazon Connect event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | 12 | "github.com/aws/aws-lambda-go/events" 13 | "github.com/aws/aws-lambda-go/lambda" 14 | ) 15 | 16 | func main() { 17 | lambda.Start(handler) 18 | } 19 | 20 | func handler(ctx context.Context, connectEvent events.ConnectEvent) (events.ConnectResponse, error) { 21 | fmt.Printf("Processing Connect event with ContactID %s.\n", connectEvent.Details.ContactData.ContactID) 22 | 23 | fmt.Printf("Invoked with %d parameters\n", len(connectEvent.Details.Parameters)) 24 | for k, v := range connectEvent.Details.Parameters { 25 | fmt.Printf("%s : %s\n", k, v) 26 | } 27 | 28 | resp := events.ConnectResponse{ 29 | "Result": "Success", 30 | "NewAttribute": "NewValue", 31 | } 32 | 33 | return resp, nil 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /events/README_ECS_ContainerInstance.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample class and Lambda function that receives Amazon ECS Container instance state change events record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | package main 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | func handler(ctx context.Context, ecsEvent events.ECSContainerInstanceEvent) { 18 | outputJSON, _ := json.MarshalIndent(ecsEvent, "", " ") 19 | fmt.Printf("Data = %s", outputJSON) 20 | } 21 | 22 | func main() { 23 | lambda.Start(handler) 24 | } 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /events/README_EventBridge_Events.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a Lambda function that receives Amazon EventBridge event record data as input and writes event detail to Lambda's CloudWatch Logs. Note that by default anything written to Console will be logged as CloudWatch Logs events. 5 | 6 | ```go 7 | import ( 8 | "context" 9 | "fmt" 10 | 11 | "github.com/aws/aws-lambda-go/events" 12 | ) 13 | 14 | func handler(ctx context.Context, event events.EventBridgeEvent) { 15 | fmt.Printf("Detail = %s\n", event.Detail) 16 | } 17 | ``` 18 | 19 | ## CloudWatch Scheduled Events 20 | 21 | If you have a constant JSON text in a CloudWatch Scheduled Event, it can be accessed either by explicitly defining a structure for the json payload you would expect: 22 | 23 | ```go 24 | type MyRequest struct { 25 | Name string `json:"name"` 26 | } 27 | 28 | func handler(ctx context.Context, req MyRequest) { 29 | } 30 | ``` 31 | 32 | or by accepting raw json blob as is: 33 | 34 | ```go 35 | func handler(ctx context.Context, b json.RawMessage) { 36 | // json.RawMessage is basically []byte which can be unmarshalled 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /events/README_Kinesis.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample class and Lambda function that receives Amazon Kinesis event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | package main 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | func handler(ctx context.Context, kinesisEvent events.KinesisEvent) error { 18 | for _, record := range kinesisEvent.Records { 19 | kinesisRecord := record.Kinesis 20 | dataBytes := kinesisRecord.Data 21 | dataText := string(dataBytes) 22 | 23 | fmt.Printf("%s Data = %s \n", record.EventName, dataText) 24 | } 25 | 26 | return nil 27 | } 28 | 29 | func main() { 30 | lambda.Start(handler) 31 | } 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /events/README_KinesisDataAnalytics.md: -------------------------------------------------------------------------------- 1 | # Sample function 2 | 3 | The following is an example for an Application Destination Lambda function that receives Amazon Kinesis Data Analytics event records as an input. To send Kinesis Data Analytics output records the Lambda function must be compliant with the (required input and return data models)[https://docs.aws.amazon.com/kinesisanalytics/latest/dev/how-it-works-output-lambda.html], so the handler returns a list of delivery statuses for each record. 4 | 5 | The following Lambda function receives Amazon Kinesis Data Analytics event record data as an input and writes some of the record data to CloudWatch Logs. For each entry it adds an element to the response slice, marking it delivered. When the logic considers the delivery to be failed the `events.KinesisAnalyticsOutputDeliveryFailed` value should be used for the response `Result` field. 6 | 7 | 8 | ```go 9 | package main 10 | 11 | import ( 12 | "context" 13 | "encoding/json" 14 | "fmt" 15 | "log" 16 | 17 | "github.com/aws/aws-lambda-go/events" 18 | "github.com/aws/aws-lambda-go/lambda" 19 | ) 20 | 21 | func handler(ctx context.Context, kinesisAnalyticsEvent events.KinesisAnalyticsOutputDeliveryEvent) (events.KinesisAnalyticsOutputDeliveryResponse, error) { 22 | var err error 23 | 24 | var responses events.KinesisAnalyticsOutputDeliveryResponse 25 | responses.Records = make([]events.KinesisAnalyticsOutputDeliveryResponseRecord, len(kinesisAnalyticsEvent.Records)) 26 | 27 | for i, record := range kinesisAnalyticsEvent.Records { 28 | responses.Records[i] = events.KinesisAnalyticsOutputDeliveryResponseRecord{ 29 | RecordID: record.RecordID, 30 | Result: events.KinesisAnalyticsOutputDeliveryOK, 31 | } 32 | 33 | dataBytes := record.Data 34 | dataText := string(dataBytes) 35 | 36 | fmt.Printf("%s Data = %s \n", record.RecordID, dataText) 37 | } 38 | return responses, err 39 | } 40 | 41 | func main() { 42 | lambda.Start(handler) 43 | } 44 | 45 | ``` 46 | -------------------------------------------------------------------------------- /events/README_KinesisFirehose.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that transforms Kinesis Firehose records by doing a ToUpper on the data. 4 | 5 | ```go 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "strings" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | func handleRequest(evnt events.KinesisFirehoseEvent) (events.KinesisFirehoseResponse, error) { 18 | 19 | fmt.Printf("InvocationID: %s\n", evnt.InvocationID) 20 | fmt.Printf("DeliveryStreamArn: %s\n", evnt.DeliveryStreamArn) 21 | fmt.Printf("Region: %s\n", evnt.Region) 22 | 23 | var response events.KinesisFirehoseResponse 24 | 25 | for _, record := range evnt.Records { 26 | fmt.Printf("RecordID: %s\n", record.RecordID) 27 | fmt.Printf("ApproximateArrivalTimestamp: %s\n", record.ApproximateArrivalTimestamp) 28 | 29 | // Transform data: ToUpper the data 30 | var transformedRecord events.KinesisFirehoseResponseRecord 31 | transformedRecord.RecordID = record.RecordID 32 | transformedRecord.Result = events.KinesisFirehoseTransformedStateOk 33 | transformedRecord.Data = []byte(strings.ToUpper(string(record.Data))) 34 | 35 | response.Records = append(response.Records, transformedRecord) 36 | } 37 | 38 | return response, nil 39 | } 40 | 41 | func main() { 42 | lambda.Start(handleRequest) 43 | } 44 | 45 | ``` 46 | -------------------------------------------------------------------------------- /events/README_Lambda.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Lambda events consist of a request that was routed to a Lambda function by the Lambda Function URLs feature. When this happens, Lambda expects the result of the function to be the response that Lambda should respond with. 4 | 5 | # Sample Function 6 | 7 | The following is a sample class and Lambda function that receives Lambda Function URLs event record data as an input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 8 | 9 | ```go 10 | package main 11 | 12 | import ( 13 | "context" 14 | "fmt" 15 | 16 | "github.com/aws/aws-lambda-go/events" 17 | "github.com/aws/aws-lambda-go/lambda" 18 | ) 19 | 20 | func handleRequest(ctx context.Context, request events.LambdaFunctionURLRequest) (events.LambdaFunctionURLResponse, error) { 21 | fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) 22 | fmt.Printf("Body size = %d.\n", len(request.Body)) 23 | 24 | fmt.Println("Headers:") 25 | for key, value := range request.Headers { 26 | fmt.Printf(" %s: %s\n", key, value) 27 | } 28 | 29 | return events.LambdaFunctionURLResponse{Body: request.Body, StatusCode: 200}, nil 30 | } 31 | 32 | func main() { 33 | lambda.Start(handleRequest) 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /events/README_Lex.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a sample class and Lambda function that receives Amazon Lex event data as input, writes some of the record data to CloudWatch Logs, and responds back to Lex. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 5 | 6 | ```go 7 | import ( 8 | "context" 9 | "fmt" 10 | 11 | "github.com/aws/aws-lambda-go/events" 12 | ) 13 | 14 | func Handler(ctx context.Context, event events.LexEvent) (*lex.LexResponse, error) { 15 | fmt.Printf("Received an input from Amazon Lex. Current Intent: %s", event.CurrentIntent.Name) 16 | 17 | messageContent := "Hello from AWS Lambda!" 18 | 19 | return &LexResponse{ 20 | SessionAttributes: event.SessionAttributes, 21 | DialogAction: events.LexDialogAction{ 22 | Type: "Close", 23 | Message: map[string]string{ 24 | "content": messageContent, 25 | "contentType": "PlainText", 26 | }, 27 | FulfillmentState: "Fulfilled", 28 | }, 29 | }, nil 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /events/README_S3.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample class and Lambda function that receives Amazon S3 event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | // main.go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "context" 13 | "github.com/aws/aws-lambda-go/lambda" 14 | "github.com/aws/aws-lambda-go/events" 15 | ) 16 | 17 | func handler(ctx context.Context, s3Event events.S3Event) { 18 | for _, record := range s3Event.Records { 19 | s3 := record.S3 20 | fmt.Printf("[%s - %s] Bucket = %s, Key = %s \n", record.EventSource, record.EventTime, s3.Bucket.Name, s3.Object.Key) 21 | } 22 | } 23 | 24 | 25 | func main() { 26 | // Make the handler available for Remote Procedure Call by AWS Lambda 27 | lambda.Start(handler) 28 | } 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /events/README_S3_Batch_Job.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample class and Lambda function that receives Amazon S3 event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 4 | 5 | ```go 6 | 7 | import ( 8 | "fmt" 9 | "context" 10 | "github.com/aws/aws-lambda-go/events" 11 | ) 12 | 13 | func handler(ctx context.Context, e events.S3BatchJobEvent) (response events.S3BatchJobResponse, err error) { 14 | fmt.Printf("InvocationSchemaVersion: %s\n", e.InvocationSchemaVersion) 15 | fmt.Printf("InvocationID: %s\n", e.InvocationID) 16 | fmt.Printf("Job.ID: %s\n", e.Job.ID) 17 | 18 | for _, task := range e.Tasks { 19 | fmt.Printf("TaskID: %s\n", task.TaskID) 20 | fmt.Printf("S3Key: %s\n", task.S3Key) 21 | fmt.Printf("S3VersionID: %s\n", task.S3VersionID) 22 | fmt.Printf("S3BucketARN: %s\n", task.S3BucketARN) 23 | 24 | } 25 | 26 | fmt.Printf("InvocationSchemaVersion: %s\n", response.InvocationSchemaVersion) 27 | fmt.Printf("TreatMissingKeysAs: %s\n", response.TreatMissingKeysAs) 28 | fmt.Printf("InvocationID: %s\n", response.InvocationID) 29 | 30 | for _, result := range response.Results { 31 | fmt.Printf("TaskID: %s\n", result.TaskID) 32 | fmt.Printf("ResultCode: %s\n", result.ResultCode) 33 | fmt.Printf("ResultString: %s\n", result.ResultString) 34 | } 35 | 36 | return 37 | } 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /events/README_SES.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a sample class and Lambda function that receives Amazon SES event message data as input, writes some of the message data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 5 | 6 | ```go 7 | package main 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | func handler(ctx context.Context, sesEvent events.SimpleEmailEvent) error { 18 | for _, record := range sesEvent.Records { 19 | ses := record.SES 20 | fmt.Printf("[%s - %s] Mail = %+v, Receipt = %+v \n", record.EventVersion, record.EventSource, ses.Mail, ses.Receipt) 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func main() { 27 | lambda.Start(handler) 28 | } 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /events/README_SNS.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a sample class and Lambda function that receives Amazon SNS event record data as input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 5 | 6 | ```go 7 | import ( 8 | "context" 9 | "fmt" 10 | 11 | "github.com/aws/aws-lambda-go/events" 12 | ) 13 | 14 | func handler(ctx context.Context, snsEvent events.SNSEvent) { 15 | for _, record := range snsEvent.Records { 16 | snsRecord := record.SNS 17 | 18 | fmt.Printf("[%s %s] Message = %s \n", record.EventSource, snsRecord.Timestamp, snsRecord.Message) 19 | } 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /events/README_SQS.md: -------------------------------------------------------------------------------- 1 | 2 | # Sample Function 3 | 4 | The following is a sample class and Lambda function that receives Amazon SQS event message data as input, writes some of the message data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) 5 | 6 | ```go 7 | package main 8 | 9 | import ( 10 | "context" 11 | "fmt" 12 | 13 | "github.com/aws/aws-lambda-go/events" 14 | "github.com/aws/aws-lambda-go/lambda" 15 | ) 16 | 17 | func handler(ctx context.Context, sqsEvent events.SQSEvent) error { 18 | for _, message := range sqsEvent.Records { 19 | fmt.Printf("The message %s for event source %s = %s \n", message.MessageId, message.EventSource, message.Body) 20 | } 21 | 22 | return nil 23 | } 24 | 25 | func main() { 26 | lambda.Start(handler) 27 | } 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /events/README_SecretsManager_SecretRotationEvent.md: -------------------------------------------------------------------------------- 1 | # Sample Function 2 | 3 | The following is a sample Lambda function that handles a SecretsManager secret rotation event. 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "context" 11 | 12 | "github.com/aws/aws-lambda-go/lambda" 13 | "github.com/aws/aws-lambda-go/events" 14 | ) 15 | 16 | func handler(ctx context.Context, event events.SecretsManagerSecretRotationEvent) error { 17 | fmt.Printf("rotating secret %s with token %s\n", 18 | event.SecretID, event.ClientRequestToken) 19 | 20 | switch event.Step { 21 | case "createSecret": 22 | // create 23 | case "setSecret": 24 | // set 25 | case "finishSecret": 26 | // finish 27 | case "testSecret": 28 | // test 29 | } 30 | 31 | return nil 32 | } 33 | 34 | 35 | func main() { 36 | lambda.Start(handler) 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /events/activemq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | type ActiveMQEvent struct { 6 | EventSource string `json:"eventSource"` 7 | EventSourceARN string `json:"eventSourceArn"` 8 | Messages []ActiveMQMessage `json:"messages"` 9 | } 10 | 11 | type ActiveMQMessage struct { 12 | MessageID string `json:"messageID"` 13 | MessageType string `json:"messageType"` 14 | Timestamp int64 `json:"timestamp"` 15 | DeliveryMode int `json:"deliveryMode"` 16 | CorrelationID string `json:"correlationID"` 17 | ReplyTo string `json:"replyTo"` 18 | Destination ActiveMQDestination `json:"destination"` 19 | Redelivered bool `json:"redelivered"` 20 | Type string `json:"type"` 21 | Expiration int64 `json:"expiration"` 22 | Priority int `json:"priority"` 23 | Data string `json:"data"` 24 | BrokerInTime int64 `json:"brokerInTime"` 25 | BrokerOutTime int64 `json:"brokerOutTime"` 26 | Properties map[string]string `json:"properties"` 27 | } 28 | 29 | type ActiveMQDestination struct { 30 | PhysicalName string `json:"physicalName"` 31 | } 32 | -------------------------------------------------------------------------------- /events/activemq_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestActiveMQEventMarshaling(t *testing.T) { 13 | // 1. read JSON from file 14 | inputJSON := test.ReadJSONFromFile(t, "./testdata/activemq-event.json") 15 | 16 | // 2. de-serialize into Go object 17 | var inputEvent ActiveMQEvent 18 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 19 | t.Errorf("could not unmarshal event. details: %v", err) 20 | } 21 | 22 | // 3. Verify values populated into Go Object, at least one validation per data type 23 | assert.Equal(t, "aws:mq", inputEvent.EventSource) 24 | assert.Equal(t, "arn:aws:mq:us-west-2:533019413397:broker:shask-test:b-0f5b7522-2b41-4f85-a615-735a4e6d96b5", inputEvent.EventSourceARN) 25 | assert.Equal(t, 1, len(inputEvent.Messages)) 26 | 27 | var message = inputEvent.Messages[0] 28 | assert.Equal(t, "jms/text-message", message.MessageType) 29 | assert.Equal(t, int64(1599863938941), message.Timestamp) 30 | assert.Equal(t, 1, message.DeliveryMode) 31 | assert.Equal(t, "testQueue", message.Destination.PhysicalName) 32 | assert.Equal(t, false, message.Redelivered) 33 | assert.Equal(t, "testValue", message.Properties["testKey"]) 34 | 35 | // 4. serialize to JSON 36 | outputJSON, err := json.Marshal(inputEvent) 37 | if err != nil { 38 | t.Errorf("could not marshal event. details: %v", err) 39 | } 40 | 41 | // 5. check result 42 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 43 | } 44 | 45 | func TestActiveMQMarshalingMalformedJson(t *testing.T) { 46 | test.TestMalformedJson(t, ActiveMQEvent{}) 47 | } 48 | -------------------------------------------------------------------------------- /events/alb.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // ALBTargetGroupRequest contains data originating from the ALB Lambda target group integration 4 | type ALBTargetGroupRequest struct { 5 | HTTPMethod string `json:"httpMethod"` 6 | Path string `json:"path"` 7 | QueryStringParameters map[string]string `json:"queryStringParameters,omitempty"` 8 | MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters,omitempty"` 9 | Headers map[string]string `json:"headers,omitempty"` 10 | MultiValueHeaders map[string][]string `json:"multiValueHeaders,omitempty"` 11 | RequestContext ALBTargetGroupRequestContext `json:"requestContext"` 12 | IsBase64Encoded bool `json:"isBase64Encoded"` 13 | Body string `json:"body"` 14 | } 15 | 16 | // ALBTargetGroupRequestContext contains the information to identify the load balancer invoking the lambda 17 | type ALBTargetGroupRequestContext struct { 18 | ELB ELBContext `json:"elb"` 19 | } 20 | 21 | // ELBContext contains the information to identify the ARN invoking the lambda 22 | type ELBContext struct { 23 | TargetGroupArn string `json:"targetGroupArn"` //nolint: stylecheck 24 | } 25 | 26 | // ALBTargetGroupResponse configures the response to be returned by the ALB Lambda target group for the request 27 | type ALBTargetGroupResponse struct { 28 | StatusCode int `json:"statusCode"` 29 | StatusDescription string `json:"statusDescription"` 30 | Headers map[string]string `json:"headers"` 31 | MultiValueHeaders map[string][]string `json:"multiValueHeaders"` 32 | Body string `json:"body,omitempty"` 33 | IsBase64Encoded bool `json:"isBase64Encoded"` 34 | } 35 | -------------------------------------------------------------------------------- /events/alb_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" //nolint: staticcheck 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestALBTargetRequestMarshaling(t *testing.T) { 13 | inputFiles := []string{ 14 | "./testdata/alb-lambda-target-request-headers-only.json", 15 | "./testdata/alb-lambda-target-request-multivalue-headers.json"} 16 | 17 | for _, filename := range inputFiles { 18 | // read json from file 19 | inputJSON, err := ioutil.ReadFile(filename) 20 | if err != nil { 21 | t.Errorf("could not open test file. details: %v", err) 22 | } 23 | 24 | // de-serialize into Go object 25 | var inputEvent ALBTargetGroupRequest 26 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 27 | t.Errorf("could not unmarshal event. details: %v", err) 28 | } 29 | 30 | // serialize to json 31 | outputJSON, err := json.Marshal(inputEvent) 32 | if err != nil { 33 | t.Errorf("could not marshal event. details: %v", err) 34 | } 35 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 36 | } 37 | } 38 | 39 | func TestALBTargetRequestMalformedJson(t *testing.T) { 40 | test.TestMalformedJson(t, ALBTargetGroupRequest{}) 41 | } 42 | 43 | func TestALBTargetResponseMarshaling(t *testing.T) { 44 | 45 | // read json from file 46 | inputJSON, err := ioutil.ReadFile("./testdata/alb-lambda-target-response.json") 47 | if err != nil { 48 | t.Errorf("could not open test file. details: %v", err) 49 | } 50 | 51 | // de-serialize into Go object 52 | var inputEvent ALBTargetGroupResponse 53 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 54 | t.Errorf("could not unmarshal event. details: %v", err) 55 | } 56 | 57 | // serialize to json 58 | outputJSON, err := json.Marshal(inputEvent) 59 | if err != nil { 60 | t.Errorf("could not marshal event. details: %v", err) 61 | } 62 | 63 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 64 | } 65 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /events/autoscaling_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestAutoScalingEventMarshaling(t *testing.T) { 12 | 13 | var sampleFileList = []string{"autoscaling-event-launch-successful.json", "autoscaling-event-launch-unsuccessful.json", "autoscaling-event-lifecycle-action.json", 14 | "autoscaling-event-terminate-action.json", "autoscaling-event-terminate-successful.json", "autoscaling-event-terminate-unsuccessful.json"} 15 | 16 | // Loop over list and test each file individually // 17 | for _, sampleFile := range sampleFileList { 18 | 19 | t.Logf("Running test for %s\n", sampleFile) 20 | // 1. read JSON from file 21 | inputJSON := test.ReadJSONFromFile(t, "./testdata/"+sampleFile) 22 | 23 | // 2. de-serialize into Go object 24 | var inputEvent AutoScalingEvent 25 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 26 | t.Errorf("could not unmarshal event. details: %v", err) 27 | } 28 | // 3. serialize to JSON 29 | outputJSON, err := json.Marshal(inputEvent) 30 | if err != nil { 31 | t.Errorf("could not marshal event. details: %v", err) 32 | } 33 | // 4. check result 34 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 35 | } 36 | 37 | } 38 | 39 | func TestAutoScalingMarshalingMalformedJson(t *testing.T) { 40 | test.TestMalformedJson(t, AutoScalingEvent{}) 41 | } 42 | -------------------------------------------------------------------------------- /events/chime_bot.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | type ChimeBotEvent struct { 10 | Sender ChimeBotEventSender `json:"Sender"` 11 | Discussion ChimeBotEventDiscussion `json:"Discussion"` 12 | EventType string `json:"EventType"` 13 | InboundHTTPSEndpoint *ChimeBotEventInboundHTTPSEndpoint `json:"InboundHttpsEndpoint,omitempty"` 14 | EventTimestamp time.Time `json:"EventTimestamp"` 15 | Message string `json:"Message,omitempty"` 16 | } 17 | 18 | type ChimeBotEventSender struct { 19 | SenderID string `json:"SenderId"` 20 | SenderIDType string `json:"SenderIdType"` 21 | } 22 | 23 | type ChimeBotEventDiscussion struct { 24 | DiscussionID string `json:"DiscussionId"` 25 | DiscussionType string `json:"DiscussionType"` 26 | } 27 | 28 | type ChimeBotEventInboundHTTPSEndpoint struct { 29 | EndpointType string `json:"EndpointType"` 30 | URL string `json:"Url"` 31 | } 32 | -------------------------------------------------------------------------------- /events/clientvpn.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type ClientVPNConnectionHandlerRequest struct { 4 | ConnectionID string `json:"connection-id"` 5 | EndpointID string `json:"endpoint-id"` 6 | CommonName string `json:"common-name"` 7 | Username string `json:"username"` 8 | OSPlatform string `json:"platform"` 9 | OSPlatformVersion string `json:"platform-version"` 10 | PublicIP string `json:"public-ip"` 11 | ClientOpenVPNVersion string `json:"client-openvpn-version"` 12 | SchemaVersion string `json:"schema-version"` 13 | } 14 | 15 | type ClientVPNConnectionHandlerResponse struct { 16 | Allow bool `json:"allow"` 17 | ErrorMsgOnFailedPostureCompliance string `json:"error-msg-on-failed-posture-compliance"` 18 | PostureComplianceStatuses []string `json:"posture-compliance-statuses"` 19 | SchemaVersion string `json:"schema-version"` 20 | } 21 | -------------------------------------------------------------------------------- /events/clientvpn_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" //nolint: staticcheck 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestClientVPNConnectionHandlerRequestMarshaling(t *testing.T) { 13 | // read json from file 14 | inputJSON, err := ioutil.ReadFile("./testdata/clientvpn-connectionhandler-request.json") 15 | if err != nil { 16 | t.Errorf("could not open test file. details: %v", err) 17 | } 18 | 19 | // de-serialize into ClientVPNConnectionHandlerRequest 20 | var inputEvent ClientVPNConnectionHandlerRequest 21 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 22 | t.Errorf("could not unmarshal event. details: %v", err) 23 | } 24 | 25 | // serialize to json 26 | outputJSON, err := json.Marshal(inputEvent) 27 | if err != nil { 28 | t.Errorf("could not marshal event. details: %v", err) 29 | } 30 | 31 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 32 | } 33 | 34 | func TestClientVPNConnectionHandlerRequestMarshalingMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, ClientVPNConnectionHandlerRequest{}) 36 | } 37 | -------------------------------------------------------------------------------- /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 EventBridge serverless service. 9 | type CloudWatchEvent struct { 10 | Version string `json:"version"` 11 | ID string `json:"id"` 12 | DetailType string `json:"detail-type"` 13 | Source string `json:"source"` 14 | AccountID string `json:"account"` 15 | Time time.Time `json:"time"` 16 | Region string `json:"region"` 17 | Resources []string `json:"resources"` 18 | Detail json.RawMessage `json:"detail"` 19 | } 20 | 21 | type EventBridgeEvent = CloudWatchEvent 22 | -------------------------------------------------------------------------------- /events/cloudwatch_events_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestCloudwatchScheduledEventIdempotency(t *testing.T) { 12 | inputJSON := []byte( 13 | "{\"version\":\"0\",\"id\":\"890abcde-f123-4567-890a-bcdef1234567\"," + 14 | "\"detail-type\":\"Scheduled Event\",\"source\":\"aws.events\"," + 15 | "\"account\":\"123456789012\",\"time\":\"2016-12-30T18:44:49Z\"," + 16 | "\"region\":\"us-east-1\"," + 17 | "\"resources\":[\"arn:aws:events:us-east-1:123456789012:rule/SampleRule\"]," + 18 | "\"detail\":{}}") 19 | 20 | var inputEvent CloudWatchEvent 21 | err := json.Unmarshal(inputJSON, &inputEvent) 22 | if err != nil { 23 | t.Errorf("Could not unmarshal scheduled event: %v", err) 24 | } 25 | 26 | outputJSON, err := json.Marshal(inputEvent) 27 | if err != nil { 28 | t.Errorf("Could not marshal scheduled event: %v", err) 29 | } 30 | 31 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 32 | } 33 | 34 | func TestCloudwatchScheduledEventRequestMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, CloudWatchEvent{}) 36 | } 37 | -------------------------------------------------------------------------------- /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 | defer zr.Close() 33 | 34 | dec := json.NewDecoder(zr) 35 | err = dec.Decode(&d) 36 | 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 | // CloudwatchLogsLogEvent 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 | -------------------------------------------------------------------------------- /events/codepipeline.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // CodePipelineJob has been incorrectly assigned as CodePipelineEvent 4 | // - https://github.com/aws/aws-lambda-go/issues/244 5 | // 6 | // This maintains backwards compatability until a v2 release 7 | type CodePipelineEvent = CodePipelineJobEvent 8 | -------------------------------------------------------------------------------- /events/codepipeline_job_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "io/ioutil" //nolint: staticcheck 7 | "testing" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestCodePipeLineJobEventMarshaling(t *testing.T) { 14 | 15 | // read json from file 16 | inputJSON, err := ioutil.ReadFile("./testdata/codepipeline-job-event.json") 17 | if err != nil { 18 | t.Errorf("could not open test file. details: %v", err) 19 | } 20 | 21 | // de-serialize into CodePipelineJobEvent 22 | var inputEvent CodePipelineJobEvent 23 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 24 | t.Errorf("could not unmarshal event. details: %v", err) 25 | } 26 | 27 | // serialize to json 28 | outputJSON, err := json.Marshal(inputEvent) 29 | if err != nil { 30 | t.Errorf("could not marshal event. details: %v", err) 31 | } 32 | 33 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 34 | } 35 | 36 | func TestCodePipelineJobEventMarshalingMalformedJson(t *testing.T) { 37 | test.TestMalformedJson(t, CodePipelineJobEvent{}) 38 | } 39 | -------------------------------------------------------------------------------- /events/codepipeline_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "io/ioutil" //nolint: staticcheck 7 | "testing" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestCodePipeLineEventMarshaling(t *testing.T) { 14 | 15 | // read json from file 16 | inputJSON, err := ioutil.ReadFile("./testdata/codepipeline-job-event.json") 17 | if err != nil { 18 | t.Errorf("could not open test file. details: %v", err) 19 | } 20 | 21 | // de-serialize into CodePipelineEvent 22 | var inputEvent CodePipelineEvent 23 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 24 | t.Errorf("could not unmarshal event. details: %v", err) 25 | } 26 | 27 | // serialize to json 28 | outputJSON, err := json.Marshal(inputEvent) 29 | if err != nil { 30 | t.Errorf("could not marshal event. details: %v", err) 31 | } 32 | 33 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 34 | } 35 | 36 | func TestCodePipelineEventMarshalingMalformedJson(t *testing.T) { 37 | test.TestMalformedJson(t, CodePipelineEvent{}) 38 | } 39 | -------------------------------------------------------------------------------- /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 | // The ID of the AWS account that owns the rule 8 | AccountID string `json:"accountId"` 9 | // The ARN that AWS Config assigned to the rule 10 | ConfigRuleArn string `json:"configRuleArn"` //nolint:stylecheck 11 | ConfigRuleID string `json:"configRuleId"` //nolint:stylecheck 12 | // The name that you assigned to the rule that caused AWS Config to publish the event 13 | ConfigRuleName string `json:"configRuleName"` 14 | // A boolean value that indicates whether the AWS resource to be evaluated has been removed from the rule's scope 15 | EventLeftScope bool `json:"eventLeftScope"` 16 | ExecutionRoleArn string `json:"executionRoleArn"` //nolint:stylecheck 17 | // If the event is published in response to a resource configuration change, this value contains a JSON configuration item 18 | InvokingEvent string `json:"invokingEvent"` 19 | // A token that the function must pass to AWS Config with the PutEvaluations call 20 | ResultToken string `json:"resultToken"` 21 | // Key/value pairs that the function processes as part of its evaluation logic 22 | RuleParameters string `json:"ruleParameters"` 23 | Version string `json:"version"` 24 | } 25 | -------------------------------------------------------------------------------- /events/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "io/ioutil" //nolint: staticcheck 7 | "testing" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestConfigEventMarshaling(t *testing.T) { 14 | // read json from file 15 | inputJSON, err := ioutil.ReadFile("./testdata/config-event.json") 16 | if err != nil { 17 | t.Errorf("could not open test file. details: %v", err) 18 | } 19 | 20 | // de-serialize into Go object 21 | var inputEvent ConfigEvent 22 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 23 | t.Errorf("could not unmarshal event. details: %v", err) 24 | } 25 | 26 | // serialize to json 27 | outputJSON, err := json.Marshal(inputEvent) 28 | if err != nil { 29 | t.Errorf("could not marshal event. details: %v", err) 30 | } 31 | 32 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 33 | } 34 | 35 | func TestConfigMarshalingMalformedJson(t *testing.T) { 36 | test.TestMalformedJson(t, ConfigEvent{}) 37 | } 38 | -------------------------------------------------------------------------------- /events/connect_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "encoding/json" 7 | "testing" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestConnectMarshaling(t *testing.T) { 14 | 15 | // 1. read JSON from file 16 | inputJSON := test.ReadJSONFromFile(t, "./testdata/connect-event.json") 17 | 18 | // 2. de-serialize into Go object 19 | var inputEvent ConnectEvent 20 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 21 | t.Errorf("could not unmarshal event. details: %v", err) 22 | } 23 | 24 | // 3. serialize to JSON 25 | outputJSON, err := json.Marshal(inputEvent) 26 | if err != nil { 27 | t.Errorf("could not marshal event. details: %v", err) 28 | } 29 | 30 | // 4. check result 31 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 32 | } 33 | 34 | func TestConnectMarshalingMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, ConnectEvent{}) 36 | } 37 | -------------------------------------------------------------------------------- /events/duration.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "math" 6 | "time" 7 | ) 8 | 9 | type DurationSeconds time.Duration 10 | 11 | // UnmarshalJSON converts a given json to a DurationSeconds 12 | func (duration *DurationSeconds) UnmarshalJSON(data []byte) error { 13 | var seconds float64 14 | if err := json.Unmarshal(data, &seconds); err != nil { 15 | return err 16 | } 17 | 18 | *duration = DurationSeconds(time.Duration(seconds) * time.Second) 19 | return nil 20 | } 21 | 22 | // MarshalJSON converts a given DurationSeconds to json 23 | func (duration DurationSeconds) MarshalJSON() ([]byte, error) { 24 | seconds := time.Duration(duration).Seconds() 25 | return json.Marshal(int64(math.Ceil(seconds))) 26 | } 27 | 28 | type DurationMinutes time.Duration 29 | 30 | // UnmarshalJSON converts a given json to a DurationMinutes 31 | func (duration *DurationMinutes) UnmarshalJSON(data []byte) error { 32 | var minutes float64 33 | if err := json.Unmarshal(data, &minutes); err != nil { 34 | return err 35 | } 36 | 37 | *duration = DurationMinutes(time.Duration(minutes) * time.Minute) 38 | return nil 39 | } 40 | 41 | // MarshalJSON converts a given DurationMinutes to json 42 | func (duration DurationMinutes) MarshalJSON() ([]byte, error) { 43 | minutes := time.Duration(duration).Minutes() 44 | return json.Marshal(int64(math.Ceil(minutes))) 45 | } 46 | -------------------------------------------------------------------------------- /events/dynamodb_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "encoding/json" 7 | "testing" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestDynamoDBEventMarshaling(t *testing.T) { 14 | 15 | // 1. read JSON from file 16 | inputJSON := test.ReadJSONFromFile(t, "./testdata/dynamodb-event.json") 17 | 18 | // 2. de-serialize into Go object 19 | var inputEvent DynamoDBEvent 20 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 21 | t.Errorf("could not unmarshal event. details: %v", err) 22 | } 23 | 24 | // 3. serialize to JSON 25 | outputJSON, err := json.Marshal(inputEvent) 26 | if err != nil { 27 | t.Errorf("could not marshal event. details: %v", err) 28 | } 29 | 30 | // 4. check result 31 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 32 | } 33 | 34 | func TestDynamoDBEventMarshalingMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, DynamoDBEvent{}) 36 | } 37 | 38 | func TestDynamoDBTimeWindowEventMarshaling(t *testing.T) { 39 | // 1. read JSON from file 40 | inputJSON := test.ReadJSONFromFile(t, "./testdata/dynamodb-time-window-event.json") 41 | 42 | // 2. de-serialize into Go object 43 | var inputEvent DynamoDBTimeWindowEvent 44 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 45 | t.Errorf("could not unmarshal event. details: %v", err) 46 | } 47 | 48 | // 3. serialize to JSON 49 | outputJSON, err := json.Marshal(inputEvent) 50 | if err != nil { 51 | t.Errorf("could not marshal event. details: %v", err) 52 | } 53 | 54 | // 4. check result 55 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 56 | } 57 | 58 | func TestDynamoDBTimeWindowEventMarshalingMalformedJson(t *testing.T) { 59 | test.TestMalformedJson(t, DynamoDBTimeWindowEvent{}) 60 | } 61 | -------------------------------------------------------------------------------- /events/ecr_image_action.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import "time" 4 | 5 | type ECRImageActionEvent struct { 6 | Version string `json:"version"` 7 | ID string `json:"id"` 8 | DetailType string `json:"detail-type"` 9 | Source string `json:"source"` 10 | Account string `json:"account"` 11 | Time time.Time `json:"time"` 12 | Region string `json:"region"` 13 | Resources []string `json:"resources"` 14 | Detail ECRImageActionEventDetailType `json:"detail"` 15 | } 16 | 17 | type ECRImageActionEventDetailType struct { 18 | Result string `json:"result"` 19 | RepositoryName string `json:"repository-name"` 20 | ImageDigest string `json:"image-digest"` 21 | ActionType string `json:"action-type"` 22 | ImageTag string `json:"image-tag"` 23 | } 24 | -------------------------------------------------------------------------------- /events/ecr_image_action_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | "time" 8 | 9 | "github.com/aws/aws-lambda-go/events/test" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestECRImageActionEventMarshaling(t *testing.T) { 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/ecr-image-push-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent ECRImageActionEvent 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. Verify values populated into Go Object, at least one validation per data type 24 | assert.Equal(t, "0", inputEvent.Version) 25 | assert.Equal(t, "13cde686-328b-6117-af20-0e5566167482", inputEvent.ID) 26 | assert.Equal(t, "ECR Image Action", inputEvent.DetailType) 27 | assert.Equal(t, "aws.ecr", inputEvent.Source) 28 | assert.Equal(t, "123456789012", inputEvent.Account) 29 | assert.Equal(t, "us-west-2", inputEvent.Region) 30 | assert.Empty(t, inputEvent.Resources) 31 | 32 | testTime, err := time.Parse(time.RFC3339, "2019-11-16T01:54:34Z") 33 | if err != nil { 34 | t.Errorf("Failed to parse time: %v", err) 35 | } 36 | assert.Equal(t, testTime, inputEvent.Time) 37 | 38 | var detail = inputEvent.Detail 39 | assert.Equal(t, "SUCCESS", detail.Result) 40 | assert.Equal(t, "my-repository-name", detail.RepositoryName) 41 | assert.Equal(t, "sha256:7f5b2640fe6fb4f46592dfd3410c4a79dac4f89e4782432e0378abcd1234", detail.ImageDigest) 42 | assert.Equal(t, "latest", detail.ImageTag) 43 | 44 | // 4. serialize to JSON 45 | outputJSON, err := json.Marshal(inputEvent) 46 | if err != nil { 47 | t.Errorf("could not marshal event. details: %v", err) 48 | } 49 | 50 | // 5. check result 51 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 52 | } 53 | 54 | func TestECRPushMarshalingMalformedJson(t *testing.T) { 55 | test.TestMalformedJson(t, ECRImageActionEvent{}) 56 | } 57 | -------------------------------------------------------------------------------- /events/ecr_scan.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type ECRScanEvent struct { 4 | Version string `json:"version"` 5 | ID string `json:"id"` 6 | DetailType string `json:"detail-type"` 7 | Source string `json:"source"` 8 | Time string `json:"time"` 9 | Region string `json:"region"` 10 | Resources []string `json:"resources"` 11 | Account string `json:"account"` 12 | Detail ECRScanEventDetailType `json:"detail"` 13 | } 14 | 15 | type ECRScanEventDetailType struct { 16 | ScanStatus string `json:"scan-status"` 17 | RepositoryName string `json:"repository-name"` 18 | FindingSeverityCounts ECRScanEventFindingSeverityCounts `json:"finding-severity-counts"` 19 | ImageDigest string `json:"image-digest"` 20 | ImageTags []string `json:"image-tags"` 21 | } 22 | 23 | type ECRScanEventFindingSeverityCounts struct { 24 | Critical int64 `json:"CRITICAL"` 25 | High int64 `json:"HIGH"` 26 | Medium int64 `json:"MEDIUM"` 27 | Low int64 `json:"LOW"` 28 | Informational int64 `json:"INFORMATIONAL"` 29 | Undefined int64 `json:"UNDEFINED"` 30 | } 31 | -------------------------------------------------------------------------------- /events/iam.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // IAMPolicyDocument represents an IAM policy document. 4 | type IAMPolicyDocument struct { 5 | Version string 6 | Statement []IAMPolicyStatement 7 | } 8 | 9 | // IAMPolicyStatement represents one statement from IAM policy with action, effect and resource. 10 | type IAMPolicyStatement struct { 11 | Action []string 12 | Effect string 13 | Resource []string 14 | } 15 | -------------------------------------------------------------------------------- /events/iot.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // IoTCoreCustomAuthorizerRequest represents the request to an IoT Core custom authorizer. 4 | // See https://docs.aws.amazon.com/iot/latest/developerguide/config-custom-auth.html 5 | type IoTCoreCustomAuthorizerRequest struct { 6 | Token string `json:"token"` 7 | SignatureVerified bool `json:"signatureVerified"` 8 | Protocols []string `json:"protocols"` 9 | ProtocolData *IoTCoreProtocolData `json:"protocolData,omitempty"` 10 | ConnectionMetadata *IoTCoreConnectionMetadata `json:"connectionMetadata,omitempty"` 11 | } 12 | 13 | type IoTCoreProtocolData struct { 14 | TLS *IoTCoreTLSContext `json:"tls,omitempty"` 15 | HTTP *IoTCoreHTTPContext `json:"http,omitempty"` 16 | MQTT *IoTCoreMQTTContext `json:"mqtt,omitempty"` 17 | } 18 | 19 | type IoTCoreTLSContext struct { 20 | ServerName string `json:"serverName"` 21 | } 22 | 23 | type IoTCoreHTTPContext struct { 24 | Headers map[string]string `json:"headers,omitempty"` 25 | QueryString string `json:"queryString"` 26 | } 27 | 28 | type IoTCoreMQTTContext struct { 29 | ClientID string `json:"clientId"` 30 | Password []byte `json:"password"` 31 | Username string `json:"username"` 32 | } 33 | 34 | type IoTCoreConnectionMetadata struct { 35 | ID string `json:"id"` 36 | } 37 | 38 | // IoTCoreCustomAuthorizerResponse represents the response from an IoT Core custom authorizer. 39 | // See https://docs.aws.amazon.com/iot/latest/developerguide/config-custom-auth.html 40 | type IoTCoreCustomAuthorizerResponse struct { 41 | IsAuthenticated bool `json:"isAuthenticated"` 42 | PrincipalID string `json:"principalId"` 43 | DisconnectAfterInSeconds uint32 `json:"disconnectAfterInSeconds"` 44 | RefreshAfterInSeconds uint32 `json:"refreshAfterInSeconds"` 45 | PolicyDocuments []*IAMPolicyDocument `json:"policyDocuments"` 46 | } 47 | -------------------------------------------------------------------------------- /events/iot_1_click.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | // IoTOneClickEvent represents a click event published by clicking button type 6 | // device. 7 | type IoTOneClickEvent struct { 8 | DeviceEvent IoTOneClickDeviceEvent `json:"deviceEvent"` 9 | DeviceInfo IoTOneClickDeviceInfo `json:"deviceInfo"` 10 | PlacementInfo IoTOneClickPlacementInfo `json:"placementInfo"` 11 | } 12 | 13 | type IoTOneClickDeviceEvent struct { 14 | ButtonClicked IoTOneClickButtonClicked `json:"buttonClicked"` 15 | } 16 | 17 | type IoTOneClickButtonClicked struct { 18 | ClickType string `json:"clickType"` 19 | ReportedTime string `json:"reportedTime"` 20 | } 21 | 22 | type IoTOneClickDeviceInfo struct { 23 | Attributes map[string]string `json:"attributes"` 24 | Type string `json:"type"` 25 | DeviceID string `json:"deviceId"` 26 | RemainingLife float64 `json:"remainingLife"` 27 | } 28 | 29 | type IoTOneClickPlacementInfo struct { 30 | ProjectName string `json:"projectName"` 31 | PlacementName string `json:"placementName"` 32 | Attributes map[string]string `json:"attributes"` 33 | Devices map[string]string `json:"devices"` 34 | } 35 | -------------------------------------------------------------------------------- /events/iot_1_click_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestIoTOneClickEventMalformedJson(t *testing.T) { 13 | 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/iot-1-click-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent IoTOneClickEvent 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. serialize to JSON 24 | outputJSON, err := json.Marshal(inputEvent) 25 | if err != nil { 26 | t.Errorf("could not marshal event. details: %v", err) 27 | } 28 | // 4. check result 29 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 30 | } 31 | 32 | func TestIoTOneClickEventMarshaling(t *testing.T) { 33 | test.TestMalformedJson(t, IoTOneClickEvent{}) 34 | } 35 | -------------------------------------------------------------------------------- /events/iot_button.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | type IoTButtonEvent struct { 6 | SerialNumber string `json:"serialNumber"` 7 | ClickType string `json:"clickType"` 8 | BatteryVoltage string `json:"batteryVoltage"` 9 | } 10 | -------------------------------------------------------------------------------- /events/iot_button_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestIoTButtonMalformedJson(t *testing.T) { 13 | 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/iot-button-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent IoTButtonEvent 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. serialize to JSON 24 | outputJSON, err := json.Marshal(inputEvent) 25 | if err != nil { 26 | t.Errorf("could not marshal event. details: %v", err) 27 | } 28 | // 4. check result 29 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 30 | } 31 | 32 | func TestIoTButtonEventMarshaling(t *testing.T) { 33 | test.TestMalformedJson(t, IoTButtonEvent{}) 34 | } 35 | -------------------------------------------------------------------------------- /events/iot_deprecated.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // IoTCustomAuthorizerRequest contains data coming in to a custom IoT device gateway authorizer function. 4 | // Deprecated: Use IoTCoreCustomAuthorizerRequest instead. IoTCustomAuthorizerRequest does not correctly model the request schema 5 | type IoTCustomAuthorizerRequest struct { 6 | HTTPContext *IoTHTTPContext `json:"httpContext,omitempty"` 7 | MQTTContext *IoTMQTTContext `json:"mqttContext,omitempty"` 8 | TLSContext *IoTTLSContext `json:"tlsContext,omitempty"` 9 | AuthorizationToken string `json:"token"` 10 | TokenSignature string `json:"tokenSignature"` 11 | } 12 | 13 | // Deprecated: Use IoTCoreHTTPContext 14 | type IoTHTTPContext IoTCoreHTTPContext 15 | 16 | // Deprecated: Use IoTCoreMQTTContext 17 | type IoTMQTTContext IoTCoreMQTTContext 18 | 19 | // Deprecated: Use IotCoreTLSContext 20 | type IoTTLSContext IoTCoreTLSContext 21 | 22 | // IoTCustomAuthorizerResponse represents the expected format of an IoT device gateway authorization response. 23 | // Deprecated: Use IoTCoreCustomAuthorizerResponse. IoTCustomAuthorizerResponse does not correctly model the response schema. 24 | type IoTCustomAuthorizerResponse struct { 25 | IsAuthenticated bool `json:"isAuthenticated"` 26 | PrincipalID string `json:"principalId"` 27 | DisconnectAfterInSeconds int32 `json:"disconnectAfterInSeconds"` 28 | RefreshAfterInSeconds int32 `json:"refreshAfterInSeconds"` 29 | PolicyDocuments []string `json:"policyDocuments"` 30 | } 31 | -------------------------------------------------------------------------------- /events/iot_preprovision_hook.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // IoTPreProvisionHookRequest contains the request parameters for the IoT Pre-Provisioning Hook. 4 | // See https://docs.aws.amazon.com/iot/latest/developerguide/pre-provisioning-hook.html 5 | type IoTPreProvisionHookRequest struct { 6 | ClaimCertificateID string `json:"claimCertificateId"` 7 | CertificateID string `json:"certificateId"` 8 | CertificatePEM string `json:"certificatePem"` 9 | TemplateARN string `json:"templateArn"` 10 | ClientID string `json:"clientId"` 11 | Parameters map[string]string `json:"parameters"` 12 | } 13 | 14 | // IoTPreProvisionHookResponse contains the response parameters for the IoT Pre-Provisioning Hook. 15 | // See https://docs.aws.amazon.com/iot/latest/developerguide/pre-provisioning-hook.html 16 | type IoTPreProvisionHookResponse struct { 17 | AllowProvisioning bool `json:"allowProvisioning"` 18 | ParameterOverrides map[string]string `json:"parameterOverrides"` 19 | } 20 | -------------------------------------------------------------------------------- /events/iot_preprovision_hook_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" //nolint: staticcheck 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | ) 10 | 11 | func TestIoTPreProvisionHookRequest(t *testing.T) { 12 | 13 | // read json from file 14 | inputJSON, err := ioutil.ReadFile("./testdata/iot-preprovision-hook-request.json") 15 | if err != nil { 16 | t.Errorf("could not open test file. details: %v", err) 17 | } 18 | 19 | // de-serialize into Go object 20 | var inputEvent IoTPreProvisionHookRequest 21 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 22 | t.Errorf("could not unmarshal event. details: %v", err) 23 | } 24 | 25 | // serialize to json 26 | outputJSON, err := json.Marshal(inputEvent) 27 | if err != nil { 28 | t.Errorf("could not marshal event. details: %v", err) 29 | } 30 | 31 | test.AssertJsonsEqual(t, inputJSON, outputJSON) 32 | } 33 | 34 | func TestIoTPreProvisionHookRequestMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, IoTPreProvisionHookRequest{}) 36 | } 37 | 38 | func TestIoTPreProvisionHookResponseMarshaling(t *testing.T) { 39 | 40 | // read json from file 41 | inputJSON, err := ioutil.ReadFile("./testdata/iot-preprovision-hook-response.json") 42 | if err != nil { 43 | t.Errorf("could not open test file. details: %v", err) 44 | } 45 | 46 | // de-serialize into Go object 47 | var inputEvent IoTPreProvisionHookResponse 48 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 49 | t.Errorf("could not unmarshal event. details: %v", err) 50 | } 51 | 52 | // serialize to json 53 | outputJSON, err := json.Marshal(inputEvent) 54 | if err != nil { 55 | t.Errorf("could not marshal event. details: %v", err) 56 | } 57 | 58 | test.AssertJsonsEqual(t, inputJSON, outputJSON) 59 | } 60 | 61 | func TestIoTPreProvisionHookResponseMalformedJson(t *testing.T) { 62 | test.TestMalformedJson(t, IoTPreProvisionHookResponse{}) 63 | } 64 | -------------------------------------------------------------------------------- /events/iot_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" //nolint: staticcheck 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | ) 10 | 11 | func TestIoTCoreCustomAuthorizerRequestMarshaling(t *testing.T) { 12 | 13 | // read json from file 14 | inputJSON, err := ioutil.ReadFile("./testdata/iot-custom-auth-request.json") 15 | if err != nil { 16 | t.Errorf("could not open test file. details: %v", err) 17 | } 18 | 19 | // de-serialize into Go object 20 | var inputEvent IoTCoreCustomAuthorizerRequest 21 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 22 | t.Errorf("could not unmarshal event. details: %v", err) 23 | } 24 | 25 | // serialize to json 26 | outputJSON, err := json.Marshal(inputEvent) 27 | if err != nil { 28 | t.Errorf("could not marshal event. details: %v", err) 29 | } 30 | 31 | test.AssertJsonsEqual(t, inputJSON, outputJSON) 32 | } 33 | 34 | func TestIoTCoreCustomAuthorizerRequestMalformedJson(t *testing.T) { 35 | test.TestMalformedJson(t, IoTCoreCustomAuthorizerRequest{}) 36 | } 37 | 38 | func TestIoTCoreCustomAuthorizerResponseMarshaling(t *testing.T) { 39 | 40 | // read json from file 41 | inputJSON, err := ioutil.ReadFile("./testdata/iot-custom-auth-response.json") 42 | if err != nil { 43 | t.Errorf("could not open test file. details: %v", err) 44 | } 45 | 46 | // de-serialize into Go object 47 | var inputEvent IoTCoreCustomAuthorizerResponse 48 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 49 | t.Errorf("could not unmarshal event. details: %v", err) 50 | } 51 | 52 | // serialize to json 53 | outputJSON, err := json.Marshal(inputEvent) 54 | if err != nil { 55 | t.Errorf("could not marshal event. details: %v", err) 56 | } 57 | 58 | test.AssertJsonsEqual(t, inputJSON, outputJSON) 59 | } 60 | 61 | func TestIoTCoreCustomAuthorizerResponseMalformedJson(t *testing.T) { 62 | test.TestMalformedJson(t, IoTCoreCustomAuthorizerResponse{}) 63 | } 64 | -------------------------------------------------------------------------------- /events/kafka.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | import ( 6 | "encoding/json" 7 | ) 8 | 9 | type KafkaEvent struct { 10 | EventSource string `json:"eventSource"` 11 | EventSourceARN string `json:"eventSourceArn"` 12 | Records map[string][]KafkaRecord `json:"records"` 13 | BootstrapServers string `json:"bootstrapServers"` 14 | } 15 | 16 | type KafkaRecord struct { 17 | Topic string `json:"topic"` 18 | Partition int64 `json:"partition"` 19 | Offset int64 `json:"offset"` 20 | Timestamp MilliSecondsEpochTime `json:"timestamp"` 21 | TimestampType string `json:"timestampType"` 22 | Key string `json:"key,omitempty"` 23 | Value string `json:"value,omitempty"` 24 | Headers []map[string]JSONNumberBytes `json:"headers"` 25 | } 26 | 27 | // JSONNumberBytes represents array of bytes in Headers field. 28 | type JSONNumberBytes []byte 29 | 30 | // MarshalJSON converts byte array into array of signed integers. 31 | func (b JSONNumberBytes) MarshalJSON() ([]byte, error) { 32 | signedNumbers := make([]int8, len(b)) 33 | for i, value := range b { 34 | signedNumbers[i] = int8(value) 35 | } 36 | return json.Marshal(signedNumbers) 37 | } 38 | 39 | // UnmarshalJSON converts a given json with potential negative values into byte array. 40 | func (b *JSONNumberBytes) UnmarshalJSON(data []byte) error { 41 | var signedNumbers []int8 42 | if err := json.Unmarshal(data, &signedNumbers); err != nil { 43 | return err 44 | } 45 | *b = make(JSONNumberBytes, len(signedNumbers)) 46 | for i, value := range signedNumbers { 47 | (*b)[i] = byte(value) 48 | } 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /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 | // KinesisTimeWindowEvent represents an Amazon Dynamodb event when using time windows 10 | // ref. https://docs.aws.amazon.com/lambda/latest/dg/with-kinesis.html#services-kinesis-windows 11 | type KinesisTimeWindowEvent struct { 12 | KinesisEvent 13 | TimeWindowProperties 14 | } 15 | 16 | // KinesisTimeWindowEventResponse is the outer structure to report batch item failures for KinesisTimeWindowEvent. 17 | type KinesisTimeWindowEventResponse struct { 18 | TimeWindowEventResponseProperties 19 | BatchItemFailures []KinesisBatchItemFailure `json:"batchItemFailures"` 20 | } 21 | 22 | type KinesisEventRecord struct { 23 | AwsRegion string `json:"awsRegion"` //nolint: stylecheck 24 | EventID string `json:"eventID"` 25 | EventName string `json:"eventName"` 26 | EventSource string `json:"eventSource"` 27 | EventSourceArn string `json:"eventSourceARN"` //nolint: stylecheck 28 | EventVersion string `json:"eventVersion"` 29 | InvokeIdentityArn string `json:"invokeIdentityArn"` //nolint: stylecheck 30 | Kinesis KinesisRecord `json:"kinesis"` 31 | } 32 | 33 | type KinesisRecord struct { 34 | ApproximateArrivalTimestamp SecondsEpochTime `json:"approximateArrivalTimestamp"` 35 | Data []byte `json:"data"` 36 | EncryptionType string `json:"encryptionType,omitempty"` 37 | PartitionKey string `json:"partitionKey"` 38 | SequenceNumber string `json:"sequenceNumber"` 39 | KinesisSchemaVersion string `json:"kinesisSchemaVersion"` 40 | } 41 | -------------------------------------------------------------------------------- /events/kinesis_analytics.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package events 4 | 5 | type KinesisAnalyticsOutputDeliveryEvent struct { 6 | InvocationID string `json:"invocationId"` 7 | ApplicationARN string `json:"applicationArn"` 8 | Records []KinesisAnalyticsOutputDeliveryEventRecord `json:"records"` 9 | } 10 | 11 | type KinesisAnalyticsOutputDeliveryEventRecord struct { 12 | RecordID string `json:"recordId"` 13 | Data []byte `json:"data"` 14 | } 15 | 16 | type KinesisAnalyticsOutputDeliveryResponse struct { 17 | Records []KinesisAnalyticsOutputDeliveryResponseRecord `json:"records"` 18 | } 19 | 20 | const ( 21 | KinesisAnalyticsOutputDeliveryOK = "Ok" 22 | KinesisAnalyticsOutputDeliveryFailed = "DeliveryFailed" 23 | ) 24 | 25 | type KinesisAnalyticsOutputDeliveryResponseRecord struct { 26 | RecordID string `json:"recordId"` 27 | Result string `json:"result"` //possible values include Ok and DeliveryFailed 28 | } 29 | -------------------------------------------------------------------------------- /events/kinesis_analytics_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestKinesisAnalyticsOutputDeliveryEventMarshaling(t *testing.T) { 13 | testKinesisAnalyticsOutputMarshaling(t, KinesisAnalyticsOutputDeliveryEvent{}, "./testdata/kinesis-analytics-output-delivery-event.json") 14 | } 15 | 16 | func TestKinesisAnalyticsOutputDeliveryResponseMarshaling(t *testing.T) { 17 | testKinesisAnalyticsOutputMarshaling(t, KinesisAnalyticsOutputDeliveryResponse{}, "./testdata/kinesis-analytics-output-delivery-response.json") 18 | } 19 | 20 | func TestKinesisOutputDeliveryEventMarshalingMalformedJson(t *testing.T) { 21 | test.TestMalformedJson(t, KinesisAnalyticsOutputDeliveryEvent{}) 22 | } 23 | 24 | func testKinesisAnalyticsOutputMarshaling(t *testing.T, inputEvent interface{}, jsonFile string) { 25 | 26 | // 1. read JSON from file 27 | inputJSON := test.ReadJSONFromFile(t, jsonFile) 28 | 29 | // 2. de-serialize into Go object 30 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 31 | t.Errorf("could not unmarshal event. details: %v", err) 32 | } 33 | 34 | // 3. serialize to JSON 35 | outputJSON, err := json.Marshal(inputEvent) 36 | if err != nil { 37 | t.Errorf("could not marshal event. details: %v", err) 38 | } 39 | 40 | // 4. check result 41 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 42 | } 43 | -------------------------------------------------------------------------------- /events/kinesis_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestKinesisEventMarshaling(t *testing.T) { 13 | 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/kinesis-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent KinesisEvent 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. serialize to JSON 24 | outputJSON, err := json.Marshal(inputEvent) 25 | if err != nil { 26 | t.Errorf("could not marshal event. details: %v", err) 27 | } 28 | 29 | // 4. check result 30 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 31 | } 32 | 33 | func TestKinesisMarshalingMalformedJson(t *testing.T) { 34 | test.TestMalformedJson(t, KinesisEvent{}) 35 | } 36 | 37 | func TestKinesisTimeWindowEventMarshaling(t *testing.T) { 38 | // 1. read JSON from file 39 | inputJSON := test.ReadJSONFromFile(t, "./testdata/kinesis-time-window-event.json") 40 | 41 | // 2. de-serialize into Go object 42 | var inputEvent KinesisTimeWindowEvent 43 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 44 | t.Errorf("could not unmarshal event. details: %v", err) 45 | } 46 | 47 | // 3. serialize to JSON 48 | outputJSON, err := json.Marshal(inputEvent) 49 | if err != nil { 50 | t.Errorf("could not marshal event. details: %v", err) 51 | } 52 | 53 | // 4. check result 54 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 55 | } 56 | 57 | func TestKinesisTimeWindowEventMarshalingMalformedJson(t *testing.T) { 58 | test.TestMalformedJson(t, KinesisTimeWindowEvent{}) 59 | } 60 | -------------------------------------------------------------------------------- /events/lex_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestLexEventMarshaling(t *testing.T) { 12 | inputJSON := test.ReadJSONFromFile(t, "./testdata/lex-event.json") 13 | 14 | var inputEvent LexEvent 15 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 16 | t.Errorf("could not unmarshal event. details: %v", err) 17 | } 18 | 19 | outputJSON, err := json.Marshal(inputEvent) 20 | if err != nil { 21 | t.Errorf("could not marshal event. details: %v", err) 22 | } 23 | 24 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 25 | } 26 | 27 | func TestLexResponseMarshaling(t *testing.T) { 28 | inputJSON := test.ReadJSONFromFile(t, "./testdata/lex-response.json") 29 | 30 | var inputEvent LexResponse 31 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 32 | t.Errorf("could not unmarshal event. details: %v", err) 33 | } 34 | 35 | outputJSON, err := json.Marshal(inputEvent) 36 | if err != nil { 37 | t.Errorf("could not marshal event. details: %v", err) 38 | } 39 | 40 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 41 | } 42 | 43 | func TestLexMarshalingMalformedJson(t *testing.T) { 44 | test.TestMalformedJson(t, LexEvent{}) 45 | } 46 | 47 | func TestLexResponseMalformedJson(t *testing.T) { 48 | test.TestMalformedJson(t, LexResponse{}) 49 | } 50 | -------------------------------------------------------------------------------- /events/rabbitmq.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type RabbitMQEvent struct { 4 | EventSource string `json:"eventSource"` 5 | EventSourceARN string `json:"eventSourceArn"` 6 | MessagesByQueue map[string][]RabbitMQMessage `json:"rmqMessagesByQueue"` 7 | } 8 | 9 | type RabbitMQMessage struct { 10 | BasicProperties RabbitMQBasicProperties `json:"basicProperties"` 11 | Data string `json:"data"` 12 | Redelivered bool `json:"redelivered"` 13 | } 14 | 15 | type RabbitMQBasicProperties struct { 16 | ContentType string `json:"contentType"` 17 | ContentEncoding *string `json:"contentEncoding"` 18 | Headers map[string]interface{} `json:"headers"` // Application or header exchange table 19 | DeliveryMode uint8 `json:"deliveryMode"` 20 | Priority uint8 `json:"priority"` 21 | CorrelationID *string `json:"correlationId"` 22 | ReplyTo *string `json:"replyTo"` 23 | Expiration string `json:"expiration"` 24 | MessageID *string `json:"messageId"` 25 | Timestamp string `json:"timestamp"` 26 | Type *string `json:"type"` 27 | UserID string `json:"userId"` 28 | AppID *string `json:"appId"` 29 | ClusterID *string `json:"clusterId"` 30 | BodySize uint64 `json:"bodySize"` 31 | } 32 | -------------------------------------------------------------------------------- /events/rabbitmq_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestRabbitMQEventMarshaling(t *testing.T) { 12 | // 1. read JSON from file 13 | inputJSON := test.ReadJSONFromFile(t, "./testdata/rabbitmq-event.json") 14 | 15 | // 2. de-serialize into Go object 16 | var inputEvent RabbitMQEvent 17 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 18 | t.Errorf("could not unmarshal event. details: %v", err) 19 | } 20 | 21 | // 3. Verify values populated into Go Object, at least one validation per data type 22 | assert.Equal(t, "aws:rmq", inputEvent.EventSource) 23 | assert.Equal(t, "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8", inputEvent.EventSourceARN) 24 | assert.Equal(t, 1, len(inputEvent.MessagesByQueue)) 25 | for _, messages := range inputEvent.MessagesByQueue { 26 | for _, message := range messages { 27 | assert.Equal(t, false, message.Redelivered) 28 | assert.Equal(t, "text/plain", message.BasicProperties.ContentType) 29 | } 30 | } 31 | 32 | // 4. serialize to JSON 33 | outputJSON, err := json.Marshal(inputEvent) 34 | if err != nil { 35 | t.Errorf("could not marshal event. details: %v", err) 36 | } 37 | 38 | // 5. check result 39 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 40 | } 41 | 42 | func TestRabbitMQMarshalingMalformedJSON(t *testing.T) { 43 | test.TestMalformedJson(t, RabbitMQEvent{}) 44 | } 45 | -------------------------------------------------------------------------------- /events/s3_object_lambda_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestS3ObjectLambdaEventMarshaling(t *testing.T) { 12 | tests := []struct { 13 | file string 14 | }{ 15 | {"./testdata/s3-object-lambda-event-get-object-iam.json"}, 16 | {"./testdata/s3-object-lambda-event-get-object-assumed-role.json"}, 17 | {"./testdata/s3-object-lambda-event-head-object-iam.json"}, 18 | {"./testdata/s3-object-lambda-event-list-objects-iam.json"}, 19 | {"./testdata/s3-object-lambda-event-list-objects-v2-iam.json"}, 20 | } 21 | 22 | for _, tc := range tests { 23 | tc := tc 24 | t.Run(tc.file, func(t *testing.T) { 25 | inputJSON := test.ReadJSONFromFile(t, tc.file) 26 | 27 | var inputEvent S3ObjectLambdaEvent 28 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 29 | t.Errorf("could not unmarshal event. details: %v", err) 30 | } 31 | 32 | outputJSON, err := json.Marshal(inputEvent) 33 | if err != nil { 34 | t.Errorf("could not marshal event. details: %v", err) 35 | } 36 | 37 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 38 | }) 39 | } 40 | } 41 | 42 | func TestS3ObjectLambdaMarshalingMalformedJson(t *testing.T) { 43 | test.TestMalformedJson(t, S3ObjectLambdaEvent{}) 44 | } 45 | -------------------------------------------------------------------------------- /events/s3_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestS3EventMarshaling(t *testing.T) { 13 | 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/s3-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent S3Event 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. serialize to JSON 24 | outputJSON, err := json.Marshal(inputEvent) 25 | if err != nil { 26 | t.Errorf("could not marshal event. details: %v", err) 27 | } 28 | 29 | // 4. read expected output JSON from file 30 | exepectedOutputJSON := test.ReadJSONFromFile(t, "./testdata/s3-event-with-decoded.json") 31 | 32 | // 5. check result 33 | assert.JSONEq(t, string(exepectedOutputJSON), string(outputJSON)) 34 | } 35 | 36 | func TestS3TestEventMarshaling(t *testing.T) { 37 | inputJSON := []byte(`{ 38 | "Service" :"Amazon S3", 39 | "Event": "s3:TestEvent", 40 | "Time": "2019-02-04T19:34:46.985Z", 41 | "Bucket": "bmoffatt", 42 | "RequestId": "7BA1940DC6AF888B", 43 | "HostId": "q1YDbiaMjllP0m+Lcy6cKKgxNrMLFJ9zCrZUFBqHGTG++0nXvnTDIGC7q2/QPAsJg86E8gI7y9U=" 44 | }`) 45 | var inputEvent S3TestEvent 46 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 47 | t.Errorf("could not marshal event. details: %v", err) 48 | } 49 | outputJSON, err := json.Marshal(inputEvent) 50 | if err != nil { 51 | t.Errorf("could not marshal event. details: %v", err) 52 | } 53 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 54 | } 55 | 56 | func TestS3MarshalingMalformedJSON(t *testing.T) { 57 | test.TestMalformedJson(t, S3Event{}) 58 | } 59 | -------------------------------------------------------------------------------- /events/secretsmanager.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // SecretsManagerSecretRotationEvent is the event passed to a Lambda function to handle 4 | // automatic secret rotation. 5 | // 6 | // https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html#rotate-secrets_how 7 | type SecretsManagerSecretRotationEvent struct { 8 | Step string `json:"Step"` 9 | SecretID string `json:"SecretId"` 10 | ClientRequestToken string `json:"ClientRequestToken"` 11 | RotationToken string `json:"RotationToken"` 12 | } 13 | -------------------------------------------------------------------------------- /events/secretsmanager_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestSecretsManagerSecretRotationEventMarshaling(t *testing.T) { 12 | 13 | // 1. read JSON from file 14 | inputJSON := test.ReadJSONFromFile(t, "./testdata/secretsmanager-secret-rotation-event.json") 15 | 16 | // 2. de-serialize into Go object 17 | var inputEvent SecretsManagerSecretRotationEvent 18 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 19 | t.Errorf("could not unmarshal event. details: %v", err) 20 | } 21 | 22 | // 3. serialize to JSON 23 | outputJSON, err := json.Marshal(inputEvent) 24 | if err != nil { 25 | t.Errorf("could not marshal event. details: %v", err) 26 | } 27 | 28 | // 4. check result 29 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 30 | } 31 | -------------------------------------------------------------------------------- /events/ses_test.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/aws/aws-lambda-go/events/test" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestSESEventMarshaling(t *testing.T) { 12 | 13 | tests := []struct { 14 | file string 15 | }{ 16 | {"./testdata/ses-lambda-event.json"}, 17 | {"./testdata/ses-s3-event.json"}, 18 | {"./testdata/ses-sns-event.json"}, 19 | } 20 | 21 | for _, tc := range tests { 22 | tc := tc 23 | t.Run(tc.file, func(t *testing.T) { 24 | inputJSON := test.ReadJSONFromFile(t, tc.file) 25 | 26 | var inputEvent SimpleEmailEvent 27 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 28 | t.Errorf("could not unmarshal event. details: %v", err) 29 | } 30 | 31 | outputJSON, err := json.Marshal(inputEvent) 32 | if err != nil { 33 | t.Errorf("could not marshal event. details: %v", err) 34 | } 35 | 36 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 37 | }) 38 | } 39 | } 40 | 41 | func TestSESMarshalingMalformedJson(t *testing.T) { 42 | test.TestMalformedJson(t, SimpleEmailEvent{}) 43 | } 44 | -------------------------------------------------------------------------------- /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"` //nolint: stylecheck 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 | -------------------------------------------------------------------------------- /events/sqs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | package events 3 | 4 | import ( 5 | "encoding/json" 6 | "testing" 7 | 8 | "github.com/aws/aws-lambda-go/events/test" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestSqsEventMarshaling(t *testing.T) { 13 | 14 | // 1. read JSON from file 15 | inputJSON := test.ReadJSONFromFile(t, "./testdata/sqs-event.json") 16 | 17 | // 2. de-serialize into Go object 18 | var inputEvent SQSEvent 19 | if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { 20 | t.Errorf("could not unmarshal event. details: %v", err) 21 | } 22 | 23 | // 3. serialize to JSON 24 | outputJSON, err := json.Marshal(inputEvent) 25 | if err != nil { 26 | t.Errorf("could not marshal event. details: %v", err) 27 | } 28 | 29 | // 4. check result 30 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 31 | } 32 | 33 | func TestSqsMarshalingMalformedJson(t *testing.T) { 34 | test.TestMalformedJson(t, SQSEvent{}) 35 | } 36 | -------------------------------------------------------------------------------- /events/streams.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | // KinesisEventResponse is the outer structure to report batch item failures for KinesisEvent. 4 | type KinesisEventResponse struct { 5 | BatchItemFailures []KinesisBatchItemFailure `json:"batchItemFailures"` 6 | } 7 | 8 | // KinesisBatchItemFailure is the individual record which failed processing. 9 | type KinesisBatchItemFailure struct { 10 | ItemIdentifier string `json:"itemIdentifier"` 11 | } 12 | 13 | // DynamoDBEventResponse is the outer structure to report batch item failures for DynamoDBEvent. 14 | type DynamoDBEventResponse struct { 15 | BatchItemFailures []DynamoDBBatchItemFailure `json:"batchItemFailures"` 16 | } 17 | 18 | // DynamoDBBatchItemFailure is the individual record which failed processing. 19 | type DynamoDBBatchItemFailure struct { 20 | ItemIdentifier string `json:"itemIdentifier"` 21 | } 22 | 23 | // SQSEventResponse is the outer structure to report batch item failures for SQSEvent. 24 | type SQSEventResponse struct { 25 | BatchItemFailures []SQSBatchItemFailure `json:"batchItemFailures"` 26 | } 27 | 28 | // SQSBatchItemFailure is the individual record which failed processing. 29 | type SQSBatchItemFailure struct { 30 | ItemIdentifier string `json:"itemIdentifier"` 31 | } 32 | -------------------------------------------------------------------------------- /events/test/assert.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" //nolint: staticcheck 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | // nolint: stylecheck 12 | func AssertJsonFile(t *testing.T, file string, o interface{}) { 13 | inputJSON, err := ioutil.ReadFile(file) 14 | if err != nil { 15 | t.Errorf("could not open test file. details: %v", err) 16 | } 17 | AssertJsonBytes(t, inputJSON, o) 18 | } 19 | 20 | // nolint: stylecheck 21 | func AssertJsonBytes(t *testing.T, inputJSON []byte, o interface{}) { 22 | // de-serialize 23 | if err := json.Unmarshal(inputJSON, o); err != nil { 24 | t.Errorf("could not unmarshal event. details: %v", err) 25 | } 26 | 27 | // serialize to json 28 | outputJSON, err := json.Marshal(o) 29 | if err != nil { 30 | t.Errorf("could not marshal event. details: %v", err) 31 | } 32 | 33 | assert.JSONEq(t, string(inputJSON), string(outputJSON)) 34 | } 35 | -------------------------------------------------------------------------------- /events/test/jsonblobs.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | // nolint: stylecheck 4 | func GetMalformedJson() []byte { 5 | return []byte(`{ "Records`) 6 | } 7 | -------------------------------------------------------------------------------- /events/test/jsoncompare.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package test 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | // AssertJsonsEqual asserts two JSON files are semantically equal 12 | // (ignores white-space and attribute order) 13 | func AssertJsonsEqual(t *testing.T, expectedJSON []byte, actualJSON []byte) { 14 | assert.JSONEq(t, string(expectedJSON), string(actualJSON)) 15 | } 16 | -------------------------------------------------------------------------------- /events/test/jsonsyntax.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package test 4 | 5 | import ( 6 | "encoding/json" 7 | "testing" 8 | ) 9 | 10 | // nolint: stylecheck 11 | func TestMalformedJson(t *testing.T, objectToDeserialize interface{}) { 12 | // 1. read JSON from file 13 | inputJson := GetMalformedJson() 14 | 15 | // 2. de-serialize into Go object 16 | err := json.Unmarshal(inputJson, objectToDeserialize) 17 | if err == nil { 18 | t.Errorf("unmarshal should have failed but succeeded instead") 19 | } 20 | 21 | _, isSyntaxError := err.(*json.SyntaxError) 22 | if !isSyntaxError { 23 | t.Errorf("unmarshal should have returned a json.SyntaxError") 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /events/test/readjson.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "io/ioutil" //nolint: staticcheck 5 | "testing" 6 | ) 7 | 8 | // ReadJSONFromFile reads a given input file to JSON 9 | func ReadJSONFromFile(t *testing.T, inputFile string) []byte { 10 | inputJSON, err := ioutil.ReadFile(inputFile) 11 | if err != nil { 12 | t.Errorf("could not open test file. details: %v", err) 13 | } 14 | 15 | return inputJSON 16 | } 17 | -------------------------------------------------------------------------------- /events/testdata/activemq-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "eventSource": "aws:mq", 3 | "eventSourceArn": "arn:aws:mq:us-west-2:533019413397:broker:shask-test:b-0f5b7522-2b41-4f85-a615-735a4e6d96b5", 4 | "messages": [ 5 | { 6 | "messageID": "ID:b-0f5b7522-2b41-4f85-a615-735a4e6d96b5-2.mq.us-west-2.amazonaws.com-34859-1598944546501-4:12:1:1:3", 7 | "messageType": "jms/text-message", 8 | "timestamp": 1599863938941, 9 | "deliveryMode": 1, 10 | "correlationID": "", 11 | "replyTo": "null", 12 | "destination": { 13 | "physicalName": "testQueue" 14 | }, 15 | "redelivered": false, 16 | "type": "", 17 | "expiration": 0, 18 | "priority": 0, 19 | "data": "RW50ZXIgc29tZSB0ZXh0IGhlcmUgZm9yIHRoZSBtZXNzYWdlIGJvZHkuLi4=", 20 | "brokerInTime": 1599863938943, 21 | "brokerOutTime": 1599863938944, 22 | "properties": {"testKey": "testValue"} 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /events/testdata/alb-lambda-target-request-headers-only.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestContext": { 3 | "elb": { 4 | "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefg" 5 | } 6 | }, 7 | "httpMethod": "GET", 8 | "path": "/", 9 | "queryStringParameters": { 10 | "key": "hello" 11 | }, 12 | "headers": { 13 | "accept": "*/*", 14 | "connection": "keep-alive", 15 | "host": "lambda-test-alb-1334523864.us-east-1.elb.amazonaws.com", 16 | "user-agent": "curl/7.54.0", 17 | "x-amzn-trace-id": "Root=1-5c34e93e-4dea0086f9763ac0667b115a", 18 | "x-forwarded-for": "25.12.198.67", 19 | "x-forwarded-port": "80", 20 | "x-forwarded-proto": "http", 21 | "x-imforwards": "20", 22 | "x-myheader": "123" 23 | }, 24 | "body": "", 25 | "isBase64Encoded": false 26 | } -------------------------------------------------------------------------------- /events/testdata/alb-lambda-target-request-multivalue-headers.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestContext": { 3 | "elb": { 4 | "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh" 5 | } 6 | }, 7 | "httpMethod": "GET", 8 | "path": "/", 9 | "multiValueQueryStringParameters": { 10 | "key": [ 11 | "hello" 12 | ] 13 | }, 14 | "multiValueHeaders": { 15 | "accept": [ 16 | "*/*" 17 | ], 18 | "connection": [ 19 | "keep-alive" 20 | ], 21 | "host": [ 22 | "lambda-test-alb-1234567.us-east-1.elb.amazonaws.com" 23 | ], 24 | "user-agent": [ 25 | "curl/7.54.0" 26 | ], 27 | "x-amzn-trace-id": [ 28 | "Root=1-5c34e7d4-00ca239424b68028d4c56d68" 29 | ], 30 | "x-forwarded-for": [ 31 | "72.21.198.67" 32 | ], 33 | "x-forwarded-port": [ 34 | "80" 35 | ], 36 | "x-forwarded-proto": [ 37 | "http" 38 | ], 39 | "x-imforwards": [ 40 | "20" 41 | ], 42 | "x-myheader": [ 43 | "123" 44 | ] 45 | }, 46 | "body": "", 47 | "isBase64Encoded": false 48 | } -------------------------------------------------------------------------------- /events/testdata/alb-lambda-target-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "isBase64Encoded": false, 3 | "statusCode": 200, 4 | "statusDescription": "200 OK", 5 | "headers": { 6 | "Set-cookie": "cookies", 7 | "Content-Type": "application/json" 8 | }, 9 | "multiValueHeaders": { 10 | "Set-cookie": ["cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly","cookie-name=cookie-value;Expires=May 8, 2019"], 11 | "Content-Type": ["application/json"] 12 | }, 13 | "body": "Hello from Lambda" 14 | } 15 | -------------------------------------------------------------------------------- /events/testdata/apigw-custom-auth-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"TOKEN", 3 | "authorizationToken":"allow", 4 | "methodArn":"arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/" 5 | } -------------------------------------------------------------------------------- /events/testdata/apigw-custom-auth-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "principalId": "yyyyyyyy", 3 | "policyDocument": { 4 | "Version": "2012-10-17", 5 | "Statement": [ 6 | { 7 | "Action": ["execute-api:Invoke"], 8 | "Effect": "Allow|Deny", 9 | "Resource": ["arn:aws:execute-api:{regionId}:{accountId}:{appId}/{stage}/{httpVerb}/[{resource}/[child-resources]]"] 10 | } 11 | ] 12 | }, 13 | "context": { 14 | "stringKey": "value", 15 | "numberKey": "1", 16 | "booleanKey": "true" 17 | }, 18 | "usageIdentifierKey": "{api-key}" 19 | } -------------------------------------------------------------------------------- /events/testdata/apigw-v2-custom-authorizer-v1-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "type": "REQUEST", 4 | "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", 5 | "identitySource": "user1,123", 6 | "authorizationToken": "user1,123", 7 | "resource": "/request", 8 | "path": "/request", 9 | "httpMethod": "GET", 10 | "headers": { 11 | "X-AMZ-Date": "20170718T062915Z", 12 | "Accept": "*/*", 13 | "HeaderAuth1": "headerValue1", 14 | "CloudFront-Viewer-Country": "US", 15 | "CloudFront-Forwarded-Proto": "https", 16 | "CloudFront-Is-Tablet-Viewer": "false", 17 | "CloudFront-Is-Mobile-Viewer": "false", 18 | "User-Agent": "..." 19 | }, 20 | "queryStringParameters": { 21 | "QueryString1": "queryValue1" 22 | }, 23 | "pathParameters": {}, 24 | "stageVariables": { 25 | "StageVar1": "stageValue1" 26 | }, 27 | "requestContext": { 28 | "path": "/request", 29 | "accountId": "123456789012", 30 | "resourceId": "05c7jb", 31 | "stage": "test", 32 | "requestId": "...", 33 | "identity": { 34 | "apiKey": "...", 35 | "sourceIp": "...", 36 | "clientCert": { 37 | "clientCertPem": "CERT_CONTENT", 38 | "subjectDN": "www.example.com", 39 | "issuerDN": "Example issuer", 40 | "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", 41 | "validity": { 42 | "notBefore": "May 28 12:30:02 2019 GMT", 43 | "notAfter": "Aug 5 09:36:04 2021 GMT" 44 | } 45 | } 46 | }, 47 | "resourcePath": "/request", 48 | "httpMethod": "GET", 49 | "apiId": "abcdef123" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /events/testdata/apigw-v2-custom-authorizer-v2-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "type": "REQUEST", 4 | "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", 5 | "identitySource": ["user1", "123"], 6 | "routeKey": "$default", 7 | "rawPath": "/my/path", 8 | "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", 9 | "cookies": ["cookie1", "cookie2"], 10 | "headers": { 11 | "Header1": "value1", 12 | "Header2": "value2" 13 | }, 14 | "queryStringParameters": { 15 | "parameter1": "value1,value2", 16 | "parameter2": "value" 17 | }, 18 | "requestContext": { 19 | "accountId": "123456789012", 20 | "apiId": "api-id", 21 | "authentication": { 22 | "clientCert": { 23 | "clientCertPem": "CERT_CONTENT", 24 | "subjectDN": "www.example.com", 25 | "issuerDN": "Example issuer", 26 | "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", 27 | "validity": { 28 | "notBefore": "May 28 12:30:02 2019 GMT", 29 | "notAfter": "Aug 5 09:36:04 2021 GMT" 30 | } 31 | } 32 | }, 33 | "domainName": "id.execute-api.us-east-1.amazonaws.com", 34 | "domainPrefix": "id", 35 | "http": { 36 | "method": "POST", 37 | "path": "/my/path", 38 | "protocol": "HTTP/1.1", 39 | "sourceIp": "IP", 40 | "userAgent": "agent" 41 | }, 42 | "requestId": "id", 43 | "routeKey": "$default", 44 | "stage": "$default", 45 | "time": "12/Mar/2020:19:03:58 +0000", 46 | "timeEpoch": 1583348638390 47 | }, 48 | "pathParameters": { "parameter1": "value1" }, 49 | "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /events/testdata/apigw-v2-request-no-authorizer.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "routeKey": "$default", 4 | "rawPath": "/", 5 | "rawQueryString": "", 6 | "headers": { 7 | "accept": "*/*", 8 | "content-length": "0", 9 | "host": "aaaaaaaaaa.execute-api.us-west-2.amazonaws.com", 10 | "user-agent": "curl/7.58.0", 11 | "x-amzn-trace-id": "Root=1-5e9f0c65-1de4d666d4dd26aced652b6c", 12 | "x-forwarded-for": "1.2.3.4", 13 | "x-forwarded-port": "443", 14 | "x-forwarded-proto": "https" 15 | }, 16 | "requestContext": { 17 | "accountId": "123456789012", 18 | "apiId": "aaaaaaaaaa", 19 | "authentication": { 20 | "clientCert": { 21 | "clientCertPem": "-----BEGIN CERTIFICATE-----\nMIIEZTCCAk0CAQEwDQ...", 22 | "issuerDN": "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Private CA", 23 | "serialNumber": "1", 24 | "subjectDN": "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Client", 25 | "validity": { 26 | "notAfter": "Aug 5 00:28:21 2120 GMT", 27 | "notBefore": "Aug 29 00:28:21 2020 GMT" 28 | } 29 | } 30 | }, 31 | "domainName": "aaaaaaaaaa.execute-api.us-west-2.amazonaws.com", 32 | "domainPrefix": "aaaaaaaaaa", 33 | "http": { 34 | "method": "GET", 35 | "path": "/", 36 | "protocol": "HTTP/1.1", 37 | "sourceIp": "1.2.3.4", 38 | "userAgent": "curl/7.58.0" 39 | }, 40 | "requestId": "LV7fzho-PHcEJPw=", 41 | "routeKey": "$default", 42 | "stage": "$default", 43 | "time": "21/Apr/2020:15:08:21 +0000", 44 | "timeEpoch": 1587481701067 45 | }, 46 | "isBase64Encoded": false 47 | } 48 | -------------------------------------------------------------------------------- /events/testdata/apigw-websocket-request-disconnect.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "Host": "dl7ptocha9.execute-api.ap-northeast-1.amazonaws.com", 4 | "x-api-key": "", 5 | "X-Forwarded-For": "", 6 | "x-restapi": "" 7 | }, 8 | "multiValueHeaders": { 9 | "Host": [ "dl7ptocha9.execute-api.ap-northeast-1.amazonaws.com" ], 10 | "x-api-key": [ "" ], 11 | "X-Forwarded-For": [ "" ], 12 | "x-restapi": [ "" ] 13 | }, 14 | "requestContext": { 15 | "routeKey": "$disconnect", 16 | "disconnectStatusCode": 1001, 17 | "eventType": "DISCONNECT", 18 | "extendedRequestId": "R1koeHsUtjMFbRw=", 19 | "requestTime": "20/Jan/2024:11:55:08 +0000", 20 | "messageDirection": "IN", 21 | "disconnectReason": "", 22 | "stage": "prod", 23 | "connectedAt": 1705751697419, 24 | "requestTimeEpoch": 1705751708326, 25 | "identity": { 26 | "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", 27 | "sourceIp": "49.105.91.154" 28 | }, 29 | "requestId": "R1koeHsUtjMFbRw=", 30 | "domainName": "dl7ptocha9.execute-api.ap-northeast-1.amazonaws.com", 31 | "connectionId": "R1kmxc2VNjMCFIA=", 32 | "apiId": "dl7ptocha9" 33 | }, 34 | "isBase64Encoded": false 35 | } 36 | -------------------------------------------------------------------------------- /events/testdata/apigw-websocket-request-send-message.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestContext": { 3 | "routeKey": "$default", 4 | "messageId": "R1knPc2ntjMCFIA=", 5 | "eventType": "MESSAGE", 6 | "extendedRequestId": "R1knPH17NjMFftw=", 7 | "requestTime": "20/Jan/2024:11:55:00 +0000", 8 | "messageDirection": "IN", 9 | "stage": "prod", 10 | "connectedAt": 1705751697419, 11 | "requestTimeEpoch": 1705751700453, 12 | "identity": { 13 | "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", 14 | "sourceIp": "49.105.91.154" 15 | }, 16 | "requestId": "R1knPH17NjMFftw=", 17 | "domainName": "dl7ptocha9.execute-api.ap-northeast-1.amazonaws.com", 18 | "connectionId": "R1kmxc2VNjMCFIA=", 19 | "apiId": "gy415nuibc" 20 | }, 21 | "body": "{\r\n\t\"a\": 1\r\n}", 22 | "isBase64Encoded": false 23 | } 24 | -------------------------------------------------------------------------------- /events/testdata/appsync-identity-cognito.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub": "123-456", 3 | "issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc", 4 | "username": "user1", 5 | "claims": { 6 | "sub": "123-456", 7 | "aud": "abcdefg", 8 | "event_id": "123-123-123", 9 | "token_use": "id", 10 | "auth_time": 1551226125, 11 | "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc", 12 | "cognito:username": "user1", 13 | "exp": 1551228178628, 14 | "iat": 1551228178629 15 | }, 16 | "sourceIp": ["192.168.196.186", "193.168.196.186"], 17 | "defaultAuthStrategy": "ALLOW" 18 | } 19 | -------------------------------------------------------------------------------- /events/testdata/appsync-identity-iam.json: -------------------------------------------------------------------------------- 1 | { 2 | "accountId": "accountid123", 3 | "cognitoIdentityPoolId": "identitypoolid123", 4 | "cognitoIdentityId": "identityid123", 5 | "cognitoIdentityAuthType": "authenticated", 6 | "cognitoIdentityAuthProvider": "providerABC", 7 | "sourceIp": ["192.168.196.186", "193.168.196.186"], 8 | "username": "user1", 9 | "userArn": "arn:aws:iam::123456789012:user/appsync" 10 | } 11 | -------------------------------------------------------------------------------- /events/testdata/appsync-lambda-auth-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "authorizationToken": "ExampleAUTHtoken123123123", 3 | "requestContext": { 4 | "apiId": "aaaaaa123123123example123", 5 | "accountId": "111122223333", 6 | "requestId": "f4081827-1111-4444-5555-5cf4695f339f", 7 | "queryString": "mutation CreateEvent {...}\n\nquery MyQuery {...}\n", 8 | "operationName": "MyQuery", 9 | "variables": {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /events/testdata/appsync-lambda-auth-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "isAuthorized": true, 3 | "resolverContext": { 4 | "banana": "very yellow", 5 | "apple": "very green" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-launch-successful.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance Launch Successful", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn", 11 | "instance-arn" 12 | ], 13 | "detail": { 14 | "StatusCode": "InProgress", 15 | "Description": "Launching a new EC2 instance: i-12345678", 16 | "AutoScalingGroupName": "my-auto-scaling-group", 17 | "ActivityId": "87654321-4321-4321-4321-210987654321", 18 | "Details": { 19 | "Availability Zone": "us-west-2b", 20 | "Subnet ID": "subnet-12345678" 21 | }, 22 | "RequestId": "12345678-1234-1234-1234-123456789012", 23 | "StatusMessage": "", 24 | "EndTime": "1970-01-01T00:00:00Z", 25 | "EC2InstanceId": "i-1234567890abcdef0", 26 | "StartTime": "1970-01-01T00:00:00Z", 27 | "Cause": "description-text" 28 | } 29 | } -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-launch-unsuccessful.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance Launch Unsuccessful", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn", 11 | "instance-arn" 12 | ], 13 | "detail": { 14 | "StatusCode": "Failed", 15 | "AutoScalingGroupName": "my-auto-scaling-group", 16 | "ActivityId": "87654321-4321-4321-4321-210987654321", 17 | "Details": { 18 | "Availability Zone": "us-west-2b", 19 | "Subnet ID": "subnet-12345678" 20 | }, 21 | "RequestId": "12345678-1234-1234-1234-123456789012", 22 | "StatusMessage": "message-text", 23 | "EndTime": "1970-01-01T00:00:00Z", 24 | "EC2InstanceId": "i-1234567890abcdef0", 25 | "StartTime": "1970-01-01T00:00:00Z", 26 | "Cause": "description-text" 27 | } 28 | } -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-lifecycle-action.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance-launch Lifecycle Action", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn" 11 | ], 12 | "detail": { 13 | "LifecycleActionToken": "87654321-4321-4321-4321-210987654321", 14 | "AutoScalingGroupName": "my-asg", 15 | "LifecycleHookName": "my-lifecycle-hook", 16 | "EC2InstanceId": "i-1234567890abcdef0", 17 | "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING", 18 | "NotificationMetadata": "additional-info" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-terminate-action.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance-terminate Lifecycle Action", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn" 11 | ], 12 | "detail": { 13 | "LifecycleActionToken":"87654321-4321-4321-4321-210987654321", 14 | "AutoScalingGroupName":"my-asg", 15 | "LifecycleHookName":"my-lifecycle-hook", 16 | "EC2InstanceId":"i-1234567890abcdef0", 17 | "LifecycleTransition":"autoscaling:EC2_INSTANCE_TERMINATING" 18 | } 19 | } -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-terminate-successful.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance Terminate Successful", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn", 11 | "instance-arn" 12 | ], 13 | "detail": { 14 | "StatusCode": "InProgress", 15 | "Description": "Terminating EC2 instance: i-12345678", 16 | "AutoScalingGroupName": "my-auto-scaling-group", 17 | "ActivityId": "87654321-4321-4321-4321-210987654321", 18 | "Details": { 19 | "Availability Zone": "us-west-2b", 20 | "Subnet ID": "subnet-12345678" 21 | }, 22 | "RequestId": "12345678-1234-1234-1234-123456789012", 23 | "StatusMessage": "", 24 | "EndTime": "1970-01-01T00:00:00Z", 25 | "EC2InstanceId": "i-1234567890abcdef0", 26 | "StartTime": "1970-01-01T00:00:00Z", 27 | "Cause": "description-text" 28 | } 29 | } -------------------------------------------------------------------------------- /events/testdata/autoscaling-event-terminate-unsuccessful.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "12345678-1234-1234-1234-123456789012", 4 | "detail-type": "EC2 Instance Terminate Unsuccessful", 5 | "source": "aws.autoscaling", 6 | "account": "123456789012", 7 | "time": "1970-01-01T00:00:00Z", 8 | "region": "us-west-2", 9 | "resources": [ 10 | "auto-scaling-group-arn", 11 | "instance-arn" 12 | ], 13 | "detail": { 14 | "StatusCode": "Failed", 15 | "AutoScalingGroupName": "my-auto-scaling-group", 16 | "ActivityId": "87654321-4321-4321-4321-210987654321", 17 | "Details": { 18 | "Availability Zone": "us-west-2b", 19 | "Subnet ID": "subnet-12345678" 20 | }, 21 | "RequestId": "12345678-1234-1234-1234-123456789012", 22 | "StatusMessage": "message-text", 23 | "EndTime": "1970-01-01T00:00:00Z", 24 | "EC2InstanceId": "i-1234567890abcdef0", 25 | "StartTime": "1970-01-01T00:00:00Z", 26 | "Cause": "description-text" 27 | } 28 | } -------------------------------------------------------------------------------- /events/testdata/clientvpn-connectionhandler-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "connection-id": "cvpn-connection-04e7e1b2f0daf9460", 3 | "endpoint-id": "cvpn-endpoint-0f13eab7f860433cc", 4 | "common-name": "", 5 | "username": "username", 6 | "platform": "", 7 | "platform-version": "", 8 | "public-ip": "10.11.12.13", 9 | "client-openvpn-version": "", 10 | "schema-version": "v1" 11 | } 12 | -------------------------------------------------------------------------------- /events/testdata/cloudwatch-alarm-sns-payload-multiple-metrics.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "EventSource": "aws:sns", 5 | "EventVersion": "1.0", 6 | "EventSubscriptionArn": "arn:aws:sns:EXAMPLE", 7 | "Sns": { 8 | "Type": "Notification", 9 | "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", 10 | "TopicArn": "arn:aws:sns:EXAMPLE", 11 | "Subject": "TestInvoke", 12 | "Message": "{\"AlarmName\":\"EXAMPLE\",\"AlarmDescription\":\"EXAMPLE\",\"AWSAccountId\":\"EXAMPLE\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 out of the last 1 datapoints [1234.0 (06/03/15 17:43:27)] was greater than the threshold (0.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\":\"2015-06-03T17:43:27.123+0000\",\"Region\":\"EXAMPLE\",\"AlarmArn\":\"arn:aws:cloudwatch:REGION:ACCOUNT_NUMBER:alarm:EXAMPLE\",\"OldStateValue\":\"INSUFFICIENT_DATA\",\"Trigger\":{\"Period\":60,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanThreshold\",\"Threshold\":0.0,\"TreatMissingData\":\"- TreatMissingData: missing\",\"EvaluateLowSampleCountPercentile\":\"\",\"Metrics\":[{\"Expression\":\"m1*1\",\"Id\":\"e1\",\"Label\":\"Expression1\",\"ReturnData\":true},{\"Id\":\"m1\",\"MetricStat\":{\"Metric\":{\"Dimensions\":[{\"value\":\"TestInstance\",\"name\":\"InstanceId\"}],\"MetricName\":\"NetworkOut\",\"Namespace\":\"AWS/EC2\"},\"Period\":60,\"Stat\":\"Average\"},\"ReturnData\":false}]}}", 13 | "Timestamp": "2015-06-03T17:43:27.123Z", 14 | "SignatureVersion": "1", 15 | "Signature": "EXAMPLE", 16 | "SigningCertUrl": "EXAMPLE", 17 | "UnsubscribeUrl": "EXAMPLE", 18 | "MessageAttributes": {} 19 | } 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /events/testdata/cloudwatch-alarm-sns-payload-single-metric.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "EventSource": "aws:sns", 5 | "EventVersion": "1.0", 6 | "EventSubscriptionArn": "arn:aws:sns:EXAMPLE", 7 | "Sns": { 8 | "Type": "Notification", 9 | "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", 10 | "TopicArn": "arn:aws:sns:EXAMPLE", 11 | "Subject": "TestInvoke", 12 | "Message": "{\"AlarmName\": \"EXAMPLE\",\"AlarmDescription\": \"EXAMPLE\",\"AWSAccountId\": \"123456789012\",\"NewStateValue\": \"ALARM\",\"NewStateReason\": \"Threshold Crossed: 1 out of the last 1 datapoints [1234.0 (06/03/15 17:43:27)] was greater than the threshold (0.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\": \"2015-06-03T17:43:27.123+0000\",\"Region\": \"EXAMPLE\",\"AlarmArn\": \"arn:aws:cloudwatch:REGION:ACCOUNT_NUMBER:alarm:EXAMPLE\",\"OldStateValue\": \"INSUFFICIENT_DATA\",\"Trigger\": {\"MetricName\": \"NetworkOut\",\"Namespace\": \"AWS/EC2\",\"StatisticType\": \"Statistic\",\"Statistic\": \"AVERAGE\",\"Unit\": \"Bytes\",\"Dimensions\": [{\"value\": \"TestInstance\",\"name\": \"InstanceId\"}],\"Period\": 60,\"EvaluationPeriods\": 1,\"ComparisonOperator\": \"GreaterThanThreshold\",\"Threshold\": 0.0,\"TreatMissingData\": \"- TreatMissingData: missing\",\"EvaluateLowSampleCountPercentile\": \"\"}}", 13 | "Timestamp": "2015-06-03T17:43:27.123Z", 14 | "SignatureVersion": "1", 15 | "Signature": "EXAMPLE", 16 | "SigningCertUrl": "EXAMPLE", 17 | "UnsubscribeUrl": "EXAMPLE", 18 | "MessageAttributes": {} 19 | } 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /events/testdata/cloudwatch-logs-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "awslogs": { 3 | "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA==" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /events/testdata/code-commit-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "eventId": "5a824061-17ca-46a9-bbf9-114edeadbeef", 5 | "eventVersion": "1.0", 6 | "eventTime": "2018-01-26T15:58:33.475+0000", 7 | "eventTriggerName": "my-trigger", 8 | "eventPartNumber": 1, 9 | "codecommit": { 10 | "references": [ 11 | { 12 | "commit": "5c4ef1049f1d27deadbeeff313e0730018be182b", 13 | "ref": "refs/heads/master" 14 | } 15 | ] 16 | }, 17 | "eventName": "TriggerEventTest", 18 | "eventTriggerConfigId": "5a824061-17ca-46a9-bbf9-114edeadbeef", 19 | "eventSourceARN": "arn:aws:codecommit:us-east-1:123456789012:my-repo", 20 | "userIdentityARN": "arn:aws:iam::123456789012:root", 21 | "eventSource": "aws:codecommit", 22 | "awsRegion": "us-east-1", 23 | "eventTotalParts": 1 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /events/testdata/codedeploy-deployment-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": "123456789012", 3 | "region": "us-east-1", 4 | "detail-type": "CodeDeploy Deployment State-change Notification", 5 | "source": "aws.codedeploy", 6 | "version": "0", 7 | "time": "2016-06-30T22:06:31Z", 8 | "id": "c071bfbf-83c4-49ca-a6ff-3df053957145", 9 | "resources": [ 10 | "arn:aws:codedeploy:us-east-1:123456789012:application:myApplication", 11 | "arn:aws:codedeploy:us-east-1:123456789012:deploymentgroup:myApplication/myDeploymentGroup" 12 | ], 13 | "detail": { 14 | "instanceGroupId": "9fd2fbef-2157-40d8-91e7-6845af69e2d2", 15 | "region": "us-east-1", 16 | "application": "myApplication", 17 | "deploymentId": "d-123456789", 18 | "state": "SUCCESS", 19 | "deploymentGroup": "myDeploymentGroup" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /events/testdata/codedeploy-instance-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": "123456789012", 3 | "region": "us-east-1", 4 | "detail-type": "CodeDeploy Instance State-change Notification", 5 | "source": "aws.codedeploy", 6 | "version": "0", 7 | "time": "2016-06-30T23:18:50Z", 8 | "id": "fb1d3015-c091-4bf9-95e2-d98521ab2ecb", 9 | "resources": [ 10 | "arn:aws:ec2:us-east-1:123456789012:instance/i-0000000aaaaaaaaaa", 11 | "arn:aws:codedeploy:us-east-1:123456789012:deploymentgroup:myApplication/myDeploymentGroup", 12 | "arn:aws:codedeploy:us-east-1:123456789012:application:myApplication" 13 | ], 14 | "detail": { 15 | "instanceId": "i-0000000aaaaaaaaaa", 16 | "region": "us-east-1", 17 | "state": "SUCCESS", 18 | "application": "myApplication", 19 | "deploymentId": "d-123456789", 20 | "instanceGroupId": "8cd3bfa8-9e72-4cbe-a1e5-da4efc7efd49", 21 | "deploymentGroup": "myDeploymentGroup" 22 | } 23 | } -------------------------------------------------------------------------------- /events/testdata/codepipeline-action-execution-stage-change-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "CWE-event-id", 4 | "detail-type": "CodePipeline Action Execution State Change", 5 | "source": "aws.codepipeline", 6 | "account": "123456789012", 7 | "time": "2017-04-22T03:31:47Z", 8 | "region": "us-east-1", 9 | "resources": [ 10 | "arn:aws:codepipeline:us-east-1:123456789012:pipeline:myPipeline" 11 | ], 12 | "detail": { 13 | "pipeline": "myPipeline", 14 | "version": 1, 15 | "execution-id": "01234567-0123-0123-0123-012345678901", 16 | "stage": "Prod", 17 | "action": "myAction", 18 | "state": "STARTED", 19 | "region":"us-west-2", 20 | "type": { 21 | "owner": "AWS", 22 | "category": "Deploy", 23 | "provider": "CodeDeploy", 24 | "version": 1 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /events/testdata/codepipeline-execution-stage-change-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "CWE-event-id", 4 | "detail-type": "CodePipeline Stage Execution State Change", 5 | "source": "aws.codepipeline", 6 | "account": "123456789012", 7 | "time": "2017-04-22T03:31:47Z", 8 | "region": "us-east-1", 9 | "resources": [ 10 | "arn:aws:codepipeline:us-east-1:123456789012:pipeline:myPipeline" 11 | ], 12 | "detail": { 13 | "pipeline": "myPipeline", 14 | "version": 1, 15 | "state": "STARTED", 16 | "execution-id": "01234567-0123-0123-0123-012345678901" 17 | } 18 | } -------------------------------------------------------------------------------- /events/testdata/codepipeline-execution-state-change-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "CWE-event-id", 4 | "detail-type": "CodePipeline Pipeline Execution State Change", 5 | "source": "aws.codepipeline", 6 | "account": "123456789012", 7 | "time": "2017-04-22T03:31:47Z", 8 | "region": "us-east-1", 9 | "resources": [ 10 | "arn:aws:codepipeline:us-east-1:123456789012:pipeline:myPipeline" 11 | ], 12 | "detail": { 13 | "pipeline": "myPipeline", 14 | "version": 1, 15 | "state": "STARTED", 16 | "execution-id": "01234567-0123-0123-0123-012345678901" 17 | } 18 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-create-auth-challenge.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "region": "us-west-2", 4 | "userPoolId": "", 5 | "userName": "", 6 | "callerContext": { 7 | "awsSdkVersion": "aws-sdk-unknown-unknown", 8 | "clientId": "" 9 | }, 10 | "triggerSource": "CreateAuthChallenge_Authentication", 11 | "request": { 12 | "userAttributes": { 13 | "sub": "", 14 | "cognito:user_status": "CONFIRMED", 15 | "phone_number_verified": "true", 16 | "cognito:phone_number_alias": "+12223334455", 17 | "phone_number": "+12223334455" 18 | }, 19 | "challengeName": "CUSTOM_CHALLENGE", 20 | "session": [ 21 | { 22 | "challengeName": "PASSWORD_VERIFIER", 23 | "challengeResult": true, 24 | "challengeMetadata": "metadata" 25 | } 26 | ], 27 | "clientMetadata": { 28 | "exampleMetadataKey": "example metadata value" 29 | } 30 | }, 31 | "response": { 32 | "publicChallengeParameters": { 33 | "a": "b" 34 | }, 35 | "privateChallengeParameters": { 36 | "c": "d" 37 | }, 38 | "challengeMetadata": "challengeMetadata" 39 | } 40 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-custommessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "CustomMessage_SignUp/CustomMessage_ResendCode/CustomMessage_ForgotPassword/CustomMessage_VerifyUserAttribute", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "userAttributes": { 13 | "phone_number_verified": true, 14 | "email_verified": false 15 | }, 16 | "codeParameter": "####", 17 | "usernameParameter": "{username}", 18 | "clientMetadata": { 19 | "exampleMetadataKey": "example metadata value" 20 | } 21 | }, 22 | "response": { 23 | "smsMessage": "", 24 | "emailMessage": "", 25 | "emailSubject": "" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-define-auth-challenge.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "region": "us-west-2", 4 | "userPoolId": "", 5 | "userName": "", 6 | "callerContext": { 7 | "awsSdkVersion": "aws-sdk-unknown-unknown", 8 | "clientId": "" 9 | }, 10 | "triggerSource": "DefineAuthChallenge_Authentication", 11 | "request": { 12 | "userAttributes": { 13 | "sub": "", 14 | "cognito:user_status": "CONFIRMED", 15 | "phone_number_verified": "true", 16 | "cognito:phone_number_alias": "+12223334455", 17 | "phone_number": "+12223334455" 18 | }, 19 | "session": [ 20 | { 21 | "challengeName": "PASSWORD_VERIFIER", 22 | "challengeResult": true, 23 | "challengeMetadata": "metadata" 24 | } 25 | ], 26 | "clientMetadata": { 27 | "exampleMetadataKey": "example metadata value" 28 | }, 29 | "userNotFound": false 30 | }, 31 | "response": { 32 | "challengeName": "challengeName", 33 | "issueTokens": true, 34 | "failAuthentication": true 35 | } 36 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-migrateuser.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "UserMigration_Authentication", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "password": "", 13 | "validationData": { 14 | "exampleMetadataKey": "example metadata value" 15 | }, 16 | "clientMetadata": { 17 | "exampleMetadataKey": "example metadata value" 18 | } 19 | }, 20 | "response": { 21 | "userAttributes": { 22 | "email": "", 23 | "phone_number": "" 24 | }, 25 | "finalUserStatus": "", 26 | "messageAction": "", 27 | "desiredDeliveryMediums": [ 28 | "", 29 | "" 30 | ], 31 | "forceAliasCreation": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-postauthentication.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "PostAuthentication_Authentication", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "newDeviceUsed": true, 13 | "userAttributes" : { 14 | "email": "", 15 | "phone_number": "" 16 | }, 17 | "clientMetadata": { 18 | "exampleMetadataKey": "example metadata value" 19 | } 20 | }, 21 | "response": {} 22 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-postconfirmation.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "PostConfirmation_ConfirmSignUp", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "userAttributes" : { 13 | "email": "", 14 | "phone_number": "" 15 | }, 16 | "clientMetadata": { 17 | "exampleMetadataKey": "example metadata value" 18 | } 19 | }, 20 | "response": {} 21 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-preauthentication.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "PreAuthentication_Authentication", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "userAttributes": { 13 | "email": "" 14 | }, 15 | "validationData": { 16 | "k1": "v1", 17 | "k2": "v2" 18 | } 19 | }, 20 | "response": {} 21 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-presignup.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "PreSignUp_SignUp", 4 | "region": "", 5 | "userPoolId": "", 6 | "userName": "", 7 | "callerContext": { 8 | "awsSdkVersion": "", 9 | "clientId": "" 10 | }, 11 | "request": { 12 | "userAttributes": { 13 | "email": "", 14 | "phone_number": "" 15 | }, 16 | "validationData": { 17 | "k1": "v1", 18 | "k2": "v2" 19 | }, 20 | "clientMetadata": { 21 | "exampleMetadataKey": "example metadata value" 22 | } 23 | }, 24 | "response": { 25 | "autoConfirmUser": false, 26 | "autoVerifyEmail": true, 27 | "autoVerifyPhone": true 28 | } 29 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-pretokengen.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "triggerSource": "PreTokenGen", 4 | "region": "region", 5 | "userPoolId": "userPoolId", 6 | "userName": "userName", 7 | "callerContext": { 8 | "awsSdkVersion": "calling aws sdk with version", 9 | "clientId": "apps client id" 10 | }, 11 | "request": { 12 | "userAttributes": { 13 | "email": "email", 14 | "phone_number": "phone_number" 15 | }, 16 | "groupConfiguration": { 17 | "groupsToOverride": ["group-A", "group-B", "group-C"], 18 | "iamRolesToOverride": ["arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA", "arn:aws:iam::XXXXXXXXX:role/sns_callerB", "arn:aws:iam::XXXXXXXXXX:role/sns_callerC"], 19 | "preferredRole": "arn:aws:iam::XXXXXXXXXXX:role/sns_caller" 20 | }, 21 | "clientMetadata": { 22 | "exampleMetadataKey": "example metadata value" 23 | } 24 | }, 25 | "response": { 26 | "claimsOverrideDetails": { 27 | "claimsToAddOrOverride": { 28 | "attribute_key2": "attribute_value2", 29 | "attribute_key": "attribute_value" 30 | }, 31 | "claimsToSuppress": ["email"], 32 | "groupOverrideDetails": { 33 | "groupsToOverride": ["group-A", "group-B", "group-C"], 34 | "iamRolesToOverride": ["arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA", "arn:aws:iam::XXXXXXXXX:role/sns_callerB", "arn:aws:iam::XXXXXXXXXX:role/sns_callerC"], 35 | "preferredRole": "arn:aws:iam::XXXXXXXXXXX:role/sns_caller" 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /events/testdata/cognito-event-userpools-verify-auth-challenge.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "region": "us-west-2", 4 | "userPoolId": "", 5 | "userName": "", 6 | "callerContext": { 7 | "awsSdkVersion": "aws-sdk-unknown-unknown", 8 | "clientId": "" 9 | }, 10 | "triggerSource": "VerifyAuthChallengeResponse_Authentication", 11 | "request": { 12 | "userAttributes": { 13 | "sub": "", 14 | "cognito:user_status": "CONFIRMED", 15 | "phone_number_verified": "true", 16 | "cognito:phone_number_alias": "+12223334455", 17 | "phone_number": "+12223334455" 18 | }, 19 | "privateChallengeParameters": { 20 | "secret": "11122233" 21 | }, 22 | "challengeAnswer": "123xxxx", 23 | "clientMetadata": { 24 | "exampleMetadataKey": "example metadata value" 25 | } 26 | }, 27 | "response": { 28 | "answerCorrect": true 29 | } 30 | } -------------------------------------------------------------------------------- /events/testdata/cognito-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "datasetName": "datasetName", 3 | "eventType": "SyncTrigger", 4 | "region": "us-east-1", 5 | "identityId": "identityId", 6 | "datasetRecords": 7 | { 8 | "SampleKey1": 9 | { 10 | "newValue": "newValue1", 11 | "oldValue": "oldValue1", 12 | "op": "replace" 13 | } 14 | }, 15 | "identityPoolId": "identityPoolId", 16 | "version": 2 17 | } -------------------------------------------------------------------------------- /events/testdata/config-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "configRuleId": "config-rule-0123456", 3 | "version": "1.0", 4 | "configRuleName": "periodic-config-rule", 5 | "configRuleArn": "arn:aws:config:us-east-1:012345678912:config-rule/config-rule-0123456", 6 | "invokingEvent": "{\"configSnapshotId\":\"00000000-0000-0000-0000-000000000000\",\"s3ObjectKey\":\"AWSLogs/000000000000/Config/us-east-1/2016/2/24/ConfigSnapshot/000000000000_Config_us-east-1_ConfigSnapshot_20160224T182319Z_00000000-0000-0000-0000-000000000000.json.gz\",\"s3Bucket\":\"config-bucket\",\"notificationCreationTime\":\"2016-02-24T18:23:20.328Z\",\"messageType\":\"ConfigurationSnapshotDeliveryCompleted\",\"recordVersion\":\"1.1\"}", 7 | "resultToken": "myResultToken", 8 | "eventLeftScope": false, 9 | "ruleParameters": "{\"myParameterKey\":\"myParameterValue\"}", 10 | "executionRoleArn": "arn:aws:iam::012345678912:role/config-role", 11 | "accountId": "012345678912" 12 | } 13 | -------------------------------------------------------------------------------- /events/testdata/connect-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"ContactFlowExecution", 3 | "Details":{ 4 | "Parameters":{ 5 | "key1":"value1", 6 | "key2":"value2" 7 | }, 8 | "ContactData":{ 9 | "ContactId":"ASDAcxcasDFSSDFs", 10 | "InitialContactId":"Acxsada-asdasdaxA", 11 | "PreviousContactId":"Acxsada-asdasdaxA", 12 | "Channel":"Voice", 13 | "InstanceARN": "", 14 | "InitiationMethod":"INBOUND/OUTBOUND/TRANSFER/CALLBACK", 15 | "SystemEndpoint":{ 16 | "Type":"TELEPHONE_NUMBER", 17 | "Address":"01234567" 18 | }, 19 | "CustomerEndpoint":{ 20 | "Type":"TELEPHONE_NUMBER", 21 | "Address":"+14802021091" 22 | }, 23 | "Queue" : { 24 | "Name":"PrimaryPhoneQueue", 25 | "ARN" : "" 26 | }, 27 | 28 | "Attributes":{ 29 | "key1":"value", 30 | "key2":"value" 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /events/testdata/ecr-image-push-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "13cde686-328b-6117-af20-0e5566167482", 4 | "detail-type": "ECR Image Action", 5 | "source": "aws.ecr", 6 | "account": "123456789012", 7 | "time": "2019-11-16T01:54:34Z", 8 | "region": "us-west-2", 9 | "resources": [], 10 | "detail": { 11 | "result": "SUCCESS", 12 | "repository-name": "my-repository-name", 13 | "image-digest": "sha256:7f5b2640fe6fb4f46592dfd3410c4a79dac4f89e4782432e0378abcd1234", 14 | "action-type": "PUSH", 15 | "image-tag": "latest" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /events/testdata/ecr-image-scan-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0", 3 | "id": "01234567-0123-0123-0123-012345678901", 4 | "detail-type": "ECR Image Scan", 5 | "source": "aws.ecr", 6 | "account": "123456789012", 7 | "time": "2019-10-30T21:32:27Z", 8 | "region": "eu-north-1", 9 | "resources": ["arn:aws:ecr:eu-north-1:123456789012:repository/tribble-image-scan-test"], 10 | "detail": { 11 | "scan-status": "COMPLETE", 12 | "repository-name": "tribble-image-scan-test", 13 | "finding-severity-counts": { 14 | "CRITICAL": 10, 15 | "HIGH": 2, 16 | "MEDIUM": 9, 17 | "LOW": 3, 18 | "INFORMATIONAL": 0, 19 | "UNDEFINED": 0 20 | }, 21 | "image-digest": "sha256:d4a96ee9443e641fc100e763a0c10928720b50c6e3ea3342d05d7c3435fc5355", 22 | "image-tags": ["1572471135"] 23 | } 24 | } -------------------------------------------------------------------------------- /events/testdata/iot-1-click-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "deviceEvent": { 3 | "buttonClicked": { 4 | "clickType": "SINGLE", 5 | "reportedTime": "2018-05-04T23:26:33.747Z" 6 | } 7 | }, 8 | "deviceInfo": { 9 | "attributes": { 10 | "key3": "value3", 11 | "key1": "value1", 12 | "key4": "value4" 13 | }, 14 | "type": "button", 15 | "deviceId": "G030PMXXXXXXXXXX", 16 | "remainingLife": 5.00 17 | }, 18 | "placementInfo": { 19 | "projectName": "test", 20 | "placementName": "myPlacement", 21 | "attributes": { 22 | "location": "Seattle", 23 | "equipment": "printer" 24 | }, 25 | "devices": { 26 | "myButton": "G030PMXXXXXXXXXX" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /events/testdata/iot-button-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "serialNumber": "ABCDEFG12345", 3 | "clickType": "SINGLE", 4 | "batteryVoltage": "2000 mV" 5 | } -------------------------------------------------------------------------------- /events/testdata/iot-custom-auth-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "token" :"aToken", 3 | "signatureVerified": true, 4 | "protocols": ["tls", "http", "mqtt"], 5 | "protocolData": { 6 | "tls" : { 7 | "serverName": "serverName" 8 | }, 9 | "http": { 10 | "headers": { 11 | "X-Request-ID": "abc123" 12 | }, 13 | "queryString": "?foo=bar" 14 | }, 15 | "mqtt": { 16 | "username": "myUserName", 17 | "password": "bXlQYXNzd29yZA==", 18 | "clientId": "myClientId" 19 | } 20 | }, 21 | "connectionMetadata": { 22 | "id": "e56f08c3-c559-490f-aa9f-7e8427d0f57b" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /events/testdata/iot-custom-auth-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "isAuthenticated":true, 3 | "principalId": "xxxxxxxx", 4 | "disconnectAfterInSeconds": 86400, 5 | "refreshAfterInSeconds": 300, 6 | "policyDocuments": [ 7 | { 8 | "Version": "2012-10-17", 9 | "Statement": [ 10 | { 11 | "Action": ["iot:Publish"], 12 | "Effect": "Allow", 13 | "Resource": ["arn:aws:iot:us-east-1::topic/customauthtesting"] 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /events/testdata/iot-preprovision-hook-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "claimCertificateId" : "string", 3 | "certificateId" : "string", 4 | "certificatePem" : "string", 5 | "templateArn" : "arn:aws:iot:us-east-1:1234567890:provisioningtemplate/MyTemplate", 6 | "clientId" : "221a6d10-9c7f-42f1-9153-e52e6fc869c1", 7 | "parameters" : { 8 | "param1" : "parma1value", 9 | "param2" : "param2value" 10 | } 11 | } -------------------------------------------------------------------------------- /events/testdata/iot-preprovision-hook-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowProvisioning": true, 3 | "parameterOverrides" : { 4 | "Key1": "newCustomValue1", 5 | "Key2": "newCustomValue2" 6 | } 7 | } -------------------------------------------------------------------------------- /events/testdata/kafka-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "eventSource": "aws:kafka", 3 | "eventSourceArn": "arn:aws:kafka:us-west-2:012345678901:cluster/ExampleMSKCluster/e9f754c6-d29a-4430-a7db-958a19fd2c54-4", 4 | "bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", 5 | "records": { 6 | "AWSKafkaTopic-0": [ 7 | { 8 | "topic": "AWSKafkaTopic", 9 | "partition": 0, 10 | "offset": 0, 11 | "timestamp": 1595035749700, 12 | "timestampType": "CREATE_TIME", 13 | "key": "OGQ1NTk2YjQtMTgxMy00MjM4LWIyNGItNmRhZDhlM2QxYzBj", 14 | "value": "OGQ1NTk2YjQtMTgxMy00MjM4LWIyNGItNmRhZDhlM2QxYzBj", 15 | "headers": [ 16 | { 17 | "headerKey": [ 18 | 118, 19 | -36, 20 | 0, 21 | 127, 22 | -128 23 | ] 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /events/testdata/kinesis-analytics-output-delivery-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "invocationId": "invocationIdExample", 3 | "applicationArn": "arn:aws:kinesisanalytics:us-west-2:123456789012:application/example-application", 4 | "records": [ 5 | { 6 | "recordId": "49571347871967966406409637155186850213682522142927749122", 7 | "data": "VGhpcyBpcyBhIHRlc3QgZnJvbSBLaW5lc2lzIEFuYWx5dGljcw==" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /events/testdata/kinesis-analytics-output-delivery-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "records": [ 3 | { 4 | "recordId": "49571347871967966406409637155186850213682522142927749122", 5 | "result": "Ok" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /events/testdata/kinesis-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "kinesis": { 5 | "kinesisSchemaVersion": "1.0", 6 | "partitionKey": "s1", 7 | "sequenceNumber": "49568167373333333333333333333333333333333333333333333333", 8 | "data": "SGVsbG8gV29ybGQ=", 9 | "approximateArrivalTimestamp": 1480641523.477 10 | }, 11 | "eventSource": "aws:kinesis", 12 | "eventVersion": "1.0", 13 | "eventID": "shardId-000000000000:49568167373333333333333333333333333333333333333333333333", 14 | "eventName": "aws:kinesis:record", 15 | "invokeIdentityArn": "arn:aws:iam::123456789012:role/LambdaRole", 16 | "awsRegion": "us-east-1", 17 | "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/simple-stream" 18 | }, 19 | { 20 | "kinesis": { 21 | "kinesisSchemaVersion": "1.0", 22 | "partitionKey": "s1", 23 | "sequenceNumber": "49568167373333333334444444444444444444444444444444444444", 24 | "data": "SGVsbG8gV29ybGQ=", 25 | "approximateArrivalTimestamp": 1480841523.477 26 | }, 27 | "eventSource": "aws:kinesis", 28 | "eventVersion": "1.0", 29 | "eventID": "shardId-000000000000:49568167373333333334444444444444444444444444444444444444", 30 | "eventName": "aws:kinesis:record", 31 | "invokeIdentityArn": "arn:aws:iam::123456789012:role/LambdaRole", 32 | "awsRegion": "us-east-1", 33 | "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/simple-stream" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /events/testdata/kinesis-firehose-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "invocationId": "invoked123", 3 | "deliveryStreamArn": "aws:lambda:events", 4 | "sourceKinesisStreamArn": "arn:aws:kinesis:us-east-1:123456789012:stream/test", 5 | "region": "us-west-2", 6 | "records": [ 7 | { 8 | "data": "SGVsbG8gV29ybGQ=", 9 | "recordId": "record1", 10 | "approximateArrivalTimestamp": 1507217624302, 11 | "kinesisRecordMetadata": { 12 | "shardId": "shardId-000000000000", 13 | "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a", 14 | "approximateArrivalTimestamp": 1507217624302, 15 | "sequenceNumber": "49546986683135544286507457936321625675700192471156785154", 16 | "subsequenceNumber": 123456 17 | } 18 | }, 19 | { 20 | "data": "SGVsbG8gV29ybGQ=", 21 | "recordId": "record2", 22 | "approximateArrivalTimestamp": 1507217624302, 23 | "kinesisRecordMetadata": { 24 | "shardId": "shardId-000000000001", 25 | "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c318a", 26 | "approximateArrivalTimestamp": 1507217624302, 27 | "sequenceNumber": "49546986683135544286507457936321625675700192471156785155", 28 | "subsequenceNumber": 123457 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /events/testdata/kinesis-firehose-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "records": [ 3 | { 4 | "data": "SGVsbG8gV29ybGQ=", 5 | "recordId": "record1", 6 | "result": "TRANSFORMED_STATE_OK", 7 | "metadata": { 8 | "partitionKeys": {} 9 | } 10 | }, 11 | { 12 | "data": "SGVsbG8gV29ybGQ=", 13 | "recordId": "record2", 14 | "result": "TRANSFORMED_STATE_DROPPED", 15 | "metadata": { 16 | "partitionKeys": {} 17 | } 18 | }, 19 | { 20 | "data": "SGVsbG8gV29ybGQ=", 21 | "recordId": "record3", 22 | "result": "TransformedStateOk", 23 | "metadata": { 24 | "partitionKeys": { 25 | "iamKey1": "iamValue1", 26 | "iamKey2": "iamValue2" 27 | } 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /events/testdata/kinesis-time-window-event.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "Records": [ 4 | { 5 | "kinesis": { 6 | "kinesisSchemaVersion": "1.0", 7 | "partitionKey": "1", 8 | "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", 9 | "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==", 10 | "approximateArrivalTimestamp": 1607497475.000 11 | }, 12 | "eventSource": "aws:kinesis", 13 | "eventVersion": "1.0", 14 | "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898", 15 | "eventName": "aws:kinesis:record", 16 | "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-kinesis-role", 17 | "awsRegion": "us-east-1", 18 | "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/lambda-stream" 19 | } 20 | ], 21 | "window": { 22 | "start": "2020-12-09T07:04:00Z", 23 | "end": "2020-12-09T07:06:00Z" 24 | }, 25 | "state": { 26 | "1": "state 1", 27 | "2": "state 2" 28 | }, 29 | "shardId": "shardId-000000000006", 30 | "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/lambda-stream", 31 | "isFinalInvokeForWindow": false, 32 | "isWindowTerminatedEarly": false 33 | } 34 | -------------------------------------------------------------------------------- /events/testdata/lambda-urls-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "rawPath": "/my/path", 4 | "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", 5 | "cookies": [ 6 | "cookie1", 7 | "cookie2" 8 | ], 9 | "headers": { 10 | "header1": "value1", 11 | "header2": "value1,value2" 12 | }, 13 | "queryStringParameters": { 14 | "parameter1": "value1,value2", 15 | "parameter2": "value" 16 | }, 17 | "requestContext": { 18 | "accountId": "123456789012", 19 | "apiId": "", 20 | "authorizer": { 21 | "iam": { 22 | "accessKey": "AKIA...", 23 | "accountId": "111122223333", 24 | "callerId": "AIDA...", 25 | "userArn": "arn:aws:iam::111122223333:user/example-user", 26 | "userId": "AIDA..." 27 | } 28 | }, 29 | "domainName": ".lambda-url.us-west-2.on.aws", 30 | "domainPrefix": "", 31 | "http": { 32 | "method": "POST", 33 | "path": "/my/path", 34 | "protocol": "HTTP/1.1", 35 | "sourceIp": "123.123.123.123", 36 | "userAgent": "agent" 37 | }, 38 | "requestId": "id", 39 | "time": "12/Mar/2020:19:03:58 +0000", 40 | "timeEpoch": 1583348638390 41 | }, 42 | "body": "Hello from client!", 43 | "isBase64Encoded": false 44 | } 45 | -------------------------------------------------------------------------------- /events/testdata/lambda-urls-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "statusCode": 201, 3 | "headers": { 4 | "Content-Type": "application/json", 5 | "My-Custom-Header": "Custom Value" 6 | }, 7 | "body": "{ \"message\": \"Hello, world!\" }", 8 | "cookies": [ 9 | "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT", 10 | "Cookie_2=Value2; Max-Age=78000" 11 | ], 12 | "isBase64Encoded": false 13 | } 14 | -------------------------------------------------------------------------------- /events/testdata/lex-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentIntent": { 3 | "name": "intent-name", 4 | "slots": { 5 | "slot name1": "value1", 6 | "slot name2": "value2" 7 | }, 8 | "slotDetails": { 9 | "slot name1": { 10 | "resolutions": [ 11 | { "value1": "resolved value1" }, 12 | { "value2": "resolved value2" } 13 | ], 14 | "originalValue": "original text" 15 | }, 16 | "slot name2": { 17 | "resolutions": [ 18 | { "value1": "resolved value1" }, 19 | { "value2": "resolved value2" } 20 | ], 21 | "originalValue": "original text" 22 | } 23 | }, 24 | "confirmationStatus": "None, Confirmed, or Denied (intent confirmation, if configured)" 25 | }, 26 | "bot": { 27 | "name": "bot name", 28 | "alias": "bot alias", 29 | "version": "bot version" 30 | }, 31 | "userId": "User ID specified in the POST request to Amazon Lex.", 32 | "inputTranscript": "Text used to process the request", 33 | "invocationSource": "FulfillmentCodeHook or DialogCodeHook", 34 | "outputDialogMode": "Text or Voice, based on ContentType request header in runtime API request", 35 | "messageVersion": "1.0", 36 | "sessionAttributes": { 37 | "key1": "value1", 38 | "key2": "value2" 39 | }, 40 | "requestAttributes": { 41 | "key1": "value1", 42 | "key2": "value2" 43 | } 44 | } -------------------------------------------------------------------------------- /events/testdata/lex-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionAttributes": { 3 | "key1": "value1", 4 | "key2": "value2" 5 | }, 6 | "dialogAction": { 7 | "type": "ElicitIntent, ElicitSlot, ConfirmIntent, Delegate, or Close", 8 | "fulfillmentState": "Fulfilled or Failed", 9 | "message": { 10 | "contentType": "PlainText or SSML", 11 | "content": "message to convey to the user" 12 | }, 13 | "intentName": "intent-name", 14 | "slots": { 15 | "slot-name1": "value1", 16 | "slot-name2": "value2", 17 | "slot-name3": "value3" 18 | }, 19 | "slotToElicit": "slot-name", 20 | "responseCard": { 21 | "version": 3, 22 | "contentType": "application/vnd.amazonaws.card.generic", 23 | "genericAttachments": [ 24 | { 25 | "title": "card-title", 26 | "subTitle": "card-sub-title", 27 | "imageUrl": "URL of the image to be shown", 28 | "attachmentLinkUrl": "URL of the attachment to be associated with the card", 29 | "buttons": [ 30 | { 31 | "text": "button-text", 32 | "value": "value sent to server on button click" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /events/testdata/rabbitmq-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "eventSource": "aws:rmq", 3 | "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8", 4 | "rmqMessagesByQueue": { 5 | "test::/": [ 6 | { 7 | "basicProperties": { 8 | "contentType": "text/plain", 9 | "contentEncoding": null, 10 | "headers": { 11 | "header1": { 12 | "bytes": [ 13 | 118, 14 | 97, 15 | 108, 16 | 117, 17 | 101, 18 | 49 19 | ] 20 | }, 21 | "header2": { 22 | "bytes": [ 23 | 118, 24 | 97, 25 | 108, 26 | 117, 27 | 101, 28 | 50 29 | ] 30 | }, 31 | "numberInHeader": 10 32 | }, 33 | "deliveryMode": 1, 34 | "priority": 34, 35 | "correlationId": null, 36 | "replyTo": null, 37 | "expiration": "60000", 38 | "messageId": null, 39 | "timestamp": "Jan 1, 1970, 12:33:41 AM", 40 | "type": null, 41 | "userId": "AIDACKCEVSQ6C2EXAMPLE", 42 | "appId": null, 43 | "clusterId": null, 44 | "bodySize": 80 45 | }, 46 | "redelivered": false, 47 | "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ==" 48 | } 49 | ] 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /events/testdata/s3-batch-job-event-request-1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "invocationSchemaVersion": "1.0", 3 | "invocationId": "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", 4 | "job": { 5 | "id": "f3cc4f60-61f6-4a2b-8a21-d07600c373ce" 6 | }, 7 | "tasks": [ 8 | { 9 | "taskId": "dGFza2lkZ29lc2hlcmUK", 10 | "s3Key": "customerImage1.jpg", 11 | "s3VersionId": "1", 12 | "s3BucketArn": "arn:aws:s3:us-east-1:0123456788:awsexamplebucket" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /events/testdata/s3-batch-job-event-request-2.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "invocationSchemaVersion": "2.0", 3 | "invocationId": "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", 4 | "job": { 5 | "id": "f3cc4f60-61f6-4a2b-8a21-d07600c373ce", 6 | "userArguments": { 7 | "k1": "v1", 8 | "k2": "v2" 9 | } 10 | }, 11 | "tasks": [ 12 | { 13 | "taskId": "dGFza2lkZ29lc2hlcmUK", 14 | "s3Key": "customerImage1.jpg", 15 | "s3VersionId": "jbo9_jhdPEyB4RrmOxWS0kU0EoNrU_oI", 16 | "s3Bucket": "awsexamplebucket" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /events/testdata/s3-batch-job-event-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "invocationSchemaVersion": "1.0", 3 | "treatMissingKeysAs" : "PermanentFailure", 4 | "invocationId" : "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", 5 | "results": [ 6 | { 7 | "taskId": "dGFza2lkZ29lc2hlcmUK", 8 | "resultCode": "Succeeded", 9 | "resultString": "[\"Mary Major\", \"John Stiles\"]" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /events/testdata/s3-event-with-decoded.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "eventVersion": "2.0", 5 | "eventSource": "aws:s3", 6 | "awsRegion": "us-east-1", 7 | "eventTime": "1970-01-01T00:00:00.123Z", 8 | "eventName": "ObjectCreated:Put", 9 | "userIdentity": { 10 | "principalId": "EXAMPLE" 11 | }, 12 | "requestParameters": { 13 | "sourceIPAddress": "127.0.0.1" 14 | }, 15 | "responseElements": { 16 | "x-amz-request-id": "C3D13FE58DE4C810", 17 | "x-amz-id-2": "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" 18 | }, 19 | "s3": { 20 | "s3SchemaVersion": "1.0", 21 | "configurationId": "testConfigRule", 22 | "bucket": { 23 | "name": "sourcebucket", 24 | "ownerIdentity": { 25 | "principalId": "EXAMPLE" 26 | }, 27 | "arn": "arn:aws:s3:::mybucket" 28 | }, 29 | "object": { 30 | "key": "Happy%20Face.jpg", 31 | "urlDecodedKey": "Happy Face.jpg", 32 | "size": 1024, 33 | "versionId": "version", 34 | "eTag": "d41d8cd98f00b204e9800998ecf8427e", 35 | "sequencer": "Happy Sequencer" 36 | } 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /events/testdata/s3-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "eventVersion": "2.0", 5 | "eventSource": "aws:s3", 6 | "awsRegion": "us-east-1", 7 | "eventTime": "1970-01-01T00:00:00.123Z", 8 | "eventName": "ObjectCreated:Put", 9 | "userIdentity": { 10 | "principalId": "EXAMPLE" 11 | }, 12 | "requestParameters": { 13 | "sourceIPAddress": "127.0.0.1" 14 | }, 15 | "responseElements": { 16 | "x-amz-request-id": "C3D13FE58DE4C810", 17 | "x-amz-id-2": "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" 18 | }, 19 | "s3": { 20 | "s3SchemaVersion": "1.0", 21 | "configurationId": "testConfigRule", 22 | "bucket": { 23 | "name": "sourcebucket", 24 | "ownerIdentity": { 25 | "principalId": "EXAMPLE" 26 | }, 27 | "arn": "arn:aws:s3:::mybucket" 28 | }, 29 | "object": { 30 | "key": "Happy%20Face.jpg", 31 | "size": 1024, 32 | "versionId": "version", 33 | "eTag": "d41d8cd98f00b204e9800998ecf8427e", 34 | "sequencer": "Happy Sequencer" 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /events/testdata/s3-object-lambda-event-get-object-assumed-role.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAmzRequestId": "requestId", 3 | "getObjectContext": { 4 | "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=", 5 | "outputRoute": "io-use1-001", 6 | "outputToken": "OutputToken" 7 | }, 8 | "configuration": { 9 | "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", 10 | "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", 11 | "payload": "{}" 12 | }, 13 | "userRequest": { 14 | "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", 15 | "headers": { 16 | "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", 17 | "Accept-Encoding": "identity", 18 | "X-Amz-Content-SHA256": "e3b0c44298fc1example" 19 | } 20 | }, 21 | "userIdentity": { 22 | "type": "AssumedRole", 23 | "principalId": "principalId", 24 | "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example", 25 | "accountId": "111122223333", 26 | "accessKeyId": "accessKeyId", 27 | "sessionContext": { 28 | "attributes": { 29 | "mfaAuthenticated": "false", 30 | "creationDate": "Wed Mar 10 23:41:52 UTC 2021" 31 | }, 32 | "sessionIssuer": { 33 | "type": "Role", 34 | "principalId": "principalId", 35 | "arn": "arn:aws:iam::111122223333:role/Admin", 36 | "accountId": "111122223333", 37 | "userName": "Admin" 38 | } 39 | } 40 | }, 41 | "protocolVersion": "1.00" 42 | } -------------------------------------------------------------------------------- /events/testdata/s3-object-lambda-event-get-object-iam.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAmzRequestId": "requestId", 3 | "getObjectContext": { 4 | "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=", 5 | "outputRoute": "io-use1-001", 6 | "outputToken": "OutputToken" 7 | }, 8 | "configuration": { 9 | "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", 10 | "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", 11 | "payload": "{}" 12 | }, 13 | "userRequest": { 14 | "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", 15 | "headers": { 16 | "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", 17 | "Accept-Encoding": "identity", 18 | "X-Amz-Content-SHA256": "e3b0c44298fc1example" 19 | } 20 | }, 21 | "userIdentity": { 22 | "type": "IAMUser", 23 | "principalId": "principalId", 24 | "arn": "arn:aws:iam::111122223333:user/username", 25 | "accountId": "111122223333", 26 | "accessKeyId": "accessKeyId" 27 | }, 28 | "protocolVersion": "1.00" 29 | } -------------------------------------------------------------------------------- /events/testdata/s3-object-lambda-event-head-object-iam.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAmzRequestId": "requestId", 3 | "headObjectContext": { 4 | "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=" 5 | }, 6 | "configuration": { 7 | "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", 8 | "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", 9 | "payload": "{}" 10 | }, 11 | "userRequest": { 12 | "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", 13 | "headers": { 14 | "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", 15 | "Accept-Encoding": "identity", 16 | "X-Amz-Content-SHA256": "e3b0c44298fc1example" 17 | } 18 | }, 19 | "userIdentity": { 20 | "type": "IAMUser", 21 | "principalId": "principalId", 22 | "arn": "arn:aws:iam::111122223333:user/username", 23 | "accountId": "111122223333", 24 | "accessKeyId": "accessKeyId" 25 | }, 26 | "protocolVersion": "1.01" 27 | } -------------------------------------------------------------------------------- /events/testdata/s3-object-lambda-event-list-objects-iam.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAmzRequestId": "requestId", 3 | "listObjectsContext": { 4 | "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=" 5 | }, 6 | "configuration": { 7 | "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", 8 | "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", 9 | "payload": "{}" 10 | }, 11 | "userRequest": { 12 | "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", 13 | "headers": { 14 | "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", 15 | "Accept-Encoding": "identity", 16 | "X-Amz-Content-SHA256": "e3b0c44298fc1example" 17 | } 18 | }, 19 | "userIdentity": { 20 | "type": "IAMUser", 21 | "principalId": "principalId", 22 | "arn": "arn:aws:iam::111122223333:user/username", 23 | "accountId": "111122223333", 24 | "accessKeyId": "accessKeyId" 25 | }, 26 | "protocolVersion": "1.01" 27 | } -------------------------------------------------------------------------------- /events/testdata/s3-object-lambda-event-list-objects-v2-iam.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAmzRequestId": "requestId", 3 | "listObjectsV2Context": { 4 | "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=" 5 | }, 6 | "configuration": { 7 | "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", 8 | "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", 9 | "payload": "{}" 10 | }, 11 | "userRequest": { 12 | "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", 13 | "headers": { 14 | "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", 15 | "Accept-Encoding": "identity", 16 | "X-Amz-Content-SHA256": "e3b0c44298fc1example" 17 | } 18 | }, 19 | "userIdentity": { 20 | "type": "IAMUser", 21 | "principalId": "principalId", 22 | "arn": "arn:aws:iam::111122223333:user/username", 23 | "accountId": "111122223333", 24 | "accessKeyId": "accessKeyId" 25 | }, 26 | "protocolVersion": "1.01" 27 | } -------------------------------------------------------------------------------- /events/testdata/secretsmanager-secret-rotation-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Step": "createSecret", 3 | "SecretId": "arn:aws:secretsmanager:us-east-1:111122223333:secret:id-ABCD1E", 4 | "ClientRequestToken": "1ab23456-cde7-8912-34fg-h56i78j9k12l", 5 | "RotationToken": "abcd1234-efgh-5678-ijkl-8ab4515a7db0" 6 | } -------------------------------------------------------------------------------- /events/testdata/sns-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "EventVersion": "1.0", 5 | "EventSubscriptionArn": "arn:aws:sns:EXAMPLE", 6 | "EventSource": "aws:sns", 7 | "Sns": { 8 | "Signature": "EXAMPLE", 9 | "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", 10 | "Type": "Notification", 11 | "TopicArn": "arn:aws:sns:EXAMPLE", 12 | "MessageAttributes": { 13 | "Test": { 14 | "Type": "String", 15 | "Value": "TestString" 16 | }, 17 | "TestBinary": { 18 | "Type": "Binary", 19 | "Value": "TestBinary" 20 | } 21 | }, 22 | "SignatureVersion": "1", 23 | "Timestamp": "2015-06-03T17:43:27.123Z", 24 | "SigningCertUrl": "EXAMPLE", 25 | "Message": "Hello from SNS!", 26 | "UnsubscribeUrl": "EXAMPLE", 27 | "Subject": "TestInvoke" 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /events/testdata/sqs-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "Records": [ 3 | { 4 | "messageId" : "MessageID_1", 5 | "receiptHandle" : "MessageReceiptHandle", 6 | "body" : "Message Body", 7 | "md5OfBody" : "fce0ea8dd236ccb3ed9b37dae260836f", 8 | "md5OfMessageAttributes" : "582c92c5c5b6ac403040a4f3ab3115c9", 9 | "eventSourceARN": "arn:aws:sqs:us-west-2:123456789012:SQSQueue", 10 | "eventSource": "aws:sqs", 11 | "awsRegion": "us-west-2", 12 | "attributes" : { 13 | "ApproximateReceiveCount" : "2", 14 | "SentTimestamp" : "1520621625029", 15 | "SenderId" : "AROAIWPX5BD2BHG722MW4:sender", 16 | "ApproximateFirstReceiveTimestamp" : "1520621634884" 17 | }, 18 | "messageAttributes" : { 19 | "Attribute3" : { 20 | "binaryValue" : "MTEwMA==", 21 | "stringListValues" : ["abc", "123"], 22 | "binaryListValues" : ["MA==", "MQ==", "MA=="], 23 | "dataType" : "Binary" 24 | }, 25 | "Attribute2" : { 26 | "stringValue" : "123", 27 | "stringListValues" : [ ], 28 | "binaryListValues" : ["MQ==", "MA=="], 29 | "dataType" : "Number" 30 | }, 31 | "Attribute1" : { 32 | "stringValue" : "AttributeValue1", 33 | "stringListValues" : [ ], 34 | "binaryListValues" : [ ], 35 | "dataType" : "String" 36 | } 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aws/aws-lambda-go 2 | 3 | go 1.18 4 | 5 | require github.com/stretchr/testify v1.7.2 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | gopkg.in/yaml.v3 v3.0.1 // indirect 11 | ) 12 | 13 | retract v1.39.0 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 7 | github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= 8 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 11 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 12 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 13 | -------------------------------------------------------------------------------- /lambda/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/aws/aws-lambda-go/lambda.svg)](https://pkg.go.dev/github.com/aws/aws-lambda-go/lambda) 4 | -------------------------------------------------------------------------------- /lambda/entry_generic.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | // Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved 5 | 6 | package lambda 7 | 8 | import ( 9 | "context" 10 | ) 11 | 12 | // HandlerFunc represents a valid input with two arguments and two returns as described by Start 13 | type HandlerFunc[TIn, TOut any] interface { 14 | func(context.Context, TIn) (TOut, error) 15 | } 16 | 17 | // StartHandlerFunc is the same as StartWithOptions except that it takes a generic input 18 | // so that the function signature can be validated at compile time. 19 | func StartHandlerFunc[TIn any, TOut any, H HandlerFunc[TIn, TOut]](handler H, options ...Option) { 20 | start(newHandler(handler, options...)) 21 | } 22 | -------------------------------------------------------------------------------- /lambda/entry_generic_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | // Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved 5 | 6 | package lambda 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | "reflect" 12 | "testing" 13 | 14 | "github.com/stretchr/testify/assert" 15 | ) 16 | 17 | func TestStartHandlerFunc(t *testing.T) { 18 | actual := "unexpected" 19 | logFatalf = func(format string, v ...interface{}) { 20 | actual = fmt.Sprintf(format, v...) 21 | } 22 | 23 | f := func(context.Context, any) (any, error) { return 1, nil } 24 | StartHandlerFunc(f) 25 | 26 | assert.Equal(t, "expected AWS Lambda environment variables [_LAMBDA_SERVER_PORT AWS_LAMBDA_RUNTIME_API] are not defined", actual) 27 | 28 | handlerType := reflect.TypeOf(f) 29 | 30 | handlerTakesContext, err := handlerTakesContext(handlerType) 31 | assert.NoError(t, err) 32 | assert.True(t, handlerTakesContext) 33 | 34 | err = validateReturns(handlerType) 35 | assert.NoError(t, err) 36 | } 37 | -------------------------------------------------------------------------------- /lambda/entry_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved 2 | 3 | package lambda 4 | 5 | import ( 6 | "context" 7 | "log" 8 | "os" 9 | "strings" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | type ctxTestKey struct{} 16 | 17 | func TestStartRuntimeAPIWithContext(t *testing.T) { 18 | server, _ := runtimeAPIServer("null", 1) // serve a single invoke, and then cause an internal error 19 | expected := "expected" 20 | actual := "unexpected" 21 | 22 | os.Setenv("AWS_LAMBDA_RUNTIME_API", strings.Split(server.URL, "://")[1]) 23 | defer os.Unsetenv("AWS_LAMBDA_RUNTIME_API") 24 | logFatalf = func(format string, v ...interface{}) {} 25 | defer func() { logFatalf = log.Fatalf }() 26 | 27 | StartWithContext(context.WithValue(context.Background(), ctxTestKey{}, expected), func(ctx context.Context) error { 28 | actual, _ = ctx.Value(ctxTestKey{}).(string) 29 | return nil 30 | }) 31 | 32 | assert.Equal(t, expected, actual) 33 | } 34 | -------------------------------------------------------------------------------- /lambda/entry_with_no_rpc_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | //go:build lambda.norpc 4 | // +build lambda.norpc 5 | 6 | package lambda 7 | 8 | import ( 9 | "fmt" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestStartNotInLambda(t *testing.T) { 16 | actual := "unexpected" 17 | logFatalf = func(format string, v ...interface{}) { 18 | actual = fmt.Sprintf(format, v...) 19 | } 20 | 21 | Start(func() error { return nil }) 22 | assert.Equal(t, "expected AWS Lambda environment variables [AWS_LAMBDA_RUNTIME_API] are not defined", actual) 23 | } 24 | -------------------------------------------------------------------------------- /lambda/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved 2 | 3 | package lambda 4 | 5 | import ( 6 | "reflect" 7 | 8 | "github.com/aws/aws-lambda-go/lambda/messages" 9 | ) 10 | 11 | func getErrorType(err interface{}) string { 12 | errorType := reflect.TypeOf(err) 13 | if errorType.Kind() == reflect.Ptr { 14 | return errorType.Elem().Name() 15 | } 16 | return errorType.Name() 17 | } 18 | 19 | func lambdaErrorResponse(invokeError error) *messages.InvokeResponse_Error { 20 | if ive, ok := invokeError.(messages.InvokeResponse_Error); ok { 21 | return &ive 22 | } 23 | var errorName string 24 | if errorType := reflect.TypeOf(invokeError); errorType.Kind() == reflect.Ptr { 25 | errorName = errorType.Elem().Name() 26 | } else { 27 | errorName = errorType.Name() 28 | } 29 | return &messages.InvokeResponse_Error{ 30 | Message: invokeError.Error(), 31 | Type: errorName, 32 | } 33 | } 34 | 35 | func lambdaPanicResponse(err interface{}) *messages.InvokeResponse_Error { 36 | if ive, ok := err.(messages.InvokeResponse_Error); ok { 37 | return &ive 38 | } 39 | panicInfo := getPanicInfo(err) 40 | return &messages.InvokeResponse_Error{ 41 | Message: panicInfo.Message, 42 | Type: getErrorType(err), 43 | StackTrace: panicInfo.StackTrace, 44 | ShouldExit: true, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lambda/handlertrace/trace.go: -------------------------------------------------------------------------------- 1 | // Package handlertrace allows middleware authors using lambda.NewHandler to 2 | // instrument request and response events. 3 | package handlertrace 4 | 5 | import ( 6 | "context" 7 | ) 8 | 9 | // HandlerTrace allows handlers which wrap the return value of lambda.NewHandler 10 | // to access to the request and response events. 11 | type HandlerTrace struct { 12 | RequestEvent func(context.Context, interface{}) 13 | ResponseEvent func(context.Context, interface{}) 14 | } 15 | 16 | func callbackCompose(f1, f2 func(context.Context, interface{})) func(context.Context, interface{}) { 17 | return func(ctx context.Context, event interface{}) { 18 | if nil != f1 { 19 | f1(ctx, event) 20 | } 21 | if nil != f2 { 22 | f2(ctx, event) 23 | } 24 | } 25 | } 26 | 27 | type handlerTraceKey struct{} 28 | 29 | // NewContext adds callbacks to the provided context which allows handlers which 30 | // wrap the return value of lambda.NewHandler to access to the request and 31 | // response events. 32 | func NewContext(ctx context.Context, trace HandlerTrace) context.Context { 33 | existing := FromContext(ctx) 34 | return context.WithValue(ctx, handlerTraceKey{}, HandlerTrace{ 35 | RequestEvent: callbackCompose(existing.RequestEvent, trace.RequestEvent), 36 | ResponseEvent: callbackCompose(existing.ResponseEvent, trace.ResponseEvent), 37 | }) 38 | } 39 | 40 | // FromContext returns the HandlerTrace associated with the provided context. 41 | func FromContext(ctx context.Context) HandlerTrace { 42 | trace, _ := ctx.Value(handlerTraceKey{}).(HandlerTrace) 43 | return trace 44 | } 45 | -------------------------------------------------------------------------------- /lambda/handlertrace/trace_test.go: -------------------------------------------------------------------------------- 1 | package handlertrace 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestTrace(t *testing.T) { 12 | ctx := context.Background() 13 | 14 | requestCall := 0 15 | responseCall := 0 16 | 17 | existedContext := context.WithValue(ctx, handlerTraceKey{}, HandlerTrace{ 18 | RequestEvent: func(ctx context.Context, event interface{}) { 19 | requestCall += 1 20 | }, 21 | ResponseEvent: func(ctx context.Context, event interface{}) { 22 | responseCall += 1 23 | }, 24 | }) 25 | 26 | trace := HandlerTrace{ 27 | RequestEvent: func(ctx context.Context, event interface{}) { 28 | requestCall += 1 29 | }, 30 | ResponseEvent: func(ctx context.Context, event interface{}) { 31 | responseCall += 1 32 | }, 33 | } 34 | 35 | ctxWithTrace := NewContext(existedContext, trace) 36 | traceFromCtx := FromContext(ctxWithTrace) 37 | 38 | traceFromCtx.RequestEvent(ctxWithTrace, nil) 39 | assert.Equal(t, requestCall, 2) 40 | 41 | traceFromCtx.ResponseEvent(ctxWithTrace, nil) 42 | fmt.Println(responseCall) 43 | assert.Equal(t, responseCall, 2) 44 | } 45 | -------------------------------------------------------------------------------- /lambda/messages/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/aws/aws-lambda-go/lambda/messages.svg)](https://pkg.go.dev/github.com/aws/aws-lambda-go/lambda/messages) 4 | -------------------------------------------------------------------------------- /lambda/messages/messages.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | package messages 4 | 5 | import "fmt" 6 | 7 | type PingRequest struct { 8 | } 9 | 10 | type PingResponse struct { 11 | } 12 | 13 | //nolint:stylecheck 14 | type InvokeRequest_Timestamp struct { 15 | Seconds int64 16 | Nanos int64 17 | } 18 | 19 | //nolint:stylecheck 20 | type InvokeRequest struct { 21 | Payload []byte 22 | RequestId string //nolint:stylecheck 23 | XAmznTraceId string 24 | Deadline InvokeRequest_Timestamp 25 | InvokedFunctionArn string 26 | CognitoIdentityId string //nolint:stylecheck 27 | CognitoIdentityPoolId string //nolint:stylecheck 28 | ClientContext []byte 29 | } 30 | 31 | type InvokeResponse struct { 32 | Payload []byte 33 | Error *InvokeResponse_Error 34 | } 35 | 36 | //nolint:stylecheck 37 | type InvokeResponse_Error struct { 38 | Message string `json:"errorMessage"` 39 | Type string `json:"errorType"` 40 | StackTrace []*InvokeResponse_Error_StackFrame `json:"stackTrace,omitempty"` 41 | ShouldExit bool `json:"-"` 42 | } 43 | 44 | func (e InvokeResponse_Error) Error() string { 45 | return fmt.Sprintf("%#v", e) 46 | } 47 | 48 | //nolint:stylecheck 49 | type InvokeResponse_Error_StackFrame struct { 50 | Path string `json:"path"` 51 | Line int32 `json:"line"` 52 | Label string `json:"label"` 53 | } 54 | -------------------------------------------------------------------------------- /lambda/testdata/.gitignore: -------------------------------------------------------------------------------- 1 | handler* 2 | *.json 3 | -------------------------------------------------------------------------------- /lambda/testdata/bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | echo "\"$(od -N $((512 * 1024)) /dev/random | base64)\"" > data.json 6 | echo "data payload for tests is: $(du -h data.json)" 7 | 8 | trap "docker kill rie-bench" 1 2 3 6 9 | bench () { 10 | local handler_exe=$1 11 | local entrypoint=$2 12 | local image=$3 13 | echo "-------------------------------------------------" 14 | echo $@ 15 | echo "-------------------------------------------------" 16 | docker run --name rie-bench --rm -d -p 9001:8080 -v "${handler_exe}:/var/task/bootstrap" --entrypoint aws-lambda-rie ${image} ${entrypoint} bootstrap 17 | sleep 2 18 | echo "ensuring healthy function before starting test" 19 | curl -s -XPOST http://localhost:9001/2015-03-31/functions/function/invocations -d '{"hello": "world"}' | jq 20 | echo "-------------------------------------------------" 21 | ab -p data.json -n 100 http://localhost:9001/2015-03-31/functions/function/invocations 22 | docker kill rie-bench 23 | } 24 | 25 | GOOS=linux GOARCH=amd64 go build -o handler echo_handler.go 26 | GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o handler_norpc echo_handler.go 27 | ls -lah handler* 28 | 29 | bench "$(pwd)/handler_norpc" /var/task/bootstrap public.ecr.aws/lambda/provided:alami 30 | bench "$(pwd)/handler_norpc" /var/runtime/bootstrap public.ecr.aws/lambda/go 31 | bench "$(pwd)/handler" /var/runtime/bootstrap public.ecr.aws/lambda/go 32 | -------------------------------------------------------------------------------- /lambda/testdata/echo_handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/aws/aws-lambda-go/lambda" 7 | ) 8 | 9 | type handler struct{} 10 | 11 | func (h handler) Invoke(_ context.Context, e []byte) ([]byte, error) { 12 | return e, nil 13 | } 14 | 15 | func main() { 16 | lambda.Start(handler{}) 17 | } 18 | -------------------------------------------------------------------------------- /lambda/testdata/sigterm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | "time" 10 | 11 | "github.com/aws/aws-lambda-go/lambda" 12 | ) 13 | 14 | func init() { 15 | // conventional SIGTERM callback 16 | signaled := make(chan os.Signal, 1) 17 | signal.Notify(signaled, syscall.SIGTERM) 18 | go func() { 19 | <-signaled 20 | fmt.Println("I've been TERMINATED!") 21 | }() 22 | 23 | } 24 | 25 | func main() { 26 | // lambda option to enable sigterm, plus optional extra sigterm callbacks 27 | sigtermOption := lambda.WithEnableSIGTERM(func() { 28 | fmt.Println("Hello SIGTERM!") 29 | }) 30 | handlerOptions := []lambda.Option{} 31 | if os.Getenv("ENABLE_SIGTERM") != "" { 32 | handlerOptions = append(handlerOptions, sigtermOption) 33 | } 34 | lambda.StartWithOptions( 35 | func(ctx context.Context) { 36 | deadline, _ := ctx.Deadline() 37 | <-time.After(time.Until(deadline) + time.Second) 38 | panic("unreachable line reached!") 39 | }, 40 | handlerOptions..., 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /lambdacontext/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/aws/aws-lambda-go/lambdacontext.svg)](https://pkg.go.dev/github.com/aws/aws-lambda-go/lambdacontext) 4 | -------------------------------------------------------------------------------- /lambdaurl/testdata/function-url-domain-only-get-request-trailing-slash.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "accept": "application/xml", 4 | "accept-encoding": "gzip, deflate", 5 | "content-type": "application/json", 6 | "host": "lambda-url-id.lambda-url.us-west-2.on.aws", 7 | "user-agent": "python-requests/2.28.2", 8 | "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 9 | "x-amz-date": "20230418T170147Z", 10 | "x-amz-security-token": "security-token", 11 | "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", 12 | "x-amzn-tls-version": "TLSv1.2", 13 | "x-amzn-trace-id": "Root=1-643eccfb-7c4d3f09749a95a044db997a", 14 | "x-forwarded-for": "127.0.0.1", 15 | "x-forwarded-port": "443", 16 | "x-forwarded-proto": "https" 17 | }, 18 | "isBase64Encoded": false, 19 | "rawPath": "/", 20 | "rawQueryString": "", 21 | "requestContext": { 22 | "accountId": "aws-account-id", 23 | "apiId": "lambda-url-id", 24 | "authorizer": { 25 | "iam": {} 26 | }, 27 | "domainName": "lambda-url-id.lambda-url.us-west-2.on.aws", 28 | "domainPrefix": "lambda-url-id", 29 | "http": { 30 | "method": "GET", 31 | "path": "/", 32 | "protocol": "HTTP/1.1", 33 | "sourceIp": "127.0.0.1", 34 | "userAgent": "python-requests/2.28.2" 35 | }, 36 | "requestId": "3a72f39b-d6bd-4a4f-b040-f94d09b4daa3", 37 | "routeKey": "$default", 38 | "stage": "$default", 39 | "time": "18/Apr/2023:17:01:47 +0000", 40 | "timeEpoch": 1681837307717 41 | }, 42 | "routeKey": "$default", 43 | "version": "2.0" 44 | } 45 | -------------------------------------------------------------------------------- /lambdaurl/testdata/function-url-domain-only-get-request.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "accept": "application/xml", 4 | "accept-encoding": "gzip, deflate", 5 | "content-type": "application/json", 6 | "host": "lambda-url-id.lambda-url.us-west-2.on.aws", 7 | "user-agent": "python-requests/2.28.2", 8 | "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 9 | "x-amz-date": "20230418T170147Z", 10 | "x-amz-security-token": "security-token", 11 | "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", 12 | "x-amzn-tls-version": "TLSv1.2", 13 | "x-amzn-trace-id": "Root=1-643eccfb-4c9be61972302fa41111a443", 14 | "x-forwarded-for": "127.0.0.1", 15 | "x-forwarded-port": "443", 16 | "x-forwarded-proto": "https" 17 | }, 18 | "isBase64Encoded": false, 19 | "rawPath": "/", 20 | "rawQueryString": "", 21 | "requestContext": { 22 | "accountId": "aws-account-id", 23 | "apiId": "lambda-url-id", 24 | "authorizer": { 25 | "iam": {} 26 | }, 27 | "domainName": "lambda-url-id.lambda-url.us-west-2.on.aws", 28 | "domainPrefix": "lambda-url-id", 29 | "http": { 30 | "method": "GET", 31 | "path": "/", 32 | "protocol": "HTTP/1.1", 33 | "sourceIp": "127.0.0.1", 34 | "userAgent": "python-requests/2.28.2" 35 | }, 36 | "requestId": "deeb7e49-a9a8-4a8f-bcd1-5482231e2087", 37 | "routeKey": "$default", 38 | "stage": "$default", 39 | "time": "18/Apr/2023:17:01:47 +0000", 40 | "timeEpoch": 1681837307545 41 | }, 42 | "routeKey": "$default", 43 | "version": "2.0" 44 | } 45 | -------------------------------------------------------------------------------- /lambdaurl/testdata/function-url-domain-only-request-with-base64-encoded-body.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "PGlkay8+", 3 | "headers": { 4 | "accept": "*/*", 5 | "accept-encoding": "gzip, deflate", 6 | "content-length": "6", 7 | "content-type": "idk", 8 | "host": "lambda-url-id.lambda-url.us-west-2.on.aws", 9 | "user-agent": "python-requests/2.28.2", 10 | "x-amz-content-sha256": "0ab2082273499eaa495f2196e32d8c794745e58a20a0c93182c59d2165432839", 11 | "x-amz-date": "20230418T170147Z", 12 | "x-amz-security-token": "security-token", 13 | "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", 14 | "x-amzn-tls-version": "TLSv1.2", 15 | "x-amzn-trace-id": "Root=1-643eccfb-7fdecb844a12b4b45645132d", 16 | "x-forwarded-for": "127.0.0.1", 17 | "x-forwarded-port": "443", 18 | "x-forwarded-proto": "https" 19 | }, 20 | "isBase64Encoded": true, 21 | "rawPath": "/", 22 | "rawQueryString": "", 23 | "requestContext": { 24 | "accountId": "aws-account-id", 25 | "apiId": "lambda-url-id", 26 | "authorizer": { 27 | "iam": {} 28 | }, 29 | "domainName": "lambda-url-id.lambda-url.us-west-2.on.aws", 30 | "domainPrefix": "lambda-url-id", 31 | "http": { 32 | "method": "POST", 33 | "path": "/", 34 | "protocol": "HTTP/1.1", 35 | "sourceIp": "127.0.0.1", 36 | "userAgent": "python-requests/2.28.2" 37 | }, 38 | "requestId": "9701a3d4-36ad-40bd-bf0b-a525c987d27f", 39 | "routeKey": "$default", 40 | "stage": "$default", 41 | "time": "18/Apr/2023:17:01:47 +0000", 42 | "timeEpoch": 1681837307386 43 | }, 44 | "routeKey": "$default", 45 | "version": "2.0" 46 | } 47 | -------------------------------------------------------------------------------- /lambdaurl/testdata/function-url-request-with-headers-and-cookies-and-text-body.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": "{\"hello\": \"world\"}", 3 | "cookies": [ 4 | "foo=bar", 5 | "hello=hello" 6 | ], 7 | "headers": { 8 | "accept": "*/*", 9 | "accept-encoding": "gzip, deflate", 10 | "content-length": "18", 11 | "content-type": "application/json", 12 | "cookie": "foo=bar; hello=hello", 13 | "header1": "h1", 14 | "header2": "h1,h2", 15 | "header3": "h3", 16 | "host": "lambda-url-id.lambda-url.us-west-2.on.aws", 17 | "user-agent": "python-requests/2.28.2", 18 | "x-amz-content-sha256": "5f8f04f6a3a892aaabbddb6cf273894493773960d4a325b105fee46eef4304f1", 19 | "x-amz-date": "20230418T170146Z", 20 | "x-amz-security-token": "security-token", 21 | "x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256", 22 | "x-amzn-tls-version": "TLSv1.2", 23 | "x-amzn-trace-id": "Root=1-643eccfa-2c6028925c2b249524664087", 24 | "x-forwarded-for": "127.0.0.1", 25 | "x-forwarded-port": "443", 26 | "x-forwarded-proto": "https" 27 | }, 28 | "isBase64Encoded": false, 29 | "queryStringParameters": { 30 | "foo": "bar", 31 | "hello": "world" 32 | }, 33 | "rawPath": "/hello", 34 | "rawQueryString": "hello=world&foo=bar", 35 | "requestContext": { 36 | "accountId": "aws-account-id", 37 | "apiId": "lambda-url-id", 38 | "authorizer": { 39 | "iam": {} 40 | }, 41 | "domainName": "lambda-url-id.lambda-url.us-west-2.on.aws", 42 | "domainPrefix": "lambda-url-id", 43 | "http": { 44 | "method": "POST", 45 | "path": "/hello", 46 | "protocol": "HTTP/1.1", 47 | "sourceIp": "127.0.0.1", 48 | "userAgent": "python-requests/2.28.2" 49 | }, 50 | "requestId": "5bbd0e3e-fe7a-4299-9076-32d4de45391b", 51 | "routeKey": "$default", 52 | "stage": "$default", 53 | "time": "18/Apr/2023:17:01:46 +0000", 54 | "timeEpoch": 1681837306806 55 | }, 56 | "routeKey": "$default", 57 | "version": "2.0" 58 | } 59 | -------------------------------------------------------------------------------- /lambdaurl/testdata/gen-events.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | url_id="${1}" # should be the lambda function url domain prefix for an echo function 5 | region=${AWS_REGION:-us-west-2} 6 | url="https://${url_id}.lambda-url.${region}.on.aws" 7 | account_id=$(aws sts get-caller-identity --output text --query "Account") 8 | 9 | redact () { 10 | #https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids 11 | sed "s/${url_id}/lambda-url-id/g" \ 12 | | sed 's/A[A-Z][A-Z]A[A-Z1-9]*\([":]\)/iam-unique-id\1/g' \ 13 | | sed "s/${account_id}/aws-account-id/g" \ 14 | | jq '.headers |= (.["x-amz-security-token"] = "security-token" )' \ 15 | | jq '.headers |= (.["x-forwarded-for"] = "127.0.0.1")' \ 16 | | jq '.requestContext.authorizer |= (.["iam"] = {})' \ 17 | | jq '.requestContext.http |= (.["sourceIp"] = "127.0.0.1")' 18 | } 19 | 20 | awscurl --service lambda --region $region \ 21 | -X POST \ 22 | -H 'Header1: h1' \ 23 | -H 'Header2: h1,h2' \ 24 | -H 'Header3: h3' \ 25 | -H 'Cookie: foo=bar; hello=hello' \ 26 | -H 'Content-Type: application/json' \ 27 | -d '{"hello": "world"}' \ 28 | "$url/hello?hello=world&foo=bar" \ 29 | | redact \ 30 | | tee function-url-request-with-headers-and-cookies-and-text-body.json \ 31 | | jq 32 | 33 | awscurl --service lambda --region $region \ 34 | -X POST \ 35 | -d '' \ 36 | "$url" \ 37 | | redact \ 38 | | tee function-url-domain-only-request-with-base64-encoded-body.json \ 39 | | jq 40 | 41 | awscurl --service lambda --region $region \ 42 | -X GET \ 43 | "$url" \ 44 | | redact \ 45 | | tee function-url-domain-only-get-request.json \ 46 | | jq 47 | 48 | awscurl --service lambda --region $region \ 49 | -X GET \ 50 | "$url/" \ 51 | | redact \ 52 | | tee function-url-domain-only-get-request-trailing-slash.json \ 53 | | jq 54 | 55 | -------------------------------------------------------------------------------- /lambdaurl/testdata/lambdaurl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | "strings" 7 | 8 | "github.com/aws/aws-lambda-go/lambdaurl" 9 | ) 10 | 11 | const content = ` 12 | 13 | 14 | Hello World! 15 | 16 | 17 | ` 18 | 19 | func main() { 20 | lambdaurl.Start(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 21 | _, _ = io.Copy(w, strings.NewReader(content)) 22 | }), 23 | lambdaurl.WithDetectContentType(true), 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/.gitignore: -------------------------------------------------------------------------------- 1 | .aws-sam/ 2 | samconfig.toml 3 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/echo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/aws/aws-lambda-go/lambda" 5 | ) 6 | 7 | func main() { 8 | lambda.Start(func(req any) (any, error) { 9 | return req, nil 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/go.mod: -------------------------------------------------------------------------------- 1 | module testfunc 2 | 3 | require github.com/aws/aws-lambda-go v1.40.0 4 | 5 | replace github.com/aws/aws-lambda-go => ../../../ 6 | 7 | go 1.20 8 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 3 | github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= 4 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 5 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/site/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | "os" 9 | "strings" 10 | 11 | "github.com/aws/aws-lambda-go/lambdaurl" 12 | ) 13 | 14 | func logLambdaRequest(ctx context.Context) { 15 | req, ok := lambdaurl.RequestFromContext(ctx) 16 | if ok { 17 | enc := json.NewEncoder(os.Stdout) 18 | enc.SetIndent("", " ") 19 | enc.Encode(req) 20 | } 21 | } 22 | 23 | func root(w http.ResponseWriter, r *http.Request) { 24 | logLambdaRequest(r.Context()) 25 | } 26 | 27 | func hello(w http.ResponseWriter, r *http.Request) { 28 | w.Header().Set("Content-Type", "text/html") 29 | io.Copy(w, strings.NewReader(`Hello World!`)) 30 | } 31 | 32 | func main() { 33 | http.HandleFunc("/hello", hello) 34 | http.HandleFunc("/", root) 35 | if os.Getenv("AWS_LAMBDA_RUNTIME_API") != "" { 36 | lambdaurl.Start(http.DefaultServeMux) 37 | } 38 | http.ListenAndServe(":9001", nil) 39 | } 40 | -------------------------------------------------------------------------------- /lambdaurl/testdata/testfunc/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | Test handler for github.com/aws/aws-lambda-go/lambdaurl 5 | Globals: 6 | Function: 7 | Timeout: 3 8 | Runtime: provided.al2 9 | Handler: bootstrap 10 | Architectures: [ arm64 ] 11 | Resources: 12 | Site: 13 | Type: AWS::Serverless::Function 14 | Metadata: 15 | BuildMethod: go1.x 16 | Properties: 17 | CodeUri: site 18 | FunctionUrlConfig: 19 | AuthType: AWS_IAM 20 | InvokeMode: RESPONSE_STREAM 21 | Echo: 22 | Type: AWS::Serverless::Function 23 | Metadata: 24 | BuildMethod: go1.x 25 | Properties: 26 | CodeUri: echo 27 | FunctionUrlConfig: 28 | AuthType: AWS_IAM 29 | InvokeMode: RESPONSE_STREAM 30 | 31 | Outputs: 32 | SiteUrl: 33 | Description: "Site Lambda Function URL" 34 | Value: !GetAtt SiteUrl.FunctionUrl 35 | EchoUrl: 36 | Description: "Echo Lambda Function URL" 37 | Value: !GetAtt EchoUrl.FunctionUrl 38 | --------------------------------------------------------------------------------