feat(aws): support lambda (#334)

This commit is contained in:
Bo-Yi Wu 2018-01-23 16:34:34 +08:00 committed by GitHub
parent b0260af17b
commit d7ce3c077c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 2795 additions and 2 deletions

View File

@ -172,6 +172,9 @@ build_linux_arm64:
build_linux_arm:
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/arm/$(DEPLOY_IMAGE)
build_linux_lambda:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags 'lambda' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/lambda/$(DEPLOY_IMAGE)
docker_image:
docker build -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) -f Dockerfile .

19
gorush/server_lambda.go Normal file
View File

@ -0,0 +1,19 @@
// +build lambda
package gorush
import (
"github.com/apex/gateway"
)
// RunHTTPServer provide run http or https protocol.
func RunHTTPServer() error {
if !PushConf.Core.Enabled {
LogAccess.Debug("httpd server is disabled.")
return nil
}
LogAccess.Debug("HTTPD server is running on " + PushConf.Core.Port + " port.")
return gateway.ListenAndServe(PushConf.Core.Address+":"+PushConf.Core.Port, routerEngine())
}

View File

@ -1,4 +1,4 @@
// +build !windows
// +build !windows,!lambda
package gorush

View File

@ -1,4 +1,4 @@
// +build windows
// +build windows,!lambda
package gorush

34
vendor/github.com/apex/gateway/Readme.md generated vendored Normal file
View File

@ -0,0 +1,34 @@
<img src="http://tjholowaychuk.com:6000/svg/title/APEX/GATEWAY">
Package gateway provides a drop-in replacement for net/http's `ListenAndServe` for use in AWS Lambda & API Gateway, simply swap it out for `gateway.ListenAndServe`. Extracted from [Up](https://github.com/apex/up) which provides additional middleware features and operational functionality.
```go
package main
import (
"fmt"
"log"
"net/http"
"os"
"github.com/apex/gateway"
)
func main() {
addr := ":" + os.Getenv("PORT")
http.HandleFunc("/", hello)
log.Fatal(gateway.ListenAndServe(addr, nil))
}
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World from Go")
}
```
---
[![GoDoc](https://godoc.org/github.com/apex/up-go?status.svg)](https://godoc.org/github.com/apex/gateway)
![](https://img.shields.io/badge/license-MIT-blue.svg)
![](https://img.shields.io/badge/status-stable-green.svg)
<a href="https://apex.sh"><img src="http://tjholowaychuk.com:6000/svg/sponsor"></a>

33
vendor/github.com/apex/gateway/gateway.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
// Package gateway provides a drop-in replacement for net/http.ListenAndServe for use in AWS Lambda & API Gateway.
package gateway
import (
"context"
"net/http"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
// ListenAndServe is a drop-in replacement for
// http.ListenAndServe for use within AWS Lambda.
//
// ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, h http.Handler) error {
if h == nil {
h = http.DefaultServeMux
}
lambda.Start(func(ctx context.Context, e events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
r, err := NewRequest(ctx, e)
if err != nil {
return events.APIGatewayProxyResponse{}, err
}
w := NewResponse()
h.ServeHTTP(w, r)
return w.End(), nil
})
return nil
}

74
vendor/github.com/apex/gateway/request.go generated vendored Normal file
View File

@ -0,0 +1,74 @@
package gateway
import (
"context"
"encoding/base64"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/aws/aws-lambda-go/events"
"github.com/pkg/errors"
)
// NewRequest returns a new http.Request from the given Lambda event.
func NewRequest(ctx context.Context, e events.APIGatewayProxyRequest) (*http.Request, error) {
// path
u, err := url.Parse(e.Path)
if err != nil {
return nil, errors.Wrap(err, "parsing path")
}
// querystring
q := u.Query()
for k, v := range e.QueryStringParameters {
q.Set(k, v)
}
u.RawQuery = q.Encode()
// base64 encoded body
body := e.Body
if e.IsBase64Encoded {
b, err := base64.StdEncoding.DecodeString(body)
if err != nil {
return nil, errors.Wrap(err, "decoding base64 body")
}
body = string(b)
}
// new request
req, err := http.NewRequest(e.HTTPMethod, u.String(), strings.NewReader(body))
if err != nil {
return nil, errors.Wrap(err, "creating request")
}
// remote addr
req.RemoteAddr = e.RequestContext.Identity.SourceIP
// header fields
for k, v := range e.Headers {
req.Header.Set(k, v)
}
// content-length
if req.Header.Get("Content-Length") == "" && body != "" {
req.Header.Set("Content-Length", strconv.Itoa(len(body)))
}
// custom fields
req.Header.Set("X-Request-Id", e.RequestContext.RequestID)
req.Header.Set("X-Stage", e.RequestContext.Stage)
// xray support
if traceID := ctx.Value("x-amzn-trace-id"); traceID != nil {
req.Header.Set("X-Amzn-Trace-Id", fmt.Sprintf("%v", traceID))
}
// host
req.URL.Host = req.Header.Get("Host")
req.Host = req.URL.Host
return req, nil
}

110
vendor/github.com/apex/gateway/response.go generated vendored Normal file
View File

@ -0,0 +1,110 @@
package gateway
import (
"bytes"
"encoding/base64"
"net/http"
"strings"
"github.com/aws/aws-lambda-go/events"
)
// ResponseWriter implements the http.ResponseWriter interface
// in order to support the API Gateway Lambda HTTP "protocol".
type ResponseWriter struct {
out events.APIGatewayProxyResponse
buf bytes.Buffer
header http.Header
wroteHeader bool
}
// NewResponse returns a new response writer to capture http output.
func NewResponse() *ResponseWriter {
return &ResponseWriter{}
}
// Header implementation.
func (w *ResponseWriter) Header() http.Header {
if w.header == nil {
w.header = make(http.Header)
}
return w.header
}
// Write implementation.
func (w *ResponseWriter) Write(b []byte) (int, error) {
if !w.wroteHeader {
w.WriteHeader(http.StatusOK)
}
// TODO: HEAD? ignore
return w.buf.Write(b)
}
// WriteHeader implementation.
func (w *ResponseWriter) WriteHeader(status int) {
if w.wroteHeader {
return
}
if w.Header().Get("Content-Type") == "" {
w.Header().Set("Content-Type", "text/plain; charset=utf8")
}
w.out.StatusCode = status
h := make(map[string]string)
for k, v := range w.Header() {
if len(v) > 0 {
h[k] = v[len(v)-1]
}
}
w.out.Headers = h
w.wroteHeader = true
}
// End the request.
func (w *ResponseWriter) End() events.APIGatewayProxyResponse {
w.out.IsBase64Encoded = isBinary(w.header)
if w.out.IsBase64Encoded {
w.out.Body = base64.StdEncoding.EncodeToString(w.buf.Bytes())
} else {
w.out.Body = w.buf.String()
}
return w.out
}
// isBinary returns true if the response reprensents binary.
func isBinary(h http.Header) bool {
if !isTextMime(h.Get("Content-Type")) {
return true
}
if h.Get("Content-Encoding") == "gzip" {
return true
}
return false
}
// isTextMime returns true if the content type represents textual data.
func isTextMime(kind string) bool {
switch {
case strings.HasSuffix(kind, "svg+xml"):
return true
case strings.HasPrefix(kind, "text/"):
return true
case strings.HasPrefix(kind, "application/") && strings.HasSuffix(kind, "json"):
return true
case strings.HasPrefix(kind, "application/") && strings.HasSuffix(kind, "xml"):
return true
default:
return false
}
}

203
vendor/github.com/aws/aws-lambda-go/LICENSE generated vendored Normal file
View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

15
vendor/github.com/aws/aws-lambda-go/LICENSE-LAMBDACODE generated vendored Normal file
View File

@ -0,0 +1,15 @@
MIT No Attribution
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

7
vendor/github.com/aws/aws-lambda-go/LICENSE-SUMMARY generated vendored Normal file
View File

@ -0,0 +1,7 @@
Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Lambda functions are made available under a modified MIT license.
See LICENSE-LAMBDACODE for details.
The remainder of the project is made available under the terms of the
Apache License, version 2.0. See LICENSE for details.

21
vendor/github.com/aws/aws-lambda-go/events/README.md generated vendored Normal file
View File

@ -0,0 +1,21 @@
# Overview
This package provides input types for Lambda functions that process AWS events.
# Samples
[API Gateway](README_ApiGatewayEvent.md)
[Cognito Events](README_Cognito.md)
[Config Events](README_Config.md)
[DynamoDB Events](README_DynamoDB.md)
[Kinesis Events](README_Kinesis.md)
[Kinesis Firehose Events](README_KinesisFirehose.md)
[S3 Events](README_S3.md)
[SNS Events](README_SNS.md)

View File

@ -0,0 +1,36 @@
# Overview
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.
# Sample Function
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 by default anything written to Console will be logged as CloudWatch Logs events.)
```go
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID)
fmt.Printf("Body size = %d.\n", len(request.Body))
fmt.Println("Headers:")
for key, value := range request.Headers {
fmt.Printf(" %s: %s\n", key, value)
}
return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil
}
func main() {
lambda.Start(handleRequest)
}
```

View File

@ -0,0 +1,22 @@
# Sample Function
The following is a sample Lambda function that receives Amazon Cognito event record data as an input and writes some of the record data to CloudWatch Logs. (Note that by default anything written to Console will be logged as CloudWatch Logs events.)
```go
import (
"strings"
"github.com/aws/aws-lambda-go/events"
)
func handleRequest(ctx context.Context, cognitoEvent events.CognitoEvent) {
for datasetName, datasetRecord := range cognitoEvent.DatasetRecords {
fmt.Printf("[%s -- %s] %s -> %s -> %s \n",
cognitoEvent.EventType,
datasetName,
datasetRecord.OldValue,
datasetRecord.Op,
datasetRecord.NewValue)
}
}
```

View File

@ -0,0 +1,18 @@
# Sample Function
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 by default anything written to Console will be logged as CloudWatch Logs events.)
```go
import (
"strings"
"github.com/aws/aws-lambda-go/events"
)
func handleRequest(ctx context.Context, configEvent events.ConfigEvent) {
fmt.Printf("AWS Config rule: %s\n", configEvent.ConfigRuleName)
fmt.Printf("Invoking event JSON: %s\n", configEvent.InvokingEvent)
fmt.Printf("Event version: %s\n", configEvent.Version)
}
```

View File

@ -0,0 +1,79 @@
# Sample Function
The following is a sample Lambda function that receives DynamoDB event data as input and writes some of the record data to CloudWatch Logs. (Note that by default anything written to Console will be logged as CloudWatch Logs.)
```go
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
func handleRequest(ctx context.Context, e events.DynamoDBEvent) {
for _, record := range e.Records {
fmt.Printf("Processing request data for event ID %s, type %s.\n", record.EventID, record.EventName)
// Print new values for attributes of type String
for name, value := range record.Change.NewImage {
if value.DataType() == events.DataTypeString {
fmt.Printf("Attribute name: %s, value: %s\n", name, value.String())
}
}
}
```
# Reading attribute values
Stream notifications are delivered to the Lambda handler whenever data in the DynamoDB table is modified.
Depending on the Stream settings, a StreamRecord may contain the following data:
* Keys: key attributes of the modified item.
* NewImage: the entire item, as it appears after it was modified.
* OldImage: the entire item, as it appeared before it was modified.
The values for the attributes can be accessed using the AttributeValue type. For each type
supported natively by DynamoDB, there is a corresponding accessor method:
DynamoDB type | AttributeValue accessor method | Return type | DataType constant
---------------|--------------------------------|---------------------------|------------------
B (Binary) | Binary() | []byte | DataTypeBinary
BOOL (Boolean) | Boolean() | bool | DataTypeBoolean
BS (Binary Set)| BinarySet() | [][]byte | DataTypeBinarySet
L (List) | List() | []AttributeValue | DataTypeList
M (Map) | Map() | map[string]AttributeValue | DataTypeMap
N (Number) | Number() / Integer() / Float() | string / int64 / float64 | DataTypeNumber
NS (Number Set)| NumberSet() | []string | DataTypeNumberSet
NULL (Null) | IsNull() | bool | DataTypeNull
S (String) | String() | string | DataTypeString
SS (String Set)| StringSet() | []string | DataTypeStringSet
Calling the accessor method for the incorrect type will result in a panic. If the type needs to
be discovered in runtime, the method DataType() can be used in order to determine the correct accessor.
More information about DynamoDB data types can be seen [in this documentation](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html).
The following example reads values of attributes name and age, for which types are known to be String and Number:
```go
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
func handleRequest(ctx context.Context, e events.DynamoDBEvent) {
for _, record := range e.Records {
fmt.Printf("Processing request data for event ID %s, type %s.\n", record.EventID, record.EventName)
// Print new values for attributes name and age
name := record.Change.NewImage["name"].String()
age, _ := record.Change.NewImage["age"].Integer()
fmt.Printf("Name: %s, age: %d\n", name, age)
}
}
```

View File

@ -0,0 +1,21 @@
# Sample Function
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 by default anything written to Console will be logged as CloudWatch Logs events.)
```go
import (
"strings"
"github.com/aws/aws-lambda-go/events")
func handler(ctx context.Context, kinesisEvent events.KinesisEvent) {
for _, record := range kinesisEvent.Records {
kinesisRecord := record.Kinesis
dataBytes := kinesisRecordData.Data
dataText := string(dataBytes)
fmt.Printf("%s Data = %s \n", record.EventName, dataText)
}
}
```

View File

@ -0,0 +1,36 @@
# Sample Function
The following is a sample Lambda function that transforms Kinesis Firehose records by doing a ToUpper on the data.
```go
import (
"fmt"
"strings"
"github.com/aws/aws-lambda-go/events"
)
func handleRequest(evnt events.KinesisFirehoseEvent) events.KinesisFirehoseResponse {
fmt.Printf("InvocationId: %s\n", evnt.InvocationId)
fmt.Printf("DeliveryStreamArn: %s\n", evnt.DeliveryStreamArn)
fmt.Printf("Region: %s\n", evnt.Region)
var response events.KinesisFirehoseResponse
for _, record := range evnt.Records {
fmt.Printf("RecordId: %s\n", record.RecordId)
fmt.Printf("ApproximateArrivalTimestamp: %s\n", record.ApproximateArrivalTimestamp)
// Transform data: ToUpper the data
var transformedRecord kinesisfhevents.FirehoseResponseRecord
transformedRecord.RecordId = record.RecordId
transformedRecord.Result = kinesisfhevents.TransformedStateOk
transformedRecord.Data = strings.ToUpper(string(record.Data))
response.Records = append(response.Records, transformedRecord)
}
return response
}
```

View File

@ -0,0 +1,18 @@
# Sample Function
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 by default anything written to Console will be logged as CloudWatch Logs events.)
```go
import (
"strings"
"github.com/aws/aws-lambda-go/events")
func handler(ctx context.Context, s3Event events.S3Event) {
for _, record := range s3Event.Records {
s3 := record.S3
fmt.Printf("[%s - %s] Bucket = %s, Key = %s \n", record.EventSource, record.EventTime, s3.Bucket.Name, s3.Object.Key)
}
}
```

View File

@ -0,0 +1,21 @@
# Sample Function
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 by default anything written to Console will be logged as CloudWatch Logs events.)
```go
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
func handler(ctx context.Context, snsEvent events.SNSEvent) {
for _, record := range snsEvent.Records {
snsRecord := record.SNS
fmt.Printf("[%s %s] Message = %s \n", record.EventSource, snsRecord.Timestamp, snsRecord.Message)
}
}
```

63
vendor/github.com/aws/aws-lambda-go/events/apigw.go generated vendored Normal file
View File

@ -0,0 +1,63 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
// APIGatewayProxyRequest contains data coming from the API Gateway proxy
type APIGatewayProxyRequest struct {
Resource string `json:"resource"` // The resource path defined in API Gateway
Path string `json:"path"` // The url path for the caller
HTTPMethod string `json:"httpMethod"`
Headers map[string]string `json:"headers"`
QueryStringParameters map[string]string `json:"queryStringParameters"`
PathParameters map[string]string `json:"pathParameters"`
StageVariables map[string]string `json:"stageVariables"`
RequestContext APIGatewayProxyRequestContext `json:"requestContext"`
Body string `json:"body"`
IsBase64Encoded bool `json:"isBase64Encoded,omitempty"`
}
// APIGatewayProxyResponse configures the response to be returned by API Gateway for the request
type APIGatewayProxyResponse struct {
StatusCode int `json:"statusCode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
IsBase64Encoded bool `json:"isBase64Encoded,omitempty"`
}
// APIGatewayProxyRequestContext contains the information to identify the AWS account and resources invoking the
// Lambda function. It also includes Cognito identity information for the caller.
type APIGatewayProxyRequestContext struct {
AccountID string `json:"accountId"`
ResourceID string `json:"resourceId"`
Stage string `json:"stage"`
RequestID string `json:"requestId"`
Identity APIGatewayRequestIdentity `json:"identity"`
ResourcePath string `json:"resourcePath"`
Authorizer map[string]interface{} `json:"authorizer"`
HTTPMethod string `json:"httpMethod"`
APIID string `json:"apiId"` // The API Gateway rest API Id
}
// APIGatewayRequestIdentity contains identity information for the request caller.
type APIGatewayRequestIdentity struct {
CognitoIdentityPoolID string `json:"cognitoIdentityPoolId"`
AccountID string `json:"accountId"`
CognitoIdentityID string `json:"cognitoIdentityId"`
Caller string `json:"caller"`
APIKey string `json:"apiKey"`
SourceIP string `json:"sourceIp"`
CognitoAuthenticationType string `json:"cognitoAuthenticationType"`
CognitoAuthenticationProvider string `json:"cognitoAuthenticationProvider"`
UserArn string `json:"userArn"`
UserAgent string `json:"userAgent"`
User string `json:"user"`
}
// APIGatewayCustomAuthorizerContext represents the expected format of an API Gateway custom authorizer response.
// Deprecated. Code should be updated to use the Authorizer map from APIGatewayRequestIdentity. Ex: Authorizer["principalId"]
type APIGatewayCustomAuthorizerContext struct {
PrincipalID *string `json:"principalId"`
StringKey *string `json:"stringKey,omitempty"`
NumKey *int `json:"numKey,omitempty"`
BoolKey *bool `json:"boolKey,omitempty"`
}

View File

@ -0,0 +1,457 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"strconv"
)
// DynamoDBAttributeValue provides convenient access for a value stored in DynamoDB.
// For more information, please see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html
type DynamoDBAttributeValue struct {
value anyValue
dataType DynamoDBDataType
}
// Binary provides access to an attribute of type Binary.
// Method panics if the attribute is not of type Binary.
func (av DynamoDBAttributeValue) Binary() []byte {
av.ensureType(DataTypeBinary)
return av.value.([]byte)
}
// Boolean provides access to an attribute of type Boolean.
// Method panics if the attribute is not of type Boolean.
func (av DynamoDBAttributeValue) Boolean() bool {
av.ensureType(DataTypeBoolean)
return av.value.(bool)
}
// BinarySet provides access to an attribute of type Binary Set.
// Method panics if the attribute is not of type BinarySet.
func (av DynamoDBAttributeValue) BinarySet() [][]byte {
av.ensureType(DataTypeBinarySet)
return av.value.([][]byte)
}
// List provides access to an attribute of type List. Each element
// of the list is an DynamoDBAttributeValue itself.
// Method panics if the attribute is not of type List.
func (av DynamoDBAttributeValue) List() []DynamoDBAttributeValue {
av.ensureType(DataTypeList)
return av.value.([]DynamoDBAttributeValue)
}
// Map provides access to an attribute of type Map. They Keys are strings
// and the values are DynamoDBAttributeValue instances.
// Method panics if the attribute is not of type Map.
func (av DynamoDBAttributeValue) Map() map[string]DynamoDBAttributeValue {
av.ensureType(DataTypeMap)
return av.value.(map[string]DynamoDBAttributeValue)
}
// Number provides access to an attribute of type Number.
// DynamoDB sends the values as strings. For convenience please see also
// the methods Integer() and Float().
// Method panics if the attribute is not of type Number.
func (av DynamoDBAttributeValue) Number() string {
av.ensureType(DataTypeNumber)
return av.value.(string)
}
// Integer provides access to an attribute of type Number.
// DynamoDB sends the values as strings. For convenience this method
// provides conversion to int. If the value cannot be represented by
// a signed integer, err.Err = ErrRange and the returned value is the maximum magnitude integer
// of an int64 of the appropriate sign.
// Method panics if the attribute is not of type Number.
func (av DynamoDBAttributeValue) Integer() (int64, error) {
s, err := strconv.ParseFloat(av.Number(), 64)
return int64(s), err
}
// Float provides access to an attribute of type Number.
// DynamoDB sends the values as strings. For convenience this method
// provides conversion to float64.
// The returned value is the nearest floating point number rounded using IEEE754 unbiased rounding.
// If the number is more than 1/2 ULP away from the largest floating point number of the given size,
// the value returned is ±Inf, err.Err = ErrRange.
// Method panics if the attribute is not of type Number.
func (av DynamoDBAttributeValue) Float() (float64, error) {
s, err := strconv.ParseFloat(av.Number(), 64)
return s, err
}
// NumberSet provides access to an attribute of type Number Set.
// DynamoDB sends the numbers as strings.
// Method panics if the attribute is not of type Number.
func (av DynamoDBAttributeValue) NumberSet() []string {
av.ensureType(DataTypeNumberSet)
return av.value.([]string)
}
// String provides access to an attribute of type String.
// Method panics if the attribute is not of type String.
func (av DynamoDBAttributeValue) String() string {
av.ensureType(DataTypeString)
return av.value.(string)
}
// StringSet provides access to an attribute of type String Set.
// Method panics if the attribute is not of type String Set.
func (av DynamoDBAttributeValue) StringSet() []string {
av.ensureType(DataTypeStringSet)
return av.value.([]string)
}
// IsNull returns true if the attribute is of type Null.
func (av DynamoDBAttributeValue) IsNull() bool {
return av.value == nil
}
// DataType provides access to the DynamoDB type of the attribute
func (av DynamoDBAttributeValue) DataType() DynamoDBDataType {
return av.dataType
}
// NewStringAttribute creates an DynamoDBAttributeValue containing a String
func NewStringAttribute(value string) DynamoDBAttributeValue {
var av DynamoDBAttributeValue
av.value = value
av.dataType = DataTypeString
return av
}
// DynamoDBDataType specifies the type supported natively by DynamoDB for an attribute
type DynamoDBDataType int
const (
DataTypeBinary DynamoDBDataType = iota
DataTypeBoolean
DataTypeBinarySet
DataTypeList
DataTypeMap
DataTypeNumber
DataTypeNumberSet
DataTypeNull
DataTypeString
DataTypeStringSet
)
type anyValue interface{}
// UnsupportedDynamoDBTypeError is the error returned when trying to unmarshal a DynamoDB Attribute type not recognized by this library
type UnsupportedDynamoDBTypeError struct {
Type string
}
func (e UnsupportedDynamoDBTypeError) Error() string {
return fmt.Sprintf("unsupported DynamoDB attribute type, %v", e.Type)
}
// IncompatibleDynamoDBTypeError is the error passed in a panic when calling an accessor for an incompatible type
type IncompatibleDynamoDBTypeError struct {
Requested DynamoDBDataType
Actual DynamoDBDataType
}
func (e IncompatibleDynamoDBTypeError) Error() string {
return fmt.Sprintf("accessor called for incompatible type, requested type %v but actual type was %v", e.Requested, e.Actual)
}
func (av *DynamoDBAttributeValue) ensureType(expectedType DynamoDBDataType) {
if av.dataType != expectedType {
panic(IncompatibleDynamoDBTypeError{Requested: expectedType, Actual: av.dataType})
}
}
// MarshalJSON implements custom marshaling to be used by the standard json/encoding package
func (av DynamoDBAttributeValue) MarshalJSON() ([]byte, error) {
var buff bytes.Buffer
var err error
var b []byte
switch av.dataType {
case DataTypeBinary:
buff.WriteString(`{ "B":`)
b, err = json.Marshal(av.value.([]byte))
buff.Write(b)
case DataTypeBoolean:
buff.WriteString(`{ "BOOL":`)
b, err = json.Marshal(av.value.(bool))
buff.Write(b)
case DataTypeBinarySet:
buff.WriteString(`{ "BS":`)
b, err = json.Marshal(av.value.([][]byte))
buff.Write(b)
case DataTypeList:
buff.WriteString(`{ "L":`)
b, err = json.Marshal(av.value.([]DynamoDBAttributeValue))
buff.Write(b)
case DataTypeMap:
buff.WriteString(`{ "M":`)
b, err = json.Marshal(av.value.(map[string]DynamoDBAttributeValue))
buff.Write(b)
case DataTypeNumber:
buff.WriteString(`{ "N":`)
b, err = json.Marshal(av.value.(string))
buff.Write(b)
case DataTypeNumberSet:
buff.WriteString(`{ "NS":`)
b, err = json.Marshal(av.value.([]string))
buff.Write(b)
case DataTypeNull:
buff.WriteString(`{ "NULL": true `)
case DataTypeString:
buff.WriteString(`{ "S":`)
b, err = json.Marshal(av.value.(string))
buff.Write(b)
case DataTypeStringSet:
buff.WriteString(`{ "SS":`)
b, err = json.Marshal(av.value.([]string))
buff.Write(b)
}
buff.WriteString(`}`)
return buff.Bytes(), err
}
func unmarshalNull(target *DynamoDBAttributeValue) error {
target.value = nil
target.dataType = DataTypeNull
return nil
}
func unmarshalString(target *DynamoDBAttributeValue, value interface{}) error {
var ok bool
target.value, ok = value.(string)
target.dataType = DataTypeString
if !ok {
return errors.New("DynamoDBAttributeValue: S type should contain a string")
}
return nil
}
func unmarshalBinary(target *DynamoDBAttributeValue, value interface{}) error {
stringValue, ok := value.(string)
if !ok {
return errors.New("DynamoDBAttributeValue: B type should contain a base64 string")
}
binaryValue, err := base64.StdEncoding.DecodeString(stringValue)
if err != nil {
return err
}
target.value = binaryValue
target.dataType = DataTypeBinary
return nil
}
func unmarshalBoolean(target *DynamoDBAttributeValue, value interface{}) error {
booleanValue, ok := value.(bool)
if !ok {
return errors.New("DynamoDBAttributeValue: BOOL type should contain a boolean")
}
target.value = booleanValue
target.dataType = DataTypeBoolean
return nil
}
func unmarshalBinarySet(target *DynamoDBAttributeValue, value interface{}) error {
list, ok := value.([]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: BS type should contain a list of base64 strings")
}
binarySet := make([][]byte, len(list))
for index, element := range list {
var err error
elementString := element.(string)
binarySet[index], err = base64.StdEncoding.DecodeString(elementString)
if err != nil {
return err
}
}
target.value = binarySet
target.dataType = DataTypeBinarySet
return nil
}
func unmarshalList(target *DynamoDBAttributeValue, value interface{}) error {
list, ok := value.([]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: L type should contain a list")
}
DynamoDBAttributeValues := make([]DynamoDBAttributeValue, len(list))
for index, element := range list {
elementMap, ok := element.(map[string]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: element of a list is not an DynamoDBAttributeValue")
}
var elementDynamoDBAttributeValue DynamoDBAttributeValue
err := unmarshalDynamoDBAttributeValueMap(&elementDynamoDBAttributeValue, elementMap)
if err != nil {
return errors.New("DynamoDBAttributeValue: unmarshal of child DynamoDBAttributeValue failed")
}
DynamoDBAttributeValues[index] = elementDynamoDBAttributeValue
}
target.value = DynamoDBAttributeValues
target.dataType = DataTypeList
return nil
}
func unmarshalMap(target *DynamoDBAttributeValue, value interface{}) error {
m, ok := value.(map[string]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: M type should contain a map")
}
DynamoDBAttributeValues := make(map[string]DynamoDBAttributeValue)
for k, v := range m {
elementMap, ok := v.(map[string]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: element of a map is not an DynamoDBAttributeValue")
}
var elementDynamoDBAttributeValue DynamoDBAttributeValue
err := unmarshalDynamoDBAttributeValueMap(&elementDynamoDBAttributeValue, elementMap)
if err != nil {
return errors.New("DynamoDBAttributeValue: unmarshal of child DynamoDBAttributeValue failed")
}
DynamoDBAttributeValues[k] = elementDynamoDBAttributeValue
}
target.value = DynamoDBAttributeValues
target.dataType = DataTypeMap
return nil
}
func unmarshalNumber(target *DynamoDBAttributeValue, value interface{}) error {
var ok bool
target.value, ok = value.(string)
target.dataType = DataTypeNumber
if !ok {
return errors.New("DynamoDBAttributeValue: N type should contain a string")
}
return nil
}
func unmarshalNumberSet(target *DynamoDBAttributeValue, value interface{}) error {
list, ok := value.([]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: NS type should contain a list of strings")
}
numberSet := make([]string, len(list))
for index, element := range list {
numberSet[index], ok = element.(string)
if !ok {
return errors.New("DynamoDBAttributeValue: NS type should contain a list of strings")
}
}
target.value = numberSet
target.dataType = DataTypeNumberSet
return nil
}
func unmarshalStringSet(target *DynamoDBAttributeValue, value interface{}) error {
list, ok := value.([]interface{})
if !ok {
return errors.New("DynamoDBAttributeValue: SS type should contain a list of strings")
}
stringSet := make([]string, len(list))
for index, element := range list {
stringSet[index], ok = element.(string)
if !ok {
return errors.New("DynamoDBAttributeValue: SS type should contain a list of strings")
}
}
target.value = stringSet
target.dataType = DataTypeStringSet
return nil
}
func unmarshalDynamoDBAttributeValue(target *DynamoDBAttributeValue, typeLabel string, jsonValue interface{}) error {
switch typeLabel {
case "NULL":
return unmarshalNull(target)
case "B":
return unmarshalBinary(target, jsonValue)
case "BOOL":
return unmarshalBoolean(target, jsonValue)
case "BS":
return unmarshalBinarySet(target, jsonValue)
case "L":
return unmarshalList(target, jsonValue)
case "M":
return unmarshalMap(target, jsonValue)
case "N":
return unmarshalNumber(target, jsonValue)
case "NS":
return unmarshalNumberSet(target, jsonValue)
case "S":
return unmarshalString(target, jsonValue)
case "SS":
return unmarshalStringSet(target, jsonValue)
default:
target.value = nil
target.dataType = DataTypeNull
return UnsupportedDynamoDBTypeError{typeLabel}
}
}
// UnmarshalJSON unmarshals a JSON description of this DynamoDBAttributeValue
func (av *DynamoDBAttributeValue) UnmarshalJSON(b []byte) error {
var m map[string]interface{}
err := json.Unmarshal(b, &m)
if err != nil {
return err
}
return unmarshalDynamoDBAttributeValueMap(av, m)
}
func unmarshalDynamoDBAttributeValueMap(target *DynamoDBAttributeValue, m map[string]interface{}) error {
if m == nil {
return errors.New("DynamoDBAttributeValue: does not contain a map")
}
if len(m) != 1 {
return errors.New("DynamoDBAttributeValue: map must contain a single type")
}
for k, v := range m {
return unmarshalDynamoDBAttributeValue(target, k, v)
}
return nil
}

View File

@ -0,0 +1,55 @@
package events
import (
"bytes"
"compress/gzip"
"encoding/base64"
"encoding/json"
)
// CloudwatchLogsEvent represents raw data from a cloudwatch logs event
type CloudwatchLogsEvent struct {
AWSLogs CloudwatchLogsRawData `json:"awslogs"`
}
// CloudwatchLogsRawData contains gzipped base64 json representing the bulk
// of a cloudwatch logs event
type CloudwatchLogsRawData struct {
Data string `json:"data"`
}
// Parse returns a slice of structs represting a usable CloudwatchLogs event
func (c CloudwatchLogsRawData) Parse() (d CloudwatchLogsData, err error) {
data, err := base64.StdEncoding.DecodeString(c.Data)
if err != nil {
return
}
zr, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return
}
buf := &bytes.Buffer{}
buf.ReadFrom(zr)
err = json.Unmarshal(buf.Bytes(), &d)
return
}
// CloudwatchLogsData is an unmarshal'd, ungzip'd, cloudwatch logs event
type CloudwatchLogsData struct {
Owner string `json:"owner"`
LogGroup string `json:"logGroup"`
LogStream string `json:"logStream"`
SubscriptionFilters []string `json:"subscriptionFilters"`
MessageType string `json:"messageType"`
LogEvents []CloudwatchLogsLogEvent `json:"logEvents"`
}
// LogEvent represents a log entry from cloudwatch logs
type CloudwatchLogsLogEvent struct {
ID string `json:"id"`
Timestamp int64 `json:"timestamp"`
Message string `json:"message"`
}

21
vendor/github.com/aws/aws-lambda-go/events/cognito.go generated vendored Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
// CognitoEvent contains data from an event sent from AWS Cognito
type CognitoEvent struct {
DatasetName string `json:"datasetName"`
DatasetRecords map[string]CognitoDatasetRecord `json:"datasetRecords"`
EventType string `json:"eventType"`
IdentityID string `json:"identityId"`
IdentityPoolID string `json:"identityPoolId"`
Region string `json:"region"`
Version int `json:"version"`
}
// CognitoDatasetRecord represents a record from an AWS Cognito event
type CognitoDatasetRecord struct {
NewValue string `json:"newValue"`
OldValue string `json:"oldValue"`
Op string `json:"op"`
}

17
vendor/github.com/aws/aws-lambda-go/events/config.go generated vendored Normal file
View File

@ -0,0 +1,17 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
// ConfigEvent contains data from an event sent from AWS Config
type ConfigEvent struct {
AccountID string `json:"accountId"` // The ID of the AWS account that owns the rule
ConfigRuleArn string `json:"configRuleArn"` // The ARN that AWS Config assigned to the rule
ConfigRuleID string `json:"configRuleId"`
ConfigRuleName string `json:"configRuleName"` // The name that you assigned to the rule that caused AWS Config to publish the event
EventLeftScope bool `json:"eventLeftScope"` // A boolean value that indicates whether the AWS resource to be evaluated has been removed from the rule's scope
ExecutionRoleArn string `json:"executionRoleArn"`
InvokingEvent string `json:"invokingEvent"` // If the event is published in response to a resource configuration change, this value contains a JSON configuration item
ResultToken string `json:"resultToken"` // A token that the function must pass to AWS Config with the PutEvaluations call
RuleParameters string `json:"ruleParameters"` // Key/value pairs that the function processes as part of its evaluation logic
Version string `json:"version"`
}

117
vendor/github.com/aws/aws-lambda-go/events/dynamodb.go generated vendored Normal file
View File

@ -0,0 +1,117 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
// The DynamoDBEvent stream event handled to Lambda
// http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-ddb-update
type DynamoDBEvent struct {
Records []DynamoDBEventRecord `json:"Records"`
}
// DynamoDbEventRecord stores information about each record of a DynamoDb stream event
type DynamoDBEventRecord struct {
// The region in which the GetRecords request was received.
AWSRegion string `json:"awsRegion"`
// The main body of the stream record, containing all of the DynamoDB-specific
// fields.
Change DynamoDBStreamRecord `json:"dynamodb"`
// A globally unique identifier for the event that was recorded in this stream
// record.
EventID string `json:"eventID"`
// The type of data modification that was performed on the DynamoDB table:
//
// * INSERT - a new item was added to the table.
//
// * MODIFY - one or more of an existing item's attributes were modified.
//
// * REMOVE - the item was deleted from the table
EventName string `json:"eventName"`
// The AWS service from which the stream record originated. For DynamoDB Streams,
// this is aws:dynamodb.
EventSource string `json:"eventSource"`
// The version number of the stream record format. This number is updated whenever
// the structure of Record is modified.
//
// Client applications must not assume that eventVersion will remain at a particular
// value, as this number is subject to change at any time. In general, eventVersion
// will only increase as the low-level DynamoDB Streams API evolves.
EventVersion string `json:"eventVersion"`
// The event source ARN of DynamoDB
EventSourceArn string `json:"eventSourceARN"`
}
// A description of a single data modification that was performed on an item
// in a DynamoDB table.
type DynamoDBStreamRecord struct {
// The approximate date and time when the stream record was created, in UNIX
// epoch time (http://www.epochconverter.com/) format.
ApproximateCreationDateTime SecondsEpochTime `json:"ApproximateCreationDateTime,omitempty"`
// The primary key attribute(s) for the DynamoDB item that was modified.
Keys map[string]DynamoDBAttributeValue `json:"Keys,omitempty"`
// The item in the DynamoDB table as it appeared after it was modified.
NewImage map[string]DynamoDBAttributeValue `json:"NewImage,omitempty"`
// The item in the DynamoDB table as it appeared before it was modified.
OldImage map[string]DynamoDBAttributeValue `json:"OldImage,omitempty"`
// The sequence number of the stream record.
SequenceNumber string `json:"SequenceNumber"`
// The size of the stream record, in bytes.
SizeBytes int64 `json:"SizeBytes"`
// The type of data from the modified DynamoDB item that was captured in this
// stream record.
StreamViewType string `json:"StreamViewType"`
}
type DynamoDBKeyType string
const (
DynamoDBKeyTypeHash DynamoDBKeyType = "HASH"
DynamoDBKeyTypeRange DynamoDBKeyType = "RANGE"
)
type DynamoDBOperationType string
const (
DynamoDBOperationTypeInsert DynamoDBOperationType = "INSERT"
DynamoDBOperationTypeModify DynamoDBOperationType = "MODIFY"
DynamoDBOperationTypeRemove DynamoDBOperationType = "REMOVE"
)
type DynamoDBSharedIteratorType string
const (
DynamoDBShardIteratorTypeTrimHorizon DynamoDBSharedIteratorType = "TRIM_HORIZON"
DynamoDBShardIteratorTypeLatest DynamoDBSharedIteratorType = "LATEST"
DynamoDBShardIteratorTypeAtSequenceNumber DynamoDBSharedIteratorType = "AT_SEQUENCE_NUMBER"
DynamoDBShardIteratorTypeAfterSequenceNumber DynamoDBSharedIteratorType = "AFTER_SEQUENCE_NUMBER"
)
type DynamoDBStreamStatus string
const (
DynamoDBStreamStatusEnabling DynamoDBStreamStatus = "ENABLING"
DynamoDBStreamStatusEnabled DynamoDBStreamStatus = "ENABLED"
DynamoDBStreamStatusDisabling DynamoDBStreamStatus = "DISABLING"
DynamoDBStreamStatusDisabled DynamoDBStreamStatus = "DISABLED"
)
type DynamoDBStreamViewType string
const (
DynamoDBStreamViewTypeNewImage DynamoDBStreamViewType = "NEW_IMAGE" // the entire item, as it appeared after it was modified.
DynamoDBStreamViewTypeOldImage DynamoDBStreamViewType = "OLD_IMAGE" // the entire item, as it appeared before it was modified.
DynamoDBStreamViewTypeNewAndOldImages DynamoDBStreamViewType = "NEW_AND_OLD_IMAGES" // both the new and the old item images of the item.
DynamoDBStreamViewTypeKeysOnly DynamoDBStreamViewType = "KEYS_ONLY" // only the key attributes of the modified item.
)

View File

@ -0,0 +1,59 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
import (
"encoding/json"
"time"
)
// SecondsEpochTime serializes a time.Time in JSON as a UNIX epoch time in seconds
type SecondsEpochTime struct {
time.Time
}
// MilliSecondsEpochTime serializes a time.Time in JSON as a UNIX epoch time in milliseconds.
type MilliSecondsEpochTime struct {
time.Time
}
const secondsToNanoSecondsFactor = 1000000000
const milliSecondsToNanoSecondsFactor = 1000000
func (e SecondsEpochTime) MarshalJSON() ([]byte, error) {
// UnixNano() returns the epoch in nanoseconds
unixTime := float64(e.UnixNano()) / float64(secondsToNanoSecondsFactor)
return json.Marshal(unixTime)
}
func (e *SecondsEpochTime) UnmarshalJSON(b []byte) error {
var epoch float64
err := json.Unmarshal(b, &epoch)
if err != nil {
return err
}
epochSec := int64(epoch)
epochNano := int64((epoch - float64(epochSec)) * float64(secondsToNanoSecondsFactor))
// time.Unix(sec, nsec) expects the epoch integral seconds in the first parameter
// and remaining nanoseconds in the second parameter
*e = SecondsEpochTime{time.Unix(epochSec, epochNano)}
return nil
}
func (e MilliSecondsEpochTime) MarshalJSON() ([]byte, error) {
// UnixNano() returns the epoch in nanoseconds
unixTimeMs := e.UnixNano() / milliSecondsToNanoSecondsFactor
return json.Marshal(unixTimeMs)
}
func (e *MilliSecondsEpochTime) UnmarshalJSON(b []byte) error {
var epoch int64
err := json.Unmarshal(b, &epoch)
if err != nil {
return err
}
*e = MilliSecondsEpochTime{time.Unix(epoch/1000, (epoch%1000)*1000000)}
return nil
}

34
vendor/github.com/aws/aws-lambda-go/events/firehose.go generated vendored Normal file
View File

@ -0,0 +1,34 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
// KinesisFirehoseEvent represents the input event from Amazon Kinesis Firehose. It is used as the input parameter.
type KinesisFirehoseEvent struct {
InvocationID string `json:"invocationId"`
DeliveryStreamArn string `json:"deliveryStreamArn"`
Region string `json:"region"`
Records []KinesisFirehoseEventRecord `json:"records"`
}
type KinesisFirehoseEventRecord struct {
RecordID string `json:"recordId"`
ApproximateArrivalTimestamp MilliSecondsEpochTime `json:"approximateArrivalTimestamp"`
Data []byte `json:"data"`
}
// Constants used for describing the transformation result
const (
KinesisFirehoseTransformedStateOk = "TRANSFORMED_STATE_OK"
KinesisFirehoseTransformedStateDropped = "TRANSFORMED_STATE_DROPPED"
KinesisFirehoseTransformedStateProcessingFailed = "TRANSFORMED_STATE_PROCESSINGFAILED"
)
type KinesisFirehoseResponse struct {
Records []KinesisFirehoseResponseRecord `json:"records"`
}
type KinesisFirehoseResponseRecord struct {
RecordID string `json:"recordId"`
Result string `json:"result"` // The status of the transformation. May be TransformedStateOk, TransformedStateDropped or TransformedStateProcessingFailed
Data []byte `json:"data"`
}

27
vendor/github.com/aws/aws-lambda-go/events/kinesis.go generated vendored Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
type KinesisEvent struct {
Records []KinesisEventRecord `json:"Records"`
}
type KinesisEventRecord struct {
AwsRegion string `json:"awsRegion"`
EventID string `json:"eventID"`
EventName string `json:"eventName"`
EventSource string `json:"eventSource"`
EventSourceArn string `json:"eventSourceARN"`
EventVersion string `json:"eventVersion"`
InvokeIdentityArn string `json:"invokeIdentityArn"`
Kinesis KinesisRecord `json:"kinesis"`
}
type KinesisRecord struct {
ApproximateArrivalTimestamp SecondsEpochTime `json:"approximateArrivalTimestamp"`
Data []byte `json:"data"`
EncryptionType string `json:"encryptionType,omitempty"`
PartitionKey string `json:"partitionKey"`
SequenceNumber string `json:"sequenceNumber"`
KinesisSchemaVersion string `json:"kinesisSchemaVersion"`
}

53
vendor/github.com/aws/aws-lambda-go/events/s3.go generated vendored Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
import (
"time"
)
type S3Event struct {
Records []S3EventRecord `json:"Records"`
}
type S3EventRecord struct {
EventVersion string `json:"eventVersion"`
EventSource string `json:"eventSource"`
AWSRegion string `json:"awsRegion"`
EventTime time.Time `json:"eventTime"`
EventName string `json:"eventName"`
PrincipalID S3UserIdentity `json:"userIdentity"`
RequestParameters S3RequestParameters `json:"requestParameters"`
ResponseElements map[string]string `json:"responseElements"`
S3 S3Entity `json:"s3"`
}
type S3UserIdentity struct {
PrincipalID string `json:"principalId"`
}
type S3RequestParameters struct {
SourceIPAddress string `json:"sourceIPAddress"`
}
type S3Entity struct {
SchemaVersion string `json:"s3SchemaVersion"`
ConfigurationID string `json:"configurationId"`
Bucket S3Bucket `json:"bucket"`
Object S3Object `json:"object"`
}
type S3Bucket struct {
Name string `json:"name"`
OwnerIdentity S3UserIdentity `json:"ownerIdentity"`
Arn string `json:"arn"`
}
type S3Object struct {
Key string `json:"key"`
Size int64 `json:"size"`
URLDecodedKey string `json:"urlDecodedKey"`
VersionID string `json:"versionId"`
ETag string `json:"eTag"`
Sequencer string `json:"sequencer"`
}

32
vendor/github.com/aws/aws-lambda-go/events/sns.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package events
import (
"time"
)
type SNSEvent struct {
Records []SNSEventRecord `json:"Records"`
}
type SNSEventRecord struct {
EventVersion string `json:"EventVersion"`
EventSubscriptionArn string `json:"EventSubscriptionArn"`
EventSource string `json:"EventSource"`
SNS SNSEntity `json:"Sns"`
}
type SNSEntity struct {
Signature string `json:"Signature"`
MessageID string `json:"MessageId"`
Type string `json:"Type"`
TopicArn string `json:"TopicArn"`
MessageAttributes map[string]interface{} `json:"MessageAttributes"`
SignatureVersion string `json:"SignatureVersion"`
Timestamp time.Time `json:"Timestamp"`
SigningCertURL string `json:"SigningCertUrl"`
Message string `json:"Message"`
UnsubscribeURL string `json:"UnsubscribeUrl"`
Subject string `json:"Subject"`
}

52
vendor/github.com/aws/aws-lambda-go/lambda/entry.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package lambda
import (
"fmt"
"log"
"net"
"net/rpc"
"os"
)
// Start takes a handler, and talks to and internal Lambda endpoint to pass Invoke requests to the handler. If a
// handler does not match one of the supported types, the lambda package will respond to new invokes served by in
// internal endpoint with an appropriate error message. Start blocks, and does not return after being called.
//
// Rules:
// * handler must be a function
// * handler may take between 0 and two arguments.
// * If there are two arguments, the first argument must implement "context.Context".
// * handler may return between 0 and two arguments.
// * If there are two return values, the second argument must implement "error".
// * If there is one return value it must implement "error".
//
// func ()
// func () error
// func (TIn) error
// func () (TOut, error)
// func (TIn) (TOut, error)
// func (context.Context) error
// func (context.Context, TIn) error
// func (context.Context) (TOut, error)
// func (context.Context, TIn) (TOut, error)
//
// Where '''TIn''' and '''TOut''' are types compatible with the ''encoding/json'' standard library.
// See https://golang.org/pkg/encoding/json/#Unmarshal for how deserialization behaves
func Start(handler interface{}) {
port := os.Getenv("_LAMBDA_SERVER_PORT")
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%s", port))
if err != nil {
log.Fatal(err)
}
wrappedHandler := newHandler(handler)
function := new(Function)
function.handler = wrappedHandler
err = rpc.Register(function)
if err != nil {
log.Fatal("failed to register handler function")
}
rpc.Accept(lis)
log.Fatal("accept should not have returned")
}

83
vendor/github.com/aws/aws-lambda-go/lambda/function.go generated vendored Normal file
View File

@ -0,0 +1,83 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package lambda
import (
"context"
"encoding/json"
"reflect"
"time"
"github.com/aws/aws-lambda-go/lambda/messages"
"github.com/aws/aws-lambda-go/lambdacontext"
)
type Function struct {
handler lambdaHandler
}
func (fn *Function) Ping(req *messages.PingRequest, response *messages.PingResponse) error {
*response = messages.PingResponse{}
return nil
}
func (fn *Function) Invoke(req *messages.InvokeRequest, response *messages.InvokeResponse) error {
defer func() {
if err := recover(); err != nil {
panicInfo := getPanicInfo(err)
response.Error = &messages.InvokeResponse_Error{
Message: panicInfo.Message,
Type: getErrorType(err),
StackTrace: panicInfo.StackTrace,
ShouldExit: true,
}
}
}()
deadline := time.Unix(req.Deadline.Seconds, req.Deadline.Nanos).UTC()
invokeContext, cancel := context.WithDeadline(context.Background(), deadline)
defer cancel()
lc := &lambdacontext.LambdaContext{
AwsRequestID: req.RequestId,
InvokedFunctionArn: req.InvokedFunctionArn,
}
if len(req.ClientContext) > 0 {
if err := json.Unmarshal(req.ClientContext, &lc.ClientContext); err != nil {
response.Error = lambdaErrorResponse(err)
return nil
}
}
invokeContext = lambdacontext.NewContext(invokeContext, lc)
invokeContext = context.WithValue(invokeContext, "x-amzn-trace-id", req.XAmznTraceId)
payload, err := fn.handler.Invoke(invokeContext, req.Payload)
if err != nil {
response.Error = lambdaErrorResponse(err)
return nil
}
response.Payload = payload
return nil
}
func getErrorType(err interface{}) string {
errorType := reflect.TypeOf(err)
if errorType.Kind() == reflect.Ptr {
return errorType.Elem().Name()
}
return errorType.Name()
}
func lambdaErrorResponse(invokeError error) *messages.InvokeResponse_Error {
var errorName string
if errorType := reflect.TypeOf(invokeError); errorType.Kind() == reflect.Ptr {
errorName = errorType.Elem().Name()
} else {
errorName = errorType.Name()
}
return &messages.InvokeResponse_Error{
Message: invokeError.Error(),
Type: errorName,
}
}

123
vendor/github.com/aws/aws-lambda-go/lambda/handler.go generated vendored Normal file
View File

@ -0,0 +1,123 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package lambda
import (
"context"
"encoding/json"
"fmt"
"reflect"
)
// lambdaHandler is the generic function type
type lambdaHandler func(context.Context, []byte) (interface{}, error)
// Invoke calls the handler, and serializes the response.
// If the underlying handler returned an error, or an error occurs during serialization, error is returned.
func (handler lambdaHandler) Invoke(ctx context.Context, payload []byte) ([]byte, error) {
response, err := handler(ctx, payload)
if err != nil {
return nil, err
}
responseBytes, err := json.Marshal(response)
if err != nil {
return nil, err
}
return responseBytes, nil
}
func errorHandler(e error) lambdaHandler {
return func(ctx context.Context, event []byte) (interface{}, error) {
return nil, e
}
}
func validateArguments(handler reflect.Type) (bool, error) {
handlerTakesContext := false
if handler.NumIn() > 2 {
return false, fmt.Errorf("handlers may not take more than two arguments, but handler takes %d", handler.NumIn())
} else if handler.NumIn() > 0 {
contextType := reflect.TypeOf((*context.Context)(nil)).Elem()
argumentType := handler.In(0)
handlerTakesContext = argumentType.Implements(contextType)
if handler.NumIn() > 1 && !handlerTakesContext {
return false, fmt.Errorf("handler takes two arguments, but the first is not Context. got %s", argumentType.Kind())
}
}
return handlerTakesContext, nil
}
func validateReturns(handler reflect.Type) error {
errorType := reflect.TypeOf((*error)(nil)).Elem()
if handler.NumOut() > 2 {
return fmt.Errorf("handler may not return more than two values")
} else if handler.NumOut() > 1 {
if !handler.Out(1).Implements(errorType) {
return fmt.Errorf("handler returns two values, but the second does not implement error")
}
} else if handler.NumOut() == 1 {
if !handler.Out(0).Implements(errorType) {
return fmt.Errorf("handler returns a single value, but it does not implement error")
}
}
return nil
}
// newHandler Creates the base lambda handler, which will do basic payload unmarshaling before defering to handlerSymbol.
// If handlerSymbol is not a valid handler, the returned function will be a handler that just reports the validation error.
func newHandler(handlerSymbol interface{}) lambdaHandler {
if handlerSymbol == nil {
return errorHandler(fmt.Errorf("handler is nil"))
}
handler := reflect.ValueOf(handlerSymbol)
handlerType := reflect.TypeOf(handlerSymbol)
if handlerType.Kind() != reflect.Func {
return errorHandler(fmt.Errorf("handler kind %s is not %s", handlerType.Kind(), reflect.Func))
}
takesContext, err := validateArguments(handlerType)
if err != nil {
return errorHandler(err)
}
if err := validateReturns(handlerType); err != nil {
return errorHandler(err)
}
return func(ctx context.Context, payload []byte) (interface{}, error) {
// construct arguments
var args []reflect.Value
if takesContext {
args = append(args, reflect.ValueOf(ctx))
}
if (handlerType.NumIn() == 1 && !takesContext) || handlerType.NumIn() == 2 {
eventType := handlerType.In(handlerType.NumIn() - 1)
event := reflect.New(eventType)
if err := json.Unmarshal(payload, event.Interface()); err != nil {
return nil, err
}
args = append(args, event.Elem())
}
response := handler.Call(args)
// convert return values into (interface{}, error)
var err error
if len(response) > 0 {
if errVal, ok := response[len(response)-1].Interface().(error); ok {
err = errVal
}
}
var val interface{}
if len(response) > 1 {
val = response[0].Interface()
}
return val, err
}
}

View File

@ -0,0 +1,43 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package messages
type PingRequest struct {
}
type PingResponse struct {
}
type InvokeRequest_Timestamp struct {
Seconds int64
Nanos int64
}
type InvokeRequest struct {
Payload []byte
RequestId string
XAmznTraceId string
Deadline InvokeRequest_Timestamp
InvokedFunctionArn string
CognitoIdentityId string
CognitoIdentityPoolId string
ClientContext []byte
}
type InvokeResponse struct {
Payload []byte
Error *InvokeResponse_Error
}
type InvokeResponse_Error struct {
Message string
Type string
StackTrace []*InvokeResponse_Error_StackFrame
ShouldExit bool
}
type InvokeResponse_Error_StackFrame struct {
Path string `json:"path"`
Line int32 `json:"line"`
Label string `json:"label"`
}

99
vendor/github.com/aws/aws-lambda-go/lambda/panic.go generated vendored Normal file
View File

@ -0,0 +1,99 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package lambda
import (
"fmt"
"runtime"
"strings"
"github.com/aws/aws-lambda-go/lambda/messages"
)
type panicInfo struct {
Message string // Value passed to panic call, converted to string
StackTrace []*messages.InvokeResponse_Error_StackFrame // Stack trace of the panic
}
func getPanicInfo(value interface{}) panicInfo {
message := getPanicMessage(value)
stack := getPanicStack()
return panicInfo{Message: message, StackTrace: stack}
}
func getPanicMessage(value interface{}) string {
return fmt.Sprintf("%v", value)
}
var defaultErrorFrameCount = 32
func getPanicStack() []*messages.InvokeResponse_Error_StackFrame {
s := make([]uintptr, defaultErrorFrameCount)
const framesToHide = 3 // this (getPanicStack) -> getPanicInfo -> handler defer func
n := runtime.Callers(framesToHide, s)
if n == 0 {
return make([]*messages.InvokeResponse_Error_StackFrame, 0)
}
s = s[:n]
return convertStack(s)
}
func convertStack(s []uintptr) []*messages.InvokeResponse_Error_StackFrame {
var converted []*messages.InvokeResponse_Error_StackFrame
frames := runtime.CallersFrames(s)
for {
frame, more := frames.Next()
formattedFrame := formatFrame(frame)
converted = append(converted, formattedFrame)
if !more {
break
}
}
return converted
}
func formatFrame(inputFrame runtime.Frame) *messages.InvokeResponse_Error_StackFrame {
path := inputFrame.File
line := int32(inputFrame.Line)
label := inputFrame.Function
// Strip GOPATH from path by counting the number of seperators in label & path
//
// For example given this:
// GOPATH = /home/user
// path = /home/user/src/pkg/sub/file.go
// label = pkg/sub.Type.Method
//
// We want to set:
// path = pkg/sub/file.go
// label = Type.Method
i := len(path)
for n, g := 0, strings.Count(label, "/")+2; n < g; n++ {
i = strings.LastIndex(path[:i], "/")
if i == -1 {
// Something went wrong and path has less seperators than we expected
// Abort and leave i as -1 to counteract the +1 below
break
}
}
path = path[i+1:] // Trim the initial /
// Strip the path from the function name as it's already in the path
label = label[strings.LastIndex(label, "/")+1:]
// Likewise strip the package name
label = label[strings.Index(label, ".")+1:]
return &messages.InvokeResponse_Error_StackFrame{
Path: path,
Line: line,
Label: label,
}
}

View File

@ -0,0 +1,89 @@
// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Helpers for accessing context information from an Invoke request. Context information
// is stored in a https://golang.org/pkg/context/#Context. The functions FromContext and NewContext
// are used to retrieving and inserting an isntance of LambdaContext.
package lambdacontext
import (
"context"
"os"
"strconv"
)
// LogGroupName is the name of the log group that contains the log streams of the current Lambda Function
var LogGroupName string
// LogStreamName name of the log stream that the current Lambda Function's logs will be sent to
var LogStreamName string
// FunctionName the name of the current Lambda Function
var FunctionName string
// MemoryLimitInMB is the configured memory limit for the current instance of the Lambda Function
var MemoryLimitInMB int
// FunctionVersion is the published version of the current instance of the Lambda Function
var FunctionVersion string
func init() {
LogGroupName = os.Getenv("AWS_LAMBDA_LOG_GROUP_NAME")
LogStreamName = os.Getenv("AWS_LAMBDA_LOG_STREAM_NAME")
FunctionName = os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
if limit, err := strconv.Atoi(os.Getenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")); err != nil {
MemoryLimitInMB = 0
} else {
MemoryLimitInMB = limit
}
FunctionVersion = os.Getenv("AWS_LAMBDA_FUNCTION_VERSION")
}
// ClientApplication is metadata about the calling application.
type ClientApplication struct {
InstallationID string `json:"installation_id"`
AppTitle string `json:"app_title"`
AppVersionCode string `json:"app_version_code"`
AppPackageName string `json:"app_package_name"`
}
// ClientContext is information about the client application passed by the calling application.
type ClientContext struct {
Client ClientApplication
Env map[string]string `json:"env"`
Custom map[string]string `json:"custom"`
}
// CognitoIdentity is the cognito identity used by the calling application.
type CognitoIdentity struct {
CognitoIdentityID string
CognitoIdentityPoolID string
}
// LambdaContext is the set of metadata that is passed for every Invoke.
type LambdaContext struct {
AwsRequestID string
InvokedFunctionArn string
Identity CognitoIdentity
ClientContext ClientContext
}
// An unexported type to be used as the key for types in this package.
// This prevents collisions with keys defined in other packages.
type key struct{}
// The key for a LambdaContext in Contexts.
// Users of this package must use lambdacontext.NewContext and lambdacontext.FromContext
// instead of using this key directly.
var contextKey = &key{}
// NewContext returns a new Context that carries value lc.
func NewContext(parent context.Context, lc *LambdaContext) context.Context {
return context.WithValue(parent, contextKey, lc)
}
// FromContext returns the LambdaContext value stored in ctx, if any.
func FromContext(ctx context.Context) (*LambdaContext, bool) {
lc, ok := ctx.Value(contextKey).(*LambdaContext)
return lc, ok
}

23
vendor/github.com/pkg/errors/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
Copyright (c) 2015, Dave Cheney <dave@cheney.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

52
vendor/github.com/pkg/errors/README.md generated vendored Normal file
View File

@ -0,0 +1,52 @@
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)
Package errors provides simple error handling primitives.
`go get github.com/pkg/errors`
The traditional error handling idiom in Go is roughly akin to
```go
if err != nil {
return err
}
```
which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
## Adding context to an error
The errors.Wrap function returns a new error that adds context to the original error. For example
```go
_, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "read failed")
}
```
## Retrieving the cause of an error
Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
```go
type causer interface {
Cause() error
}
```
`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
```go
switch err := errors.Cause(err).(type) {
case *MyError:
// handle specifically
default:
// unknown error
}
```
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
## Contributing
We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
Before proposing a change, please discuss your change by raising an issue.
## License
BSD-2-Clause

32
vendor/github.com/pkg/errors/appveyor.yml generated vendored Normal file
View File

@ -0,0 +1,32 @@
version: build-{build}.{branch}
clone_folder: C:\gopath\src\github.com\pkg\errors
shallow_clone: true # for startup speed
environment:
GOPATH: C:\gopath
platform:
- x64
# http://www.appveyor.com/docs/installed-software
install:
# some helpful output for debugging builds
- go version
- go env
# pre-installed MinGW at C:\MinGW is 32bit only
# but MSYS2 at C:\msys64 has mingw64
- set PATH=C:\msys64\mingw64\bin;%PATH%
- gcc --version
- g++ --version
build_script:
- go install -v ./...
test_script:
- set PATH=C:\gopath\bin;%PATH%
- go test -v ./...
#artifacts:
# - path: '%GOPATH%\bin\*.exe'
deploy: off

269
vendor/github.com/pkg/errors/errors.go generated vendored Normal file
View File

@ -0,0 +1,269 @@
// Package errors provides simple error handling primitives.
//
// The traditional error handling idiom in Go is roughly akin to
//
// if err != nil {
// return err
// }
//
// which applied recursively up the call stack results in error reports
// without context or debugging information. The errors package allows
// programmers to add context to the failure path in their code in a way
// that does not destroy the original value of the error.
//
// Adding context to an error
//
// The errors.Wrap function returns a new error that adds context to the
// original error by recording a stack trace at the point Wrap is called,
// and the supplied message. For example
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return errors.Wrap(err, "read failed")
// }
//
// If additional control is required the errors.WithStack and errors.WithMessage
// functions destructure errors.Wrap into its component operations of annotating
// an error with a stack trace and an a message, respectively.
//
// Retrieving the cause of an error
//
// Using errors.Wrap constructs a stack of errors, adding context to the
// preceding error. Depending on the nature of the error it may be necessary
// to reverse the operation of errors.Wrap to retrieve the original error
// for inspection. Any error value which implements this interface
//
// type causer interface {
// Cause() error
// }
//
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
// the topmost error which does not implement causer, which is assumed to be
// the original cause. For example:
//
// switch err := errors.Cause(err).(type) {
// case *MyError:
// // handle specifically
// default:
// // unknown error
// }
//
// causer interface is not exported by this package, but is considered a part
// of stable public API.
//
// Formatted printing of errors
//
// All error values returned from this package implement fmt.Formatter and can
// be formatted by the fmt package. The following verbs are supported
//
// %s print the error. If the error has a Cause it will be
// printed recursively
// %v see %s
// %+v extended format. Each Frame of the error's StackTrace will
// be printed in detail.
//
// Retrieving the stack trace of an error or wrapper
//
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
// invoked. This information can be retrieved with the following interface.
//
// type stackTracer interface {
// StackTrace() errors.StackTrace
// }
//
// Where errors.StackTrace is defined as
//
// type StackTrace []Frame
//
// The Frame type represents a call site in the stack trace. Frame supports
// the fmt.Formatter interface that can be used for printing information about
// the stack trace of this error. For example:
//
// if err, ok := err.(stackTracer); ok {
// for _, f := range err.StackTrace() {
// fmt.Printf("%+s:%d", f)
// }
// }
//
// stackTracer interface is not exported by this package, but is considered a part
// of stable public API.
//
// See the documentation for Frame.Format for more details.
package errors
import (
"fmt"
"io"
)
// New returns an error with the supplied message.
// New also records the stack trace at the point it was called.
func New(message string) error {
return &fundamental{
msg: message,
stack: callers(),
}
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// Errorf also records the stack trace at the point it was called.
func Errorf(format string, args ...interface{}) error {
return &fundamental{
msg: fmt.Sprintf(format, args...),
stack: callers(),
}
}
// fundamental is an error that has a message and a stack, but no caller.
type fundamental struct {
msg string
*stack
}
func (f *fundamental) Error() string { return f.msg }
func (f *fundamental) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, f.msg)
f.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, f.msg)
case 'q':
fmt.Fprintf(s, "%q", f.msg)
}
}
// WithStack annotates err with a stack trace at the point WithStack was called.
// If err is nil, WithStack returns nil.
func WithStack(err error) error {
if err == nil {
return nil
}
return &withStack{
err,
callers(),
}
}
type withStack struct {
error
*stack
}
func (w *withStack) Cause() error { return w.error }
func (w *withStack) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v", w.Cause())
w.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, w.Error())
case 'q':
fmt.Fprintf(s, "%q", w.Error())
}
}
// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if err == nil {
return nil
}
err = &withMessage{
cause: err,
msg: message,
}
return &withStack{
err,
callers(),
}
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is call, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
err = &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
return &withStack{
err,
callers(),
}
}
// WithMessage annotates err with a new message.
// If err is nil, WithMessage returns nil.
func WithMessage(err error, message string) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: message,
}
}
type withMessage struct {
cause error
msg string
}
func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
func (w *withMessage) Cause() error { return w.cause }
func (w *withMessage) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v\n", w.Cause())
io.WriteString(s, w.msg)
return
}
fallthrough
case 's', 'q':
io.WriteString(s, w.Error())
}
}
// Cause returns the underlying cause of the error, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
//
// If the error does not implement Cause, the original error will
// be returned. If the error is nil, nil will be returned without further
// investigation.
func Cause(err error) error {
type causer interface {
Cause() error
}
for err != nil {
cause, ok := err.(causer)
if !ok {
break
}
err = cause.Cause()
}
return err
}

187
vendor/github.com/pkg/errors/stack.go generated vendored Normal file
View File

@ -0,0 +1,187 @@
package errors
import (
"fmt"
"io"
"path"
"runtime"
"strings"
)
// Frame represents a program counter inside a stack frame.
type Frame uintptr
// pc returns the program counter for this frame;
// multiple frames may have the same PC value.
func (f Frame) pc() uintptr { return uintptr(f) - 1 }
// file returns the full path to the file that contains the
// function for this Frame's pc.
func (f Frame) file() string {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return "unknown"
}
file, _ := fn.FileLine(f.pc())
return file
}
// line returns the line number of source code of the
// function for this Frame's pc.
func (f Frame) line() int {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return 0
}
_, line := fn.FileLine(f.pc())
return line
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %s source file
// %d source line
// %n function name
// %v equivalent to %s:%d
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s function name and path of source file relative to the compile time
// GOPATH separated by \n\t (<funcname>\n\t<path>)
// %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
switch verb {
case 's':
switch {
case s.Flag('+'):
pc := f.pc()
fn := runtime.FuncForPC(pc)
if fn == nil {
io.WriteString(s, "unknown")
} else {
file, _ := fn.FileLine(pc)
fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
}
default:
io.WriteString(s, path.Base(f.file()))
}
case 'd':
fmt.Fprintf(s, "%d", f.line())
case 'n':
name := runtime.FuncForPC(f.pc()).Name()
io.WriteString(s, funcname(name))
case 'v':
f.Format(s, 's')
io.WriteString(s, ":")
f.Format(s, 'd')
}
}
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace []Frame
// Format formats the stack of Frames according to the fmt.Formatter interface.
//
// %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for _, f := range st {
fmt.Fprintf(s, "\n%+v", f)
}
case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st))
default:
fmt.Fprintf(s, "%v", []Frame(st))
}
case 's':
fmt.Fprintf(s, "%s", []Frame(st))
}
}
// stack represents a stack of program counters.
type stack []uintptr
func (s *stack) Format(st fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case st.Flag('+'):
for _, pc := range *s {
f := Frame(pc)
fmt.Fprintf(st, "\n%+v", f)
}
}
}
}
func (s *stack) StackTrace() StackTrace {
f := make([]Frame, len(*s))
for i := 0; i < len(f); i++ {
f[i] = Frame((*s)[i])
}
return f
}
func callers() *stack {
const depth = 32
var pcs [depth]uintptr
n := runtime.Callers(3, pcs[:])
var st stack = pcs[0:n]
return &st
}
// funcname removes the path prefix component of a function's name reported by func.Name().
func funcname(name string) string {
i := strings.LastIndex(name, "/")
name = name[i+1:]
i = strings.Index(name, ".")
return name[i+1:]
}
func trimGOPATH(name, file string) string {
// Here we want to get the source file path relative to the compile time
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
// GOPATH at runtime, but we can infer the number of path segments in the
// GOPATH. We note that fn.Name() returns the function name qualified by
// the import path, which does not include the GOPATH. Thus we can trim
// segments from the beginning of the file path until the number of path
// separators remaining is one more than the number of path separators in
// the function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path separator
// than our desired output. We count separators from the end of the file
// path until it finds two more than in the function name and then move
// one character forward to preserve the initial path segment without a
// leading separator.
const sep = "/"
goal := strings.Count(name, sep) + 2
i := len(file)
for n := 0; n < goal; n++ {
i = strings.LastIndex(file[:i], sep)
if i == -1 {
// not enough separators found, set i so that the slice expression
// below leaves file unmodified
i = -len(sep)
break
}
}
// get back to 0 or trim the leading separator
file = file[i+len(sep):]
return file
}

36
vendor/vendor.json vendored
View File

@ -2,6 +2,12 @@
"comment": "",
"ignore": "test",
"package": [
{
"checksumSHA1": "DBuGaMCW5qcB56KbHNMdfpF797Y=",
"path": "github.com/apex/gateway",
"revision": "e9c6ccec8851cbed57b52e96858f3dc0572921dc",
"revisionTime": "2018-01-21T23:10:47Z"
},
{
"checksumSHA1": "1Jql7x7zDOmbDxGr4gsa8rFEC5g=",
"path": "github.com/appleboy/go-fcm",
@ -46,6 +52,30 @@
"revision": "de95a2ead13a0ec4cff5e37d21decd48b54a078f",
"revisionTime": "2017-01-29T11:39:06Z"
},
{
"checksumSHA1": "PJFBQGoSr7QkbNtr3XqFdkXuHTs=",
"path": "github.com/aws/aws-lambda-go/events",
"revision": "6736675908bded5127345825f653c88937222091",
"revisionTime": "2018-01-21T10:36:08Z"
},
{
"checksumSHA1": "otXwJhbwKYBj3v0viFbP9Mogqnw=",
"path": "github.com/aws/aws-lambda-go/lambda",
"revision": "6736675908bded5127345825f653c88937222091",
"revisionTime": "2018-01-21T10:36:08Z"
},
{
"checksumSHA1": "FEIW+8VDruQZu0Cv9j7r+Km8r8o=",
"path": "github.com/aws/aws-lambda-go/lambda/messages",
"revision": "6736675908bded5127345825f653c88937222091",
"revisionTime": "2018-01-21T10:36:08Z"
},
{
"checksumSHA1": "+3R+gHl3aC1ZBNfg0dEVBv1roaQ=",
"path": "github.com/aws/aws-lambda-go/lambdacontext",
"revision": "6736675908bded5127345825f653c88937222091",
"revisionTime": "2018-01-21T10:36:08Z"
},
{
"checksumSHA1": "spyv5/YFBjYyZLZa1U2LBfDR8PM=",
"path": "github.com/beorn7/perks/quantile",
@ -298,6 +328,12 @@
"revision": "8c31c2ec65b208cc2ad1608bf25a3ff91adf1944",
"revisionTime": "2017-10-22T02:23:38Z"
},
{
"checksumSHA1": "xCv4GBFyw07vZkVtKF/XrUnkHRk=",
"path": "github.com/pkg/errors",
"revision": "e881fd58d78e04cf6d0de1217f8707c8cc2249bc",
"revisionTime": "2017-12-16T07:03:16Z"
},
{
"checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=",
"path": "github.com/pmezard/go-difflib/difflib",