Skip to content

Commit 1be8070

Browse files
sjurtffuriousbunny
authored andcommitted
Add events for lambda ALB integration (#149)
Adding events for Lambda ALB integration
1 parent 554303c commit 1be8070

5 files changed

+195
-0
lines changed

events/README_ALBTargetGroupEvents.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 by default anything written to Console 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}, nil
33+
}
34+
35+
func main() {
36+
lambda.Start(handleRequest)
37+
}
38+
```

events/alb.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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"`
8+
MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters"`
9+
Headers map[string]string `json:"headers"`
10+
MultiValueHeaders map[string][]string `json:"multiValueHeaders"`
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"`
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"`
33+
IsBase64Encoded bool `json:"isBase64Encoded"`
34+
}

events/alb_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package events
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
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+
// read json from file
14+
inputJSON, err := ioutil.ReadFile("./testdata/alb-lambda-target-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 ALBTargetGroupRequest
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 TestALBTargetRequestMalformedJson(t *testing.T) {
35+
test.TestMalformedJson(t, ALBTargetGroupRequest{})
36+
}
37+
38+
func TestALBTargetResponseMarshaling(t *testing.T) {
39+
40+
// read json from file
41+
inputJSON, err := ioutil.ReadFile("./testdata/alb-lambda-target-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 ALBTargetGroupResponse
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+
assert.JSONEq(t, string(inputJSON), string(outputJSON))
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"requestContext": {
3+
"elb": {
4+
"targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09"
5+
}
6+
},
7+
"httpMethod": "GET",
8+
"path": "/",
9+
"queryStringParameters": {
10+
"testparam": "true"
11+
},
12+
"multiValueQueryStringParameters": {
13+
"name": ["me"]
14+
},
15+
"headers": {
16+
"accept": "text/html,application/xhtml+xml",
17+
"accept-language": "en-US,en;q=0.8",
18+
"content-type": "text/plain",
19+
"cookie": "cookies",
20+
"host": "lambda-846800462-us-east-2.elb.amazonaws.com",
21+
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)",
22+
"x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520",
23+
"x-forwarded-for": "72.21.198.66",
24+
"x-forwarded-port": "443",
25+
"x-forwarded-proto": "https"
26+
},
27+
"multiValueHeaders": {
28+
"Accept": ["*/*"],
29+
"Accept-Encoding": ["gzip, deflate"],
30+
"cache-control": ["no-cache"],
31+
"CloudFront-Forwarded-Proto": ["https"],
32+
"CloudFront-Is-Desktop-Viewer": ["true"],
33+
"CloudFront-Is-Mobile-Viewer": ["false"],
34+
"CloudFront-Is-SmartTV-Viewer": ["false"],
35+
"CloudFront-Is-Tablet-Viewer": ["false"],
36+
"CloudFront-Viewer-Country": ["US"],
37+
"Content-Type": ["application/json"],
38+
"headerName": ["headerValue"],
39+
"Host": ["gy415nuibc.execute-api.us-east-1.amazonaws.com"],
40+
"Postman-Token": ["9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f"],
41+
"User-Agent": ["PostmanRuntime/2.4.5"],
42+
"Via": ["1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)"],
43+
"X-Amz-Cf-Id": ["pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A=="],
44+
"X-Forwarded-For": ["54.240.196.186, 54.182.214.83"],
45+
"X-Forwarded-Port": ["443"],
46+
"X-Forwarded-Proto": ["https"]
47+
},
48+
"isBase64Encoded": false,
49+
"body": "Who there?"
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
}

0 commit comments

Comments
 (0)