mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Update Go AWS SDK to the latest version
This commit is contained in:
committed by
Andrey Smirnov
parent
d08be990ef
commit
94a72b23ff
+144
-68
@@ -5,17 +5,18 @@ package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// SDKImportRoot is the root import path of the SDK.
|
||||
const SDKImportRoot = "github.com/aws/aws-sdk-go"
|
||||
|
||||
// An API defines a service API's definition. and logic to serialize the definition.
|
||||
type API struct {
|
||||
Metadata Metadata
|
||||
@@ -24,6 +25,7 @@ type API struct {
|
||||
Waiters []Waiter
|
||||
Documentation string
|
||||
Examples Examples
|
||||
SmokeTests SmokeTestSuite
|
||||
|
||||
// Set to true to avoid removing unused shapes
|
||||
NoRemoveUnusedShapes bool
|
||||
@@ -46,7 +48,7 @@ type API struct {
|
||||
// Set to true to not generate struct field accessors
|
||||
NoGenStructFieldAccessors bool
|
||||
|
||||
SvcClientImportPath string
|
||||
BaseImportPath string
|
||||
|
||||
initialized bool
|
||||
imports map[string]bool
|
||||
@@ -54,6 +56,10 @@ type API struct {
|
||||
path string
|
||||
|
||||
BaseCrosslinkURL string
|
||||
|
||||
HasEventStream bool `json:"-"`
|
||||
|
||||
EndpointDiscoveryOp *Operation
|
||||
}
|
||||
|
||||
// A Metadata is the metadata about an API's definition.
|
||||
@@ -67,21 +73,18 @@ type Metadata struct {
|
||||
JSONVersion string
|
||||
TargetPrefix string
|
||||
Protocol string
|
||||
ProtocolSettings ProtocolSettings
|
||||
UID string
|
||||
EndpointsID string
|
||||
ServiceID string
|
||||
|
||||
NoResolveEndpoint bool
|
||||
}
|
||||
|
||||
var serviceAliases map[string]string
|
||||
|
||||
func Bootstrap() error {
|
||||
b, err := ioutil.ReadFile(filepath.Join("..", "models", "customizations", "service-aliases.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return json.Unmarshal(b, &serviceAliases)
|
||||
// ProtocolSettings define how the SDK should handle requests in the context
|
||||
// of of a protocol.
|
||||
type ProtocolSettings struct {
|
||||
HTTP2 string `json:"h2,omitempty"`
|
||||
}
|
||||
|
||||
// PackageName name of the API package
|
||||
@@ -89,6 +92,11 @@ func (a *API) PackageName() string {
|
||||
return strings.ToLower(a.StructName())
|
||||
}
|
||||
|
||||
// ImportPath returns the client's full import path
|
||||
func (a *API) ImportPath() string {
|
||||
return path.Join(a.BaseImportPath, a.PackageName())
|
||||
}
|
||||
|
||||
// InterfacePackageName returns the package name for the interface.
|
||||
func (a *API) InterfacePackageName() string {
|
||||
return a.PackageName() + "iface"
|
||||
@@ -135,11 +143,6 @@ func (a *API) StructName() string {
|
||||
// Strip out spaces.
|
||||
name = strings.Replace(name, " ", "", -1)
|
||||
|
||||
// Swap out for alias name if one is defined.
|
||||
if alias, ok := serviceAliases[strings.ToLower(name)]; ok {
|
||||
name = alias
|
||||
}
|
||||
|
||||
a.name = name
|
||||
return a.name
|
||||
}
|
||||
@@ -217,8 +220,8 @@ func (a *API) ShapeNames() []string {
|
||||
func (a *API) ShapeList() []*Shape {
|
||||
list := make([]*Shape, 0, len(a.Shapes))
|
||||
for _, n := range a.ShapeNames() {
|
||||
// Ignore error shapes in list
|
||||
if s := a.Shapes[n]; !s.IsError {
|
||||
// Ignore non-eventstream exception shapes in list.
|
||||
if s := a.Shapes[n]; !(s.Exception && len(s.EventFor) == 0) {
|
||||
list = append(list, s)
|
||||
}
|
||||
}
|
||||
@@ -230,7 +233,7 @@ func (a *API) ShapeListErrors() []*Shape {
|
||||
list := []*Shape{}
|
||||
for _, n := range a.ShapeNames() {
|
||||
// Ignore error shapes in list
|
||||
if s := a.Shapes[n]; s.IsError {
|
||||
if s := a.Shapes[n]; s.Exception {
|
||||
list = append(list, s)
|
||||
}
|
||||
}
|
||||
@@ -239,9 +242,7 @@ func (a *API) ShapeListErrors() []*Shape {
|
||||
|
||||
// resetImports resets the import map to default values.
|
||||
func (a *API) resetImports() {
|
||||
a.imports = map[string]bool{
|
||||
"github.com/aws/aws-sdk-go/aws": true,
|
||||
}
|
||||
a.imports = map[string]bool{}
|
||||
}
|
||||
|
||||
// importsGoCode returns the generated Go import code.
|
||||
@@ -293,22 +294,28 @@ var tplAPI = template.Must(template.New("api").Parse(`
|
||||
{{ end }}
|
||||
`))
|
||||
|
||||
// AddImport adds the import path to the generated file's import.
|
||||
func (a *API) AddImport(v string) error {
|
||||
a.imports[v] = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddSDKImport adds a SDK package import to the generated file's import.
|
||||
func (a *API) AddSDKImport(v ...string) error {
|
||||
e := make([]string, 0, 5)
|
||||
e = append(e, SDKImportRoot)
|
||||
e = append(e, v...)
|
||||
|
||||
a.imports[path.Join(e...)] = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// APIGoCode renders the API in Go code. Returning it as a string
|
||||
func (a *API) APIGoCode() string {
|
||||
a.resetImports()
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/awsutil"] = true
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/request"] = true
|
||||
if a.OperationHasOutputPlaceholder() {
|
||||
a.imports["github.com/aws/aws-sdk-go/private/protocol/"+a.ProtocolPackage()] = true
|
||||
a.imports["github.com/aws/aws-sdk-go/private/protocol"] = true
|
||||
}
|
||||
|
||||
for _, op := range a.Operations {
|
||||
if op.AuthType == "none" {
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/credentials"] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
a.AddSDKImport("aws")
|
||||
a.AddSDKImport("aws/awsutil")
|
||||
a.AddSDKImport("aws/request")
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := tplAPI.Execute(&buf, a)
|
||||
@@ -407,7 +414,7 @@ var tplServiceDoc = template.Must(template.New("service docs").Funcs(template.Fu
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
@@ -416,30 +423,62 @@ var tplServiceDoc = template.Must(template.New("service docs").Funcs(template.Fu
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/{{ .PackageName }}/#New
|
||||
`))
|
||||
|
||||
var serviceIDRegex = regexp.MustCompile("[^a-zA-Z0-9 ]+")
|
||||
var prefixDigitRegex = regexp.MustCompile("^[0-9]+")
|
||||
|
||||
// ServiceID will return a unique identifier specific to a service.
|
||||
func ServiceID(a *API) string {
|
||||
if len(a.Metadata.ServiceID) > 0 {
|
||||
return a.Metadata.ServiceID
|
||||
}
|
||||
|
||||
name := a.Metadata.ServiceAbbreviation
|
||||
if len(name) == 0 {
|
||||
name = a.Metadata.ServiceFullName
|
||||
}
|
||||
|
||||
name = strings.Replace(name, "Amazon", "", -1)
|
||||
name = strings.Replace(name, "AWS", "", -1)
|
||||
name = serviceIDRegex.ReplaceAllString(name, "")
|
||||
name = prefixDigitRegex.ReplaceAllString(name, "")
|
||||
name = strings.TrimSpace(name)
|
||||
return name
|
||||
}
|
||||
|
||||
// A tplService defines the template for the service generated code.
|
||||
var tplService = template.Must(template.New("service").Funcs(template.FuncMap{
|
||||
"ServiceNameConstValue": ServiceName,
|
||||
"ServiceNameValue": func(a *API) string {
|
||||
if a.NoConstServiceNames {
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointPrefix)
|
||||
if !a.NoConstServiceNames {
|
||||
return "ServiceName"
|
||||
}
|
||||
return "ServiceName"
|
||||
return fmt.Sprintf("%q", ServiceName(a))
|
||||
},
|
||||
"EndpointsIDConstValue": func(a *API) string {
|
||||
if a.NoConstServiceNames {
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointPrefix)
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointsID)
|
||||
}
|
||||
if a.Metadata.EndpointPrefix == a.Metadata.EndpointsID {
|
||||
if a.Metadata.EndpointsID == ServiceName(a) {
|
||||
return "ServiceName"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointsID)
|
||||
},
|
||||
"EndpointsIDValue": func(a *API) string {
|
||||
if a.NoConstServiceNames {
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointPrefix)
|
||||
return fmt.Sprintf("%q", a.Metadata.EndpointsID)
|
||||
}
|
||||
|
||||
return "EndpointsID"
|
||||
},
|
||||
"ServiceIDVar": func(a *API) string {
|
||||
if a.NoConstServiceNames {
|
||||
return fmt.Sprintf("%q", ServiceID(a))
|
||||
}
|
||||
|
||||
return "ServiceID"
|
||||
},
|
||||
"ServiceID": ServiceID,
|
||||
}).Parse(`
|
||||
// {{ .StructName }} provides the API operation methods for making requests to
|
||||
// {{ .Metadata.ServiceFullName }}. See this package's package overview docs
|
||||
@@ -449,6 +488,9 @@ var tplService = template.Must(template.New("service").Funcs(template.FuncMap{
|
||||
// modify mutate any of the struct's properties though.
|
||||
type {{ .StructName }} struct {
|
||||
*client.Client
|
||||
{{- if .EndpointDiscoveryOp }}
|
||||
endpointCache *crr.EndpointCache
|
||||
{{ end -}}
|
||||
}
|
||||
|
||||
{{ if .UseInitMethods }}// Used for custom client initialization logic
|
||||
@@ -462,8 +504,9 @@ var initRequest func(*request.Request)
|
||||
{{ if not .NoConstServiceNames -}}
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "{{ .Metadata.EndpointPrefix }}" // Service endpoint prefix API calls made to.
|
||||
EndpointsID = {{ EndpointsIDConstValue . }} // Service ID for Regions and Endpoints metadata.
|
||||
ServiceName = "{{ ServiceNameConstValue . }}" // Name of service.
|
||||
EndpointsID = {{ EndpointsIDConstValue . }} // ID to lookup a service endpoint with.
|
||||
ServiceID = "{{ ServiceID . }}" // ServiceID is a unique identifer of a specific service.
|
||||
)
|
||||
{{- end }}
|
||||
|
||||
@@ -504,14 +547,15 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: {{ ServiceNameValue . }},
|
||||
ServiceID : {{ ServiceIDVar . }},
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "{{ .Metadata.APIVersion }}",
|
||||
{{ if .Metadata.JSONVersion -}}
|
||||
{{ if and (.Metadata.JSONVersion) (eq .Metadata.Protocol "json") -}}
|
||||
JSONVersion: "{{ .Metadata.JSONVersion }}",
|
||||
{{- end }}
|
||||
{{ if .Metadata.TargetPrefix -}}
|
||||
{{ if and (.Metadata.TargetPrefix) (eq .Metadata.Protocol "json") -}}
|
||||
TargetPrefix: "{{ .Metadata.TargetPrefix }}",
|
||||
{{- end }}
|
||||
},
|
||||
@@ -519,8 +563,22 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
||||
),
|
||||
}
|
||||
|
||||
{{- if .EndpointDiscoveryOp }}
|
||||
svc.endpointCache = crr.NewEndpointCache(10)
|
||||
{{- end }}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed({{if eq .Metadata.SignatureVersion "v2"}}v2{{else}}v4{{end}}.SignRequestHandler)
|
||||
svc.Handlers.Sign.PushBackNamed(
|
||||
{{- if eq .Metadata.SignatureVersion "v2" -}}
|
||||
v2.SignRequestHandler
|
||||
{{- else if or (eq .Metadata.SignatureVersion "s3") (eq .Metadata.SignatureVersion "s3v4") -}}
|
||||
v4.BuildNamedHandler(v4.SignRequestHandler.Name, func(s *v4.Signer) {
|
||||
s.DisableURIPathEscaping = true
|
||||
})
|
||||
{{- else -}}
|
||||
v4.SignRequestHandler
|
||||
{{- end -}}
|
||||
)
|
||||
{{- if eq .Metadata.SignatureVersion "v2" }}
|
||||
svc.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||
{{- end }}
|
||||
@@ -528,6 +586,9 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
||||
svc.Handlers.Unmarshal.PushBackNamed({{ .ProtocolPackage }}.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed({{ .ProtocolPackage }}.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed({{ .ProtocolPackage }}.UnmarshalErrorHandler)
|
||||
{{ if .HasEventStream }}
|
||||
svc.Handlers.UnmarshalStream.PushBackNamed({{ .ProtocolPackage }}.UnmarshalHandler)
|
||||
{{ end }}
|
||||
|
||||
{{ if .UseInitMethods }}// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
@@ -570,16 +631,20 @@ func (a *API) ServicePackageDoc() string {
|
||||
// ServiceGoCode renders service go code. Returning it as a string.
|
||||
func (a *API) ServiceGoCode() string {
|
||||
a.resetImports()
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/client"] = true
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/client/metadata"] = true
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/request"] = true
|
||||
a.AddSDKImport("aws")
|
||||
a.AddSDKImport("aws/client")
|
||||
a.AddSDKImport("aws/client/metadata")
|
||||
a.AddSDKImport("aws/request")
|
||||
if a.Metadata.SignatureVersion == "v2" {
|
||||
a.imports["github.com/aws/aws-sdk-go/private/signer/v2"] = true
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/corehandlers"] = true
|
||||
a.AddSDKImport("private/signer/v2")
|
||||
a.AddSDKImport("aws/corehandlers")
|
||||
} else {
|
||||
a.imports["github.com/aws/aws-sdk-go/aws/signer/v4"] = true
|
||||
a.AddSDKImport("aws/signer/v4")
|
||||
}
|
||||
a.AddSDKImport("private/protocol", a.ProtocolPackage())
|
||||
if a.EndpointDiscoveryOp != nil {
|
||||
a.AddSDKImport("aws/crr")
|
||||
}
|
||||
a.imports["github.com/aws/aws-sdk-go/private/protocol/"+a.ProtocolPackage()] = true
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := tplService.Execute(&buf, a)
|
||||
@@ -607,9 +672,9 @@ func (a *API) ExampleGoCode() string {
|
||||
"bytes",
|
||||
"fmt",
|
||||
"time",
|
||||
"github.com/aws/aws-sdk-go/aws",
|
||||
"github.com/aws/aws-sdk-go/aws/session",
|
||||
path.Join(a.SvcClientImportPath, a.PackageName()),
|
||||
SDKImportRoot+"/aws",
|
||||
SDKImportRoot+"/aws/session",
|
||||
a.ImportPath(),
|
||||
)
|
||||
for k := range imports {
|
||||
code += fmt.Sprintf("%q\n", k)
|
||||
@@ -665,7 +730,7 @@ var tplInterface = template.Must(template.New("interface").Parse(`
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type {{ .StructName }}API interface {
|
||||
{{ range $_, $o := .OperationList }}
|
||||
@@ -684,11 +749,9 @@ var _ {{ .StructName }}API = (*{{ .PackageName }}.{{ .StructName }})(nil)
|
||||
// package than the service API's package.
|
||||
func (a *API) InterfaceGoCode() string {
|
||||
a.resetImports()
|
||||
a.imports = map[string]bool{
|
||||
"github.com/aws/aws-sdk-go/aws": true,
|
||||
"github.com/aws/aws-sdk-go/aws/request": true,
|
||||
path.Join(a.SvcClientImportPath, a.PackageName()): true,
|
||||
}
|
||||
a.AddSDKImport("aws")
|
||||
a.AddSDKImport("aws/request")
|
||||
a.AddImport(a.ImportPath())
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := tplInterface.Execute(&buf, a)
|
||||
@@ -726,7 +789,6 @@ func resolveShapeValidations(s *Shape, ancestry ...*Shape) {
|
||||
children := []string{}
|
||||
for _, name := range s.MemberNames() {
|
||||
ref := s.MemberRefs[name]
|
||||
|
||||
if s.IsRequired(name) && !s.Validations.Has(ref, ShapeValidationRequired) {
|
||||
s.Validations = append(s.Validations, ShapeValidation{
|
||||
Name: name, Ref: ref, Type: ShapeValidationRequired,
|
||||
@@ -739,6 +801,12 @@ func resolveShapeValidations(s *Shape, ancestry ...*Shape) {
|
||||
})
|
||||
}
|
||||
|
||||
if !ref.CanBeEmpty() && !s.Validations.Has(ref, ShapeValidationMinVal) {
|
||||
s.Validations = append(s.Validations, ShapeValidation{
|
||||
Name: name, Ref: ref, Type: ShapeValidationMinVal,
|
||||
})
|
||||
}
|
||||
|
||||
switch ref.Shape.Type {
|
||||
case "map", "list", "structure":
|
||||
children = append(children, name)
|
||||
@@ -806,7 +874,7 @@ func (a *API) APIErrorsGoCode() string {
|
||||
// removeOperation removes an operation, its input/output shapes, as well as
|
||||
// any references/shapes that are unique to this operation.
|
||||
func (a *API) removeOperation(name string) {
|
||||
fmt.Println("removing operation,", name)
|
||||
debugLogger.Logln("removing operation,", name)
|
||||
op := a.Operations[name]
|
||||
|
||||
delete(a.Operations, name)
|
||||
@@ -820,7 +888,7 @@ func (a *API) removeOperation(name string) {
|
||||
// shapes. Will also remove member reference targeted shapes if those shapes do
|
||||
// not have any additional references.
|
||||
func (a *API) removeShape(s *Shape) {
|
||||
fmt.Println("removing shape,", s.ShapeName)
|
||||
debugLogger.Logln("removing shape,", s.ShapeName)
|
||||
|
||||
delete(a.Shapes, s.ShapeName)
|
||||
|
||||
@@ -851,3 +919,11 @@ func (a *API) removeShapeRef(ref *ShapeRef) {
|
||||
a.removeShape(ref.Shape)
|
||||
}
|
||||
}
|
||||
|
||||
func getDeprecatedMessage(msg string, name string) string {
|
||||
if len(msg) == 0 {
|
||||
return name + " has been deprecated"
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
+5
-3
@@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
func TestAPI_StructName(t *testing.T) {
|
||||
origAliases := serviceAliases
|
||||
defer func() { serviceAliases = origAliases }()
|
||||
origAliases := serviceAliaseNames
|
||||
defer func() { serviceAliaseNames = origAliases }()
|
||||
|
||||
cases := map[string]struct {
|
||||
Aliases map[string]string
|
||||
@@ -57,12 +57,14 @@ func TestAPI_StructName(t *testing.T) {
|
||||
|
||||
for k, c := range cases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
serviceAliases = c.Aliases
|
||||
serviceAliaseNames = c.Aliases
|
||||
|
||||
a := API{
|
||||
Metadata: c.Metadata,
|
||||
}
|
||||
|
||||
a.Setup()
|
||||
|
||||
if e, o := c.StructName, a.StructName(); e != o {
|
||||
t.Errorf("expect %v structName, got %v", e, o)
|
||||
}
|
||||
|
||||
Generated
Vendored
+131
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"version":"2.0",
|
||||
"metadata":{
|
||||
"apiVersion":"2018-08-31",
|
||||
"endpointPrefix":"awsendpointdiscoverytestservice",
|
||||
"jsonVersion":"1.1",
|
||||
"protocol":"json",
|
||||
"serviceAbbreviation":"AwsEndpointDiscoveryTest",
|
||||
"serviceFullName":"AwsEndpointDiscoveryTest",
|
||||
"signatureVersion":"v4",
|
||||
"signingName":"awsendpointdiscoverytestservice",
|
||||
"targetPrefix":"AwsEndpointDiscoveryTestService"
|
||||
},
|
||||
"operations":{
|
||||
"DescribeEndpoints":{
|
||||
"name":"DescribeEndpoints",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"DescribeEndpointsRequest"},
|
||||
"output":{"shape":"DescribeEndpointsResponse"},
|
||||
"endpointoperation":true
|
||||
},
|
||||
"TestDiscoveryIdentifiersRequired":{
|
||||
"name":"TestDiscoveryIdentifiersRequired",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"TestDiscoveryIdentifiersRequiredRequest"},
|
||||
"output":{"shape":"TestDiscoveryIdentifiersRequiredResponse"},
|
||||
"endpointdiscovery":{"required":true}
|
||||
},
|
||||
"TestDiscoveryOptional":{
|
||||
"name":"TestDiscoveryOptional",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"TestDiscoveryOptionalRequest"},
|
||||
"output":{"shape":"TestDiscoveryOptionalResponse"},
|
||||
"endpointdiscovery":{
|
||||
}
|
||||
},
|
||||
"TestDiscoveryRequired":{
|
||||
"name":"TestDiscoveryRequired",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"TestDiscoveryRequiredRequest"},
|
||||
"output":{"shape":"TestDiscoveryRequiredResponse"},
|
||||
"endpointdiscovery":{
|
||||
}
|
||||
}
|
||||
},
|
||||
"shapes":{
|
||||
"Boolean":{"type":"boolean"},
|
||||
"DescribeEndpointsRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Operation": {"shape":"String"}
|
||||
}
|
||||
},
|
||||
"DescribeEndpointsResponse":{
|
||||
"type":"structure",
|
||||
"required":["Endpoints"],
|
||||
"members":{
|
||||
"Endpoints":{"shape":"Endpoints"}
|
||||
}
|
||||
},
|
||||
"Endpoint":{
|
||||
"type":"structure",
|
||||
"required":[
|
||||
"Address",
|
||||
"CachePeriodInMinutes"
|
||||
],
|
||||
"members":{
|
||||
"Address":{"shape":"String"},
|
||||
"CachePeriodInMinutes":{"shape":"Long"}
|
||||
}
|
||||
},
|
||||
"Endpoints":{
|
||||
"type":"list",
|
||||
"member":{"shape":"Endpoint"}
|
||||
},
|
||||
"Long":{"type":"long"},
|
||||
"String":{"type":"string"},
|
||||
"TestDiscoveryIdentifiersRequiredRequest":{
|
||||
"type":"structure",
|
||||
"required":["Sdk"],
|
||||
"members":{
|
||||
"Sdk":{
|
||||
"shape":"String",
|
||||
"endpointdiscoveryid":true
|
||||
}
|
||||
}
|
||||
},
|
||||
"TestDiscoveryIdentifiersRequiredResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"RequestSuccessful":{"shape":"Boolean"}
|
||||
}
|
||||
},
|
||||
"TestDiscoveryOptionalRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Sdk":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"TestDiscoveryOptionalResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"RequestSuccessful":{"shape":"Boolean"}
|
||||
}
|
||||
},
|
||||
"TestDiscoveryRequiredRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Sdk":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"TestDiscoveryRequiredResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"RequestSuccessful":{"shape":"Boolean"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"service": null,
|
||||
"operations": {
|
||||
},
|
||||
"shapes":{}
|
||||
}
|
||||
Generated
Vendored
+228
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"version":"2.0",
|
||||
"metadata":{
|
||||
"apiVersion":"0000-00-00",
|
||||
"endpointPrefix":"rpcservice",
|
||||
"jsonVersion":"1.1",
|
||||
"protocol":"json",
|
||||
"serviceAbbreviation":"RPCService",
|
||||
"serviceFullName":"RPC Service",
|
||||
"serviceId":"RPCService",
|
||||
"signatureVersion":"v4",
|
||||
"targetPrefix":"RPCService_00000000",
|
||||
"uid":"RPCService-0000-00-00"
|
||||
},
|
||||
"operations":{
|
||||
"GetEventStream":{
|
||||
"name":"GetEventStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"GetEventStreamRequest"},
|
||||
"output":{"shape":"GetEventStreamResponse"}
|
||||
},
|
||||
"EmptyStream":{
|
||||
"name":"EmptyStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"EmptyStreamRequest"},
|
||||
"output":{"shape":"EmptyStreamResponse"}
|
||||
},
|
||||
"OtherOperation":{
|
||||
"name":"OtherOperation",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"errors":[
|
||||
{"shape":"ExceptionEvent2"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"shapes":{
|
||||
"Bool":{"type":"boolean"},
|
||||
"Byte":{"type":"byte"},
|
||||
"Short":{"type":"short"},
|
||||
"Integer":{"type":"integer"},
|
||||
"Long":{"type":"long"},
|
||||
"Blob":{"type":"blob"},
|
||||
"String":{"type":"string"},
|
||||
"Time":{"type":"timestamp"},
|
||||
"GetEventStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"InputVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"GetEventStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StrVal":{"shape":"String"},
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"EventStream":{"shape":"EventStream"}
|
||||
}
|
||||
},
|
||||
"EventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Headers":{"shape":"HeaderOnlyEvent"},
|
||||
"ImplicitPayload":{"shape":"ImplicitPayloadEvent"},
|
||||
"ExplicitPayload":{"shape":"ExplicitPayloadEvent"},
|
||||
"PayloadOnly":{"shape":"PayloadOnlyEvent"},
|
||||
"PayloadOnlyBlob":{"shape":"PayloadOnlyBlobEvent"},
|
||||
"PayloadOnlyString":{"shape":"PayloadOnlyStringEvent"},
|
||||
"Empty":{"shape":"EmptyEvent"},
|
||||
"Exception":{"shape":"ExceptionEvent"},
|
||||
"Exception2":{"shape":"ExceptionEvent2"}
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"EmptyStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{}
|
||||
},
|
||||
"EmptyStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"EventStream":{"shape":"EmptyEventStream"}
|
||||
}
|
||||
},
|
||||
"EmptyEventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"HeaderOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BoolVal":{
|
||||
"shape":"Bool",
|
||||
"eventheader":true
|
||||
},
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short",
|
||||
"eventheader":true
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer",
|
||||
"eventheader":true
|
||||
},
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"BlobVal":{
|
||||
"shape":"Blob",
|
||||
"eventheader":true
|
||||
},
|
||||
"TimeVal":{
|
||||
"shape":"Time",
|
||||
"eventheader":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ImplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short"
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer"
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ExplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyBlobEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BlobPayload":{
|
||||
"shape":"Blob",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyStringEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StringPayload":{
|
||||
"shape":"String",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"EmptyEvent": {
|
||||
"type":"structure",
|
||||
"members":{},
|
||||
"event": true
|
||||
},
|
||||
"NestedShape": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"StrVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"ExceptionEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"message":{"shape":"String"}
|
||||
},
|
||||
"exception":true
|
||||
},
|
||||
"ExceptionEvent2":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"exception":true
|
||||
}
|
||||
}
|
||||
}
|
||||
vendor/github.com/aws/aws-sdk-go/private/model/api/codegentest/models/jsonrpc/0000-00-00/docs-2.json
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"service": null,
|
||||
"operations": {
|
||||
},
|
||||
"shapes":{}
|
||||
}
|
||||
vendor/github.com/aws/aws-sdk-go/private/model/api/codegentest/models/restjson/0000-00-00/api-2.json
Generated
Vendored
+226
@@ -0,0 +1,226 @@
|
||||
{
|
||||
"version":"2.0",
|
||||
"metadata":{
|
||||
"apiVersion":"0000-00-00",
|
||||
"endpointPrefix":"restjsonservice",
|
||||
"protocol":"rest-json",
|
||||
"serviceAbbreviation":"RESTJSONService",
|
||||
"serviceFullName":"REST JSON Service",
|
||||
"serviceId":"RESTJSONService",
|
||||
"signatureVersion":"v4",
|
||||
"uid":"RESTJSONService-0000-00-00"
|
||||
},
|
||||
"operations":{
|
||||
"GetEventStream":{
|
||||
"name":"GetEventStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"GetEventStreamRequest"},
|
||||
"output":{"shape":"GetEventStreamResponse"}
|
||||
},
|
||||
"EmptyStream":{
|
||||
"name":"EmptyStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"EmptyStreamRequest"},
|
||||
"output":{"shape":"EmptyStreamResponse"}
|
||||
},
|
||||
"OtherOperation":{
|
||||
"name":"OtherOperation",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"errors":[
|
||||
{"shape":"ExceptionEvent2"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"shapes":{
|
||||
"Bool":{"type":"boolean"},
|
||||
"Byte":{"type":"byte"},
|
||||
"Short":{"type":"short"},
|
||||
"Integer":{"type":"integer"},
|
||||
"Long":{"type":"long"},
|
||||
"Blob":{"type":"blob"},
|
||||
"String":{"type":"string"},
|
||||
"Time":{"type":"timestamp"},
|
||||
"GetEventStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"InputVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"GetEventStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StrVal":{"shape":"String"},
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"EventStream":{"shape":"EventStream"}
|
||||
}
|
||||
},
|
||||
"EventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Headers":{"shape":"HeaderOnlyEvent"},
|
||||
"ImplicitPayload":{"shape":"ImplicitPayloadEvent"},
|
||||
"ExplicitPayload":{"shape":"ExplicitPayloadEvent"},
|
||||
"PayloadOnly":{"shape":"PayloadOnlyEvent"},
|
||||
"PayloadOnlyBlob":{"shape":"PayloadOnlyBlobEvent"},
|
||||
"PayloadOnlyString":{"shape":"PayloadOnlyStringEvent"},
|
||||
"Empty":{"shape":"EmptyEvent"},
|
||||
"Exception":{"shape":"ExceptionEvent"},
|
||||
"Exception2":{"shape":"ExceptionEvent2"}
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"EmptyStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{}
|
||||
},
|
||||
"EmptyStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"EventStream":{"shape":"EmptyEventStream"}
|
||||
}
|
||||
},
|
||||
"EmptyEventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"HeaderOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BoolVal":{
|
||||
"shape":"Bool",
|
||||
"eventheader":true
|
||||
},
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short",
|
||||
"eventheader":true
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer",
|
||||
"eventheader":true
|
||||
},
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"BlobVal":{
|
||||
"shape":"Blob",
|
||||
"eventheader":true
|
||||
},
|
||||
"TimeVal":{
|
||||
"shape":"Time",
|
||||
"eventheader":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ImplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short"
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer"
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ExplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyBlobEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BlobPayload":{
|
||||
"shape":"Blob",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyStringEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StringPayload":{
|
||||
"shape":"String",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"EmptyEvent": {
|
||||
"type":"structure",
|
||||
"members":{},
|
||||
"event": true
|
||||
},
|
||||
"NestedShape": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"StrVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"ExceptionEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"message":{"shape":"String"}
|
||||
},
|
||||
"exception":true
|
||||
},
|
||||
"ExceptionEvent2":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"exception":true
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"service": null,
|
||||
"operations": {
|
||||
},
|
||||
"shapes":{}
|
||||
}
|
||||
Generated
Vendored
+226
@@ -0,0 +1,226 @@
|
||||
{
|
||||
"version":"2.0",
|
||||
"metadata":{
|
||||
"apiVersion":"0000-00-00",
|
||||
"endpointPrefix":"restxmlservice",
|
||||
"protocol":"rest-xml",
|
||||
"serviceAbbreviation":"RESTXMLService",
|
||||
"serviceFullName":"REST XML Service",
|
||||
"serviceId":"RESTXMLService",
|
||||
"signatureVersion":"v4",
|
||||
"uid":"RESTXMLService-0000-00-00"
|
||||
},
|
||||
"operations":{
|
||||
"GetEventStream":{
|
||||
"name":"GetEventStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"GetEventStreamRequest"},
|
||||
"output":{"shape":"GetEventStreamResponse"}
|
||||
},
|
||||
"EmptyStream":{
|
||||
"name":"EmptyStream",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"input":{"shape":"EmptyStreamRequest"},
|
||||
"output":{"shape":"EmptyStreamResponse"}
|
||||
},
|
||||
"OtherOperation":{
|
||||
"name":"OtherOperation",
|
||||
"http":{
|
||||
"method":"POST",
|
||||
"requestUri":"/"
|
||||
},
|
||||
"errors":[
|
||||
{"shape":"ExceptionEvent2"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"shapes":{
|
||||
"Bool":{"type":"boolean"},
|
||||
"Byte":{"type":"byte"},
|
||||
"Short":{"type":"short"},
|
||||
"Integer":{"type":"integer"},
|
||||
"Long":{"type":"long"},
|
||||
"Blob":{"type":"blob"},
|
||||
"String":{"type":"string"},
|
||||
"Time":{"type":"timestamp"},
|
||||
"GetEventStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"InputVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"GetEventStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StrVal":{"shape":"String"},
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"EventStream":{"shape":"EventStream"}
|
||||
}
|
||||
},
|
||||
"EventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"Headers":{"shape":"HeaderOnlyEvent"},
|
||||
"ImplicitPayload":{"shape":"ImplicitPayloadEvent"},
|
||||
"ExplicitPayload":{"shape":"ExplicitPayloadEvent"},
|
||||
"PayloadOnly":{"shape":"PayloadOnlyEvent"},
|
||||
"PayloadOnlyBlob":{"shape":"PayloadOnlyBlobEvent"},
|
||||
"PayloadOnlyString":{"shape":"PayloadOnlyStringEvent"},
|
||||
"Empty":{"shape":"EmptyEvent"},
|
||||
"Exception":{"shape":"ExceptionEvent"},
|
||||
"Exception2":{"shape":"ExceptionEvent2"}
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"EmptyStreamRequest":{
|
||||
"type":"structure",
|
||||
"members":{}
|
||||
},
|
||||
"EmptyStreamResponse":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"EventStream":{"shape":"EmptyEventStream"}
|
||||
}
|
||||
},
|
||||
"EmptyEventStream":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"eventstream":true
|
||||
},
|
||||
"HeaderOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BoolVal":{
|
||||
"shape":"Bool",
|
||||
"eventheader":true
|
||||
},
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short",
|
||||
"eventheader":true
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer",
|
||||
"eventheader":true
|
||||
},
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"BlobVal":{
|
||||
"shape":"Blob",
|
||||
"eventheader":true
|
||||
},
|
||||
"TimeVal":{
|
||||
"shape":"Time",
|
||||
"eventheader":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ImplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"ByteVal":{
|
||||
"shape":"Byte",
|
||||
"eventheader":true
|
||||
},
|
||||
"ShortVal":{
|
||||
"shape":"Short"
|
||||
},
|
||||
"IntegerVal":{
|
||||
"shape":"Integer"
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"ExplicitPayloadEvent": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"LongVal":{
|
||||
"shape":"Long",
|
||||
"eventheader":true
|
||||
},
|
||||
"StringVal":{
|
||||
"shape":"String",
|
||||
"eventheader":true
|
||||
},
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"NestedVal":{
|
||||
"shape":"NestedShape",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyBlobEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"BlobPayload":{
|
||||
"shape":"Blob",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"PayloadOnlyStringEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"StringPayload":{
|
||||
"shape":"String",
|
||||
"eventpayload":true
|
||||
}
|
||||
},
|
||||
"event":true
|
||||
},
|
||||
"EmptyEvent": {
|
||||
"type":"structure",
|
||||
"members":{},
|
||||
"event": true
|
||||
},
|
||||
"NestedShape": {
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"StrVal":{"shape":"String"}
|
||||
}
|
||||
},
|
||||
"ExceptionEvent":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
"IntVal":{"shape":"Integer"},
|
||||
"message":{"shape":"String"}
|
||||
},
|
||||
"exception":true
|
||||
},
|
||||
"ExceptionEvent2":{
|
||||
"type":"structure",
|
||||
"members":{
|
||||
},
|
||||
"exception":true
|
||||
}
|
||||
}
|
||||
}
|
||||
vendor/github.com/aws/aws-sdk-go/private/model/api/codegentest/models/restxml/0000-00-00/docs-2.json
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"service": null,
|
||||
"operations": {
|
||||
},
|
||||
"shapes":{}
|
||||
}
|
||||
Generated
Vendored
+635
@@ -0,0 +1,635 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package awsendpointdiscoverytest
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/aws/crr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
const opDescribeEndpoints = "DescribeEndpoints"
|
||||
|
||||
// DescribeEndpointsRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DescribeEndpoints operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See DescribeEndpoints for more information on using the DescribeEndpoints
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the DescribeEndpointsRequest method.
|
||||
// req, resp := client.DescribeEndpointsRequest(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *AwsEndpointDiscoveryTest) DescribeEndpointsRequest(input *DescribeEndpointsInput) (req *request.Request, output *DescribeEndpointsOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opDescribeEndpoints,
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DescribeEndpointsInput{}
|
||||
}
|
||||
|
||||
output = &DescribeEndpointsOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
return
|
||||
}
|
||||
|
||||
// DescribeEndpoints API operation for AwsEndpointDiscoveryTest.
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for AwsEndpointDiscoveryTest's
|
||||
// API operation DescribeEndpoints for usage and error information.
|
||||
func (c *AwsEndpointDiscoveryTest) DescribeEndpoints(input *DescribeEndpointsInput) (*DescribeEndpointsOutput, error) {
|
||||
req, out := c.DescribeEndpointsRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// DescribeEndpointsWithContext is the same as DescribeEndpoints with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See DescribeEndpoints for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *AwsEndpointDiscoveryTest) DescribeEndpointsWithContext(ctx aws.Context, input *DescribeEndpointsInput, opts ...request.Option) (*DescribeEndpointsOutput, error) {
|
||||
req, out := c.DescribeEndpointsRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type discovererDescribeEndpoints struct {
|
||||
Client *AwsEndpointDiscoveryTest
|
||||
Required bool
|
||||
EndpointCache *crr.EndpointCache
|
||||
Params map[string]*string
|
||||
Key string
|
||||
}
|
||||
|
||||
func (d *discovererDescribeEndpoints) Discover() (crr.Endpoint, error) {
|
||||
input := &DescribeEndpointsInput{
|
||||
Operation: d.Params["op"],
|
||||
}
|
||||
|
||||
resp, err := d.Client.DescribeEndpoints(input)
|
||||
if err != nil {
|
||||
return crr.Endpoint{}, err
|
||||
}
|
||||
|
||||
endpoint := crr.Endpoint{
|
||||
Key: d.Key,
|
||||
}
|
||||
|
||||
for _, e := range resp.Endpoints {
|
||||
if e.Address == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cachedInMinutes := aws.Int64Value(e.CachePeriodInMinutes)
|
||||
u, err := url.Parse(*e.Address)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
addr := crr.WeightedAddress{
|
||||
URL: u,
|
||||
Expired: time.Now().Add(time.Duration(cachedInMinutes) * time.Minute),
|
||||
}
|
||||
|
||||
endpoint.Add(addr)
|
||||
}
|
||||
|
||||
d.EndpointCache.Add(endpoint)
|
||||
|
||||
return endpoint, nil
|
||||
}
|
||||
|
||||
func (d *discovererDescribeEndpoints) Handler(r *request.Request) {
|
||||
endpointKey := crr.BuildEndpointKey(d.Params)
|
||||
d.Key = endpointKey
|
||||
|
||||
endpoint, err := d.EndpointCache.Get(d, endpointKey, d.Required)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return
|
||||
}
|
||||
|
||||
if endpoint.URL != nil && len(endpoint.URL.String()) > 0 {
|
||||
r.HTTPRequest.URL = endpoint.URL
|
||||
}
|
||||
}
|
||||
|
||||
const opTestDiscoveryIdentifiersRequired = "TestDiscoveryIdentifiersRequired"
|
||||
|
||||
// TestDiscoveryIdentifiersRequiredRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the TestDiscoveryIdentifiersRequired operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See TestDiscoveryIdentifiersRequired for more information on using the TestDiscoveryIdentifiersRequired
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the TestDiscoveryIdentifiersRequiredRequest method.
|
||||
// req, resp := client.TestDiscoveryIdentifiersRequiredRequest(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryIdentifiersRequiredRequest(input *TestDiscoveryIdentifiersRequiredInput) (req *request.Request, output *TestDiscoveryIdentifiersRequiredOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opTestDiscoveryIdentifiersRequired,
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &TestDiscoveryIdentifiersRequiredInput{}
|
||||
}
|
||||
|
||||
output = &TestDiscoveryIdentifiersRequiredOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
de := discovererDescribeEndpoints{
|
||||
Required: true,
|
||||
EndpointCache: c.endpointCache,
|
||||
Params: map[string]*string{
|
||||
"op": aws.String(req.Operation.Name),
|
||||
"Sdk": input.Sdk,
|
||||
},
|
||||
Client: c,
|
||||
}
|
||||
|
||||
for k, v := range de.Params {
|
||||
if v == nil {
|
||||
delete(de.Params, k)
|
||||
}
|
||||
}
|
||||
|
||||
req.Handlers.Build.PushFrontNamed(request.NamedHandler{
|
||||
Name: "crr.endpointdiscovery",
|
||||
Fn: de.Handler,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// TestDiscoveryIdentifiersRequired API operation for AwsEndpointDiscoveryTest.
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for AwsEndpointDiscoveryTest's
|
||||
// API operation TestDiscoveryIdentifiersRequired for usage and error information.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryIdentifiersRequired(input *TestDiscoveryIdentifiersRequiredInput) (*TestDiscoveryIdentifiersRequiredOutput, error) {
|
||||
req, out := c.TestDiscoveryIdentifiersRequiredRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// TestDiscoveryIdentifiersRequiredWithContext is the same as TestDiscoveryIdentifiersRequired with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See TestDiscoveryIdentifiersRequired for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryIdentifiersRequiredWithContext(ctx aws.Context, input *TestDiscoveryIdentifiersRequiredInput, opts ...request.Option) (*TestDiscoveryIdentifiersRequiredOutput, error) {
|
||||
req, out := c.TestDiscoveryIdentifiersRequiredRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opTestDiscoveryOptional = "TestDiscoveryOptional"
|
||||
|
||||
// TestDiscoveryOptionalRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the TestDiscoveryOptional operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See TestDiscoveryOptional for more information on using the TestDiscoveryOptional
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the TestDiscoveryOptionalRequest method.
|
||||
// req, resp := client.TestDiscoveryOptionalRequest(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryOptionalRequest(input *TestDiscoveryOptionalInput) (req *request.Request, output *TestDiscoveryOptionalOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opTestDiscoveryOptional,
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &TestDiscoveryOptionalInput{}
|
||||
}
|
||||
|
||||
output = &TestDiscoveryOptionalOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
if aws.BoolValue(req.Config.EnableEndpointDiscovery) {
|
||||
de := discovererDescribeEndpoints{
|
||||
Required: false,
|
||||
EndpointCache: c.endpointCache,
|
||||
Params: map[string]*string{
|
||||
"op": aws.String(req.Operation.Name),
|
||||
},
|
||||
Client: c,
|
||||
}
|
||||
|
||||
for k, v := range de.Params {
|
||||
if v == nil {
|
||||
delete(de.Params, k)
|
||||
}
|
||||
}
|
||||
|
||||
req.Handlers.Build.PushFrontNamed(request.NamedHandler{
|
||||
Name: "crr.endpointdiscovery",
|
||||
Fn: de.Handler,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TestDiscoveryOptional API operation for AwsEndpointDiscoveryTest.
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for AwsEndpointDiscoveryTest's
|
||||
// API operation TestDiscoveryOptional for usage and error information.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryOptional(input *TestDiscoveryOptionalInput) (*TestDiscoveryOptionalOutput, error) {
|
||||
req, out := c.TestDiscoveryOptionalRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// TestDiscoveryOptionalWithContext is the same as TestDiscoveryOptional with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See TestDiscoveryOptional for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryOptionalWithContext(ctx aws.Context, input *TestDiscoveryOptionalInput, opts ...request.Option) (*TestDiscoveryOptionalOutput, error) {
|
||||
req, out := c.TestDiscoveryOptionalRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opTestDiscoveryRequired = "TestDiscoveryRequired"
|
||||
|
||||
// TestDiscoveryRequiredRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the TestDiscoveryRequired operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See TestDiscoveryRequired for more information on using the TestDiscoveryRequired
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the TestDiscoveryRequiredRequest method.
|
||||
// req, resp := client.TestDiscoveryRequiredRequest(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryRequiredRequest(input *TestDiscoveryRequiredInput) (req *request.Request, output *TestDiscoveryRequiredOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opTestDiscoveryRequired,
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &TestDiscoveryRequiredInput{}
|
||||
}
|
||||
|
||||
output = &TestDiscoveryRequiredOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
if aws.BoolValue(req.Config.EnableEndpointDiscovery) {
|
||||
de := discovererDescribeEndpoints{
|
||||
Required: false,
|
||||
EndpointCache: c.endpointCache,
|
||||
Params: map[string]*string{
|
||||
"op": aws.String(req.Operation.Name),
|
||||
},
|
||||
Client: c,
|
||||
}
|
||||
|
||||
for k, v := range de.Params {
|
||||
if v == nil {
|
||||
delete(de.Params, k)
|
||||
}
|
||||
}
|
||||
|
||||
req.Handlers.Build.PushFrontNamed(request.NamedHandler{
|
||||
Name: "crr.endpointdiscovery",
|
||||
Fn: de.Handler,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TestDiscoveryRequired API operation for AwsEndpointDiscoveryTest.
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for AwsEndpointDiscoveryTest's
|
||||
// API operation TestDiscoveryRequired for usage and error information.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryRequired(input *TestDiscoveryRequiredInput) (*TestDiscoveryRequiredOutput, error) {
|
||||
req, out := c.TestDiscoveryRequiredRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// TestDiscoveryRequiredWithContext is the same as TestDiscoveryRequired with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See TestDiscoveryRequired for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *AwsEndpointDiscoveryTest) TestDiscoveryRequiredWithContext(ctx aws.Context, input *TestDiscoveryRequiredInput, opts ...request.Option) (*TestDiscoveryRequiredOutput, error) {
|
||||
req, out := c.TestDiscoveryRequiredRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type DescribeEndpointsInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Operation *string `type:"string"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s DescribeEndpointsInput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s DescribeEndpointsInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetOperation sets the Operation field's value.
|
||||
func (s *DescribeEndpointsInput) SetOperation(v string) *DescribeEndpointsInput {
|
||||
s.Operation = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type DescribeEndpointsOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Endpoints is a required field
|
||||
Endpoints []*Endpoint `type:"list" required:"true"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s DescribeEndpointsOutput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s DescribeEndpointsOutput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetEndpoints sets the Endpoints field's value.
|
||||
func (s *DescribeEndpointsOutput) SetEndpoints(v []*Endpoint) *DescribeEndpointsOutput {
|
||||
s.Endpoints = v
|
||||
return s
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Address is a required field
|
||||
Address *string `type:"string" required:"true"`
|
||||
|
||||
// CachePeriodInMinutes is a required field
|
||||
CachePeriodInMinutes *int64 `type:"long" required:"true"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s Endpoint) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s Endpoint) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetAddress sets the Address field's value.
|
||||
func (s *Endpoint) SetAddress(v string) *Endpoint {
|
||||
s.Address = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetCachePeriodInMinutes sets the CachePeriodInMinutes field's value.
|
||||
func (s *Endpoint) SetCachePeriodInMinutes(v int64) *Endpoint {
|
||||
s.CachePeriodInMinutes = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryIdentifiersRequiredInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Sdk is a required field
|
||||
Sdk *string `type:"string" required:"true"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryIdentifiersRequiredInput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryIdentifiersRequiredInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// Validate inspects the fields of the type to determine if they are valid.
|
||||
func (s *TestDiscoveryIdentifiersRequiredInput) Validate() error {
|
||||
invalidParams := request.ErrInvalidParams{Context: "TestDiscoveryIdentifiersRequiredInput"}
|
||||
if s.Sdk == nil {
|
||||
invalidParams.Add(request.NewErrParamRequired("Sdk"))
|
||||
}
|
||||
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSdk sets the Sdk field's value.
|
||||
func (s *TestDiscoveryIdentifiersRequiredInput) SetSdk(v string) *TestDiscoveryIdentifiersRequiredInput {
|
||||
s.Sdk = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryIdentifiersRequiredOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
RequestSuccessful *bool `type:"boolean"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryIdentifiersRequiredOutput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryIdentifiersRequiredOutput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetRequestSuccessful sets the RequestSuccessful field's value.
|
||||
func (s *TestDiscoveryIdentifiersRequiredOutput) SetRequestSuccessful(v bool) *TestDiscoveryIdentifiersRequiredOutput {
|
||||
s.RequestSuccessful = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryOptionalInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Sdk *string `type:"string"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryOptionalInput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryOptionalInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetSdk sets the Sdk field's value.
|
||||
func (s *TestDiscoveryOptionalInput) SetSdk(v string) *TestDiscoveryOptionalInput {
|
||||
s.Sdk = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryOptionalOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
RequestSuccessful *bool `type:"boolean"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryOptionalOutput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryOptionalOutput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetRequestSuccessful sets the RequestSuccessful field's value.
|
||||
func (s *TestDiscoveryOptionalOutput) SetRequestSuccessful(v bool) *TestDiscoveryOptionalOutput {
|
||||
s.RequestSuccessful = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryRequiredInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Sdk *string `type:"string"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryRequiredInput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryRequiredInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetSdk sets the Sdk field's value.
|
||||
func (s *TestDiscoveryRequiredInput) SetSdk(v string) *TestDiscoveryRequiredInput {
|
||||
s.Sdk = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type TestDiscoveryRequiredOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
RequestSuccessful *bool `type:"boolean"`
|
||||
}
|
||||
|
||||
// String returns the string representation
|
||||
func (s TestDiscoveryRequiredOutput) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation
|
||||
func (s TestDiscoveryRequiredOutput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SetRequestSuccessful sets the RequestSuccessful field's value.
|
||||
func (s *TestDiscoveryRequiredOutput) SetRequestSuccessful(v bool) *TestDiscoveryRequiredOutput {
|
||||
s.RequestSuccessful = &v
|
||||
return s
|
||||
}
|
||||
Generated
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package awsendpointdiscoverytestiface provides an interface to enable mocking the AwsEndpointDiscoveryTest service client
|
||||
// for testing your code.
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters.
|
||||
package awsendpointdiscoverytestiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/model/api/codegentest/service/awsendpointdiscoverytest"
|
||||
)
|
||||
|
||||
// AwsEndpointDiscoveryTestAPI provides an interface to enable mocking the
|
||||
// awsendpointdiscoverytest.AwsEndpointDiscoveryTest service client's API operation,
|
||||
// paginators, and waiters. This make unit testing your code that calls out
|
||||
// to the SDK's service client's calls easier.
|
||||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // AwsEndpointDiscoveryTest.
|
||||
// func myFunc(svc awsendpointdiscoverytestiface.AwsEndpointDiscoveryTestAPI) bool {
|
||||
// // Make svc.DescribeEndpoints request
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// sess := session.New()
|
||||
// svc := awsendpointdiscoverytest.New(sess)
|
||||
//
|
||||
// myFunc(svc)
|
||||
// }
|
||||
//
|
||||
// In your _test.go file:
|
||||
//
|
||||
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||
// type mockAwsEndpointDiscoveryTestClient struct {
|
||||
// awsendpointdiscoverytestiface.AwsEndpointDiscoveryTestAPI
|
||||
// }
|
||||
// func (m *mockAwsEndpointDiscoveryTestClient) DescribeEndpoints(input *awsendpointdiscoverytest.DescribeEndpointsInput) (*awsendpointdiscoverytest.DescribeEndpointsOutput, error) {
|
||||
// // mock response/functionality
|
||||
// }
|
||||
//
|
||||
// func TestMyFunc(t *testing.T) {
|
||||
// // Setup Test
|
||||
// mockSvc := &mockAwsEndpointDiscoveryTestClient{}
|
||||
//
|
||||
// myfunc(mockSvc)
|
||||
//
|
||||
// // Verify myFunc's functionality
|
||||
// }
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type AwsEndpointDiscoveryTestAPI interface {
|
||||
DescribeEndpoints(*awsendpointdiscoverytest.DescribeEndpointsInput) (*awsendpointdiscoverytest.DescribeEndpointsOutput, error)
|
||||
DescribeEndpointsWithContext(aws.Context, *awsendpointdiscoverytest.DescribeEndpointsInput, ...request.Option) (*awsendpointdiscoverytest.DescribeEndpointsOutput, error)
|
||||
DescribeEndpointsRequest(*awsendpointdiscoverytest.DescribeEndpointsInput) (*request.Request, *awsendpointdiscoverytest.DescribeEndpointsOutput)
|
||||
|
||||
TestDiscoveryIdentifiersRequired(*awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredInput) (*awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredOutput, error)
|
||||
TestDiscoveryIdentifiersRequiredWithContext(aws.Context, *awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredInput, ...request.Option) (*awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredOutput, error)
|
||||
TestDiscoveryIdentifiersRequiredRequest(*awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredInput) (*request.Request, *awsendpointdiscoverytest.TestDiscoveryIdentifiersRequiredOutput)
|
||||
|
||||
TestDiscoveryOptional(*awsendpointdiscoverytest.TestDiscoveryOptionalInput) (*awsendpointdiscoverytest.TestDiscoveryOptionalOutput, error)
|
||||
TestDiscoveryOptionalWithContext(aws.Context, *awsendpointdiscoverytest.TestDiscoveryOptionalInput, ...request.Option) (*awsendpointdiscoverytest.TestDiscoveryOptionalOutput, error)
|
||||
TestDiscoveryOptionalRequest(*awsendpointdiscoverytest.TestDiscoveryOptionalInput) (*request.Request, *awsendpointdiscoverytest.TestDiscoveryOptionalOutput)
|
||||
|
||||
TestDiscoveryRequired(*awsendpointdiscoverytest.TestDiscoveryRequiredInput) (*awsendpointdiscoverytest.TestDiscoveryRequiredOutput, error)
|
||||
TestDiscoveryRequiredWithContext(aws.Context, *awsendpointdiscoverytest.TestDiscoveryRequiredInput, ...request.Option) (*awsendpointdiscoverytest.TestDiscoveryRequiredOutput, error)
|
||||
TestDiscoveryRequiredRequest(*awsendpointdiscoverytest.TestDiscoveryRequiredInput) (*request.Request, *awsendpointdiscoverytest.TestDiscoveryRequiredOutput)
|
||||
}
|
||||
|
||||
var _ AwsEndpointDiscoveryTestAPI = (*awsendpointdiscoverytest.AwsEndpointDiscoveryTest)(nil)
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package awsendpointdiscoverytest provides the client and types for making API
|
||||
// requests to AwsEndpointDiscoveryTest.
|
||||
//
|
||||
// See awsendpointdiscoverytest package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/awsendpointdiscoverytest/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact AwsEndpointDiscoveryTest with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the AwsEndpointDiscoveryTest client AwsEndpointDiscoveryTest for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/awsendpointdiscoverytest/#New
|
||||
package awsendpointdiscoverytest
|
||||
Generated
Vendored
+136
@@ -0,0 +1,136 @@
|
||||
package awsendpointdiscoverytest
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
)
|
||||
|
||||
func TestEndpointDiscovery(t *testing.T) {
|
||||
svc := New(unit.Session, &aws.Config{
|
||||
EnableEndpointDiscovery: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Clear()
|
||||
svc.Handlers.Send.PushBack(mockSendDescEndpoint)
|
||||
|
||||
var descCount int32
|
||||
svc.Handlers.Complete.PushBack(func(r *request.Request) {
|
||||
if r.Operation.Name != opDescribeEndpoints {
|
||||
return
|
||||
}
|
||||
atomic.AddInt32(&descCount, 1)
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
req, _ := svc.TestDiscoveryIdentifiersRequiredRequest(
|
||||
&TestDiscoveryIdentifiersRequiredInput{
|
||||
Sdk: aws.String("sdk"),
|
||||
},
|
||||
)
|
||||
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
if e, a := "http://foo", r.HTTPRequest.URL.String(); e != a {
|
||||
t.Errorf("expected %q, but received %q", e, a)
|
||||
}
|
||||
})
|
||||
if err := req.Send(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if e, a := int32(1), atomic.LoadInt32(&descCount); e != a {
|
||||
t.Errorf("expect desc endpoint called %d, got %d", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsyncEndpointDiscovery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := New(unit.Session, &aws.Config{
|
||||
EnableEndpointDiscovery: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Clear()
|
||||
|
||||
var firstAsyncReq sync.WaitGroup
|
||||
firstAsyncReq.Add(1)
|
||||
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||
if r.Operation.Name == opDescribeEndpoints {
|
||||
firstAsyncReq.Wait()
|
||||
}
|
||||
})
|
||||
svc.Handlers.Send.PushBack(mockSendDescEndpoint)
|
||||
|
||||
req, _ := svc.TestDiscoveryOptionalRequest(&TestDiscoveryOptionalInput{
|
||||
Sdk: aws.String("sdk"),
|
||||
})
|
||||
const clientHost = "awsendpointdiscoverytestservice.mock-region.amazonaws.com"
|
||||
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
if e, a := clientHost, r.HTTPRequest.URL.Host; e != a {
|
||||
t.Errorf("expected %q, but received %q", e, a)
|
||||
}
|
||||
})
|
||||
req.Handlers.Complete.PushBack(func(r *request.Request) {
|
||||
firstAsyncReq.Done()
|
||||
})
|
||||
if err := req.Send(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var cacheUpdated bool
|
||||
for s := time.Now().Add(10 * time.Second); s.After(time.Now()); {
|
||||
// Wait for the cache to be updated before making second request.
|
||||
if svc.endpointCache.Has(req.Operation.Name) {
|
||||
cacheUpdated = true
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
if !cacheUpdated {
|
||||
t.Fatalf("expect endpoint cache to be updated, was not")
|
||||
}
|
||||
|
||||
req, _ = svc.TestDiscoveryOptionalRequest(&TestDiscoveryOptionalInput{
|
||||
Sdk: aws.String("sdk"),
|
||||
})
|
||||
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||
if e, a := "http://foo", r.HTTPRequest.URL.String(); e != a {
|
||||
t.Errorf("expected %q, but received %q", e, a)
|
||||
}
|
||||
})
|
||||
if err := req.Send(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func removeHandlers(h request.Handlers, removeSendHandlers bool) request.Handlers {
|
||||
if removeSendHandlers {
|
||||
h.Send.Clear()
|
||||
}
|
||||
h.Unmarshal.Clear()
|
||||
h.UnmarshalStream.Clear()
|
||||
h.UnmarshalMeta.Clear()
|
||||
h.UnmarshalError.Clear()
|
||||
h.Validate.Clear()
|
||||
h.Complete.Clear()
|
||||
h.ValidateResponse.Clear()
|
||||
return h
|
||||
}
|
||||
|
||||
func mockSendDescEndpoint(r *request.Request) {
|
||||
if r.Operation.Name != opDescribeEndpoints {
|
||||
return
|
||||
}
|
||||
|
||||
out, _ := r.Data.(*DescribeEndpointsOutput)
|
||||
out.Endpoints = []*Endpoint{
|
||||
{
|
||||
Address: aws.String("http://foo"),
|
||||
CachePeriodInMinutes: aws.Int64(5),
|
||||
},
|
||||
}
|
||||
r.Data = out
|
||||
}
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package awsendpointdiscoverytest
|
||||
Generated
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package awsendpointdiscoverytest
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/crr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
)
|
||||
|
||||
// AwsEndpointDiscoveryTest provides the API operation methods for making requests to
|
||||
// AwsEndpointDiscoveryTest. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// AwsEndpointDiscoveryTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type AwsEndpointDiscoveryTest struct {
|
||||
*client.Client
|
||||
endpointCache *crr.EndpointCache
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "AwsEndpointDiscoveryTest" // Name of service.
|
||||
EndpointsID = "awsendpointdiscoverytestservice" // ID to lookup a service endpoint with.
|
||||
ServiceID = "AwsEndpointDiscoveryTest" // ServiceID is a unique identifer of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the AwsEndpointDiscoveryTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a AwsEndpointDiscoveryTest client from just a session.
|
||||
// svc := awsendpointdiscoverytest.New(mySession)
|
||||
//
|
||||
// // Create a AwsEndpointDiscoveryTest client with additional configuration
|
||||
// svc := awsendpointdiscoverytest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *AwsEndpointDiscoveryTest {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
if c.SigningNameDerived || len(c.SigningName) == 0 {
|
||||
c.SigningName = "awsendpointdiscoverytestservice"
|
||||
}
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *AwsEndpointDiscoveryTest {
|
||||
svc := &AwsEndpointDiscoveryTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2018-08-31",
|
||||
JSONVersion: "1.1",
|
||||
TargetPrefix: "AwsEndpointDiscoveryTestService",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
svc.endpointCache = crr.NewEndpointCache(10)
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a AwsEndpointDiscoveryTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *AwsEndpointDiscoveryTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
// Package service contains automatically generated AWS clients.
|
||||
package service
|
||||
|
||||
//go:generate go run -tags codegen ../../../cli/gen-api/main.go -path=../service -svc-import-path "github.com/aws/aws-sdk-go/private/model/api/codegentest/service" ../models/*/*/api-2.json
|
||||
//go:generate gofmt -s -w ../service
|
||||
Generated
Vendored
+1355
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package restjsonservice provides the client and types for making API
|
||||
// requests to REST JSON Service.
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/RESTJSONService-0000-00-00 for more information on this service.
|
||||
//
|
||||
// See restjsonservice package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/restjsonservice/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact REST JSON Service with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the REST JSON Service client RESTJSONService for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/restjsonservice/#New
|
||||
package restjsonservice
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package restjsonservice
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeExceptionEvent for service response error code
|
||||
// "ExceptionEvent".
|
||||
ErrCodeExceptionEvent = "ExceptionEvent"
|
||||
|
||||
// ErrCodeExceptionEvent2 for service response error code
|
||||
// "ExceptionEvent2".
|
||||
ErrCodeExceptionEvent2 = "ExceptionEvent2"
|
||||
)
|
||||
Generated
Vendored
+526
@@ -0,0 +1,526 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// +build go1.6
|
||||
|
||||
package restjsonservice
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamtest"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
var _ time.Time
|
||||
var _ awserr.Error
|
||||
|
||||
func TestEmptyStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEmptyStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockEmptyStreamReadEvents() (
|
||||
[]EmptyEventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EmptyEventStreamEvent{}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restjson.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
|
||||
func TestGetEventStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEventStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetEventStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockGetEventStreamReadEvents() (
|
||||
[]EventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&EmptyEvent{},
|
||||
&ExplicitPayloadEvent{
|
||||
LongVal: aws.Int64(1234),
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
StringVal: aws.String("string value goes here"),
|
||||
},
|
||||
&HeaderOnlyEvent{
|
||||
BlobVal: []byte("blob value goes here"),
|
||||
BoolVal: aws.Bool(true),
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
LongVal: aws.Int64(1234),
|
||||
ShortVal: aws.Int64(12),
|
||||
StringVal: aws.String("string value goes here"),
|
||||
TimeVal: aws.Time(time.Unix(1396594860, 0).UTC()),
|
||||
},
|
||||
&ImplicitPayloadEvent{
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
ShortVal: aws.Int64(12),
|
||||
},
|
||||
&PayloadOnlyEvent{
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
},
|
||||
&PayloadOnlyBlobEvent{
|
||||
BlobPayload: []byte("blob value goes here"),
|
||||
},
|
||||
&PayloadOnlyStringEvent{
|
||||
StringPayload: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restjson.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Empty"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ExplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[1].(*ExplicitPayloadEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[1].(*ExplicitPayloadEvent).StringVal),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[1]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Headers"),
|
||||
},
|
||||
{
|
||||
Name: "BlobVal",
|
||||
Value: eventstream.BytesValue(expectEvents[2].(*HeaderOnlyEvent).BlobVal),
|
||||
},
|
||||
{
|
||||
Name: "BoolVal",
|
||||
Value: eventstream.BoolValue(*expectEvents[2].(*HeaderOnlyEvent).BoolVal),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[2].(*HeaderOnlyEvent).ByteVal)),
|
||||
},
|
||||
{
|
||||
Name: "IntegerVal",
|
||||
Value: eventstream.Int32Value(int32(*expectEvents[2].(*HeaderOnlyEvent).IntegerVal)),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[2].(*HeaderOnlyEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "ShortVal",
|
||||
Value: eventstream.Int16Value(int16(*expectEvents[2].(*HeaderOnlyEvent).ShortVal)),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[2].(*HeaderOnlyEvent).StringVal),
|
||||
},
|
||||
{
|
||||
Name: "TimeVal",
|
||||
Value: eventstream.TimestampValue(*expectEvents[2].(*HeaderOnlyEvent).TimeVal),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ImplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[3].(*ImplicitPayloadEvent).ByteVal)),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[3]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnly"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[4]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyBlob"),
|
||||
},
|
||||
},
|
||||
Payload: expectEvents[5].(*PayloadOnlyBlobEvent).BlobPayload,
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyString"),
|
||||
},
|
||||
},
|
||||
Payload: []byte(*expectEvents[6].(*PayloadOnlyStringEvent).StringPayload),
|
||||
},
|
||||
}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
func TestGetEventStream_ReadException(t *testing.T) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restjson.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventExceptionTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.ExceptionTypeHeader,
|
||||
Value: eventstream.StringValue("Exception"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
|
||||
},
|
||||
}
|
||||
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
err = resp.EventStream.Err()
|
||||
if err == nil {
|
||||
t.Fatalf("expect err, got none")
|
||||
}
|
||||
|
||||
expectErr := &ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
}
|
||||
aerr, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
t.Errorf("expect exception, got %T, %#v", err, err)
|
||||
}
|
||||
if e, a := expectErr.Code(), aerr.Code(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := expectErr.Message(), aerr.Message(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := expectErr, aerr; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
var _ awserr.Error = (*ExceptionEvent)(nil)
|
||||
var _ awserr.Error = (*ExceptionEvent2)(nil)
|
||||
|
||||
type loopReader struct {
|
||||
source *bytes.Reader
|
||||
}
|
||||
|
||||
func (c *loopReader) Read(p []byte) (int, error) {
|
||||
if c.source.Len() == 0 {
|
||||
c.source.Seek(0, 0)
|
||||
}
|
||||
|
||||
return c.source.Read(p)
|
||||
}
|
||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package restjsonserviceiface provides an interface to enable mocking the REST JSON Service service client
|
||||
// for testing your code.
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters.
|
||||
package restjsonserviceiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/model/api/codegentest/service/restjsonservice"
|
||||
)
|
||||
|
||||
// RESTJSONServiceAPI provides an interface to enable mocking the
|
||||
// restjsonservice.RESTJSONService service client's API operation,
|
||||
// paginators, and waiters. This make unit testing your code that calls out
|
||||
// to the SDK's service client's calls easier.
|
||||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // REST JSON Service.
|
||||
// func myFunc(svc restjsonserviceiface.RESTJSONServiceAPI) bool {
|
||||
// // Make svc.EmptyStream request
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// sess := session.New()
|
||||
// svc := restjsonservice.New(sess)
|
||||
//
|
||||
// myFunc(svc)
|
||||
// }
|
||||
//
|
||||
// In your _test.go file:
|
||||
//
|
||||
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||
// type mockRESTJSONServiceClient struct {
|
||||
// restjsonserviceiface.RESTJSONServiceAPI
|
||||
// }
|
||||
// func (m *mockRESTJSONServiceClient) EmptyStream(input *restjsonservice.EmptyStreamInput) (*restjsonservice.EmptyStreamOutput, error) {
|
||||
// // mock response/functionality
|
||||
// }
|
||||
//
|
||||
// func TestMyFunc(t *testing.T) {
|
||||
// // Setup Test
|
||||
// mockSvc := &mockRESTJSONServiceClient{}
|
||||
//
|
||||
// myfunc(mockSvc)
|
||||
//
|
||||
// // Verify myFunc's functionality
|
||||
// }
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type RESTJSONServiceAPI interface {
|
||||
EmptyStream(*restjsonservice.EmptyStreamInput) (*restjsonservice.EmptyStreamOutput, error)
|
||||
EmptyStreamWithContext(aws.Context, *restjsonservice.EmptyStreamInput, ...request.Option) (*restjsonservice.EmptyStreamOutput, error)
|
||||
EmptyStreamRequest(*restjsonservice.EmptyStreamInput) (*request.Request, *restjsonservice.EmptyStreamOutput)
|
||||
|
||||
GetEventStream(*restjsonservice.GetEventStreamInput) (*restjsonservice.GetEventStreamOutput, error)
|
||||
GetEventStreamWithContext(aws.Context, *restjsonservice.GetEventStreamInput, ...request.Option) (*restjsonservice.GetEventStreamOutput, error)
|
||||
GetEventStreamRequest(*restjsonservice.GetEventStreamInput) (*request.Request, *restjsonservice.GetEventStreamOutput)
|
||||
|
||||
OtherOperation(*restjsonservice.OtherOperationInput) (*restjsonservice.OtherOperationOutput, error)
|
||||
OtherOperationWithContext(aws.Context, *restjsonservice.OtherOperationInput, ...request.Option) (*restjsonservice.OtherOperationOutput, error)
|
||||
OtherOperationRequest(*restjsonservice.OtherOperationInput) (*request.Request, *restjsonservice.OtherOperationOutput)
|
||||
}
|
||||
|
||||
var _ RESTJSONServiceAPI = (*restjsonservice.RESTJSONService)(nil)
|
||||
Generated
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package restjsonservice
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
// RESTJSONService provides the API operation methods for making requests to
|
||||
// REST JSON Service. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// RESTJSONService methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type RESTJSONService struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "RESTJSONService" // Name of service.
|
||||
EndpointsID = "restjsonservice" // ID to lookup a service endpoint with.
|
||||
ServiceID = "RESTJSONService" // ServiceID is a unique identifer of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the RESTJSONService client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a RESTJSONService client from just a session.
|
||||
// svc := restjsonservice.New(mySession)
|
||||
//
|
||||
// // Create a RESTJSONService client with additional configuration
|
||||
// svc := restjsonservice.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *RESTJSONService {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *RESTJSONService {
|
||||
svc := &RESTJSONService{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "0000-00-00",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(restjson.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(restjson.UnmarshalErrorHandler)
|
||||
|
||||
svc.Handlers.UnmarshalStream.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a RESTJSONService operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *RESTJSONService) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
Generated
Vendored
+1355
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package restxmlservice provides the client and types for making API
|
||||
// requests to REST XML Service.
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00 for more information on this service.
|
||||
//
|
||||
// See restxmlservice package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/restxmlservice/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact REST XML Service with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the REST XML Service client RESTXMLService for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/restxmlservice/#New
|
||||
package restxmlservice
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package restxmlservice
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeExceptionEvent for service response error code
|
||||
// "ExceptionEvent".
|
||||
ErrCodeExceptionEvent = "ExceptionEvent"
|
||||
|
||||
// ErrCodeExceptionEvent2 for service response error code
|
||||
// "ExceptionEvent2".
|
||||
ErrCodeExceptionEvent2 = "ExceptionEvent2"
|
||||
)
|
||||
Generated
Vendored
+526
@@ -0,0 +1,526 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// +build go1.6
|
||||
|
||||
package restxmlservice
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamtest"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
||||
)
|
||||
|
||||
var _ time.Time
|
||||
var _ awserr.Error
|
||||
|
||||
func TestEmptyStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEmptyStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockEmptyStreamReadEvents() (
|
||||
[]EmptyEventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EmptyEventStreamEvent{}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restxml.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
|
||||
func TestGetEventStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEventStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetEventStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockGetEventStreamReadEvents() (
|
||||
[]EventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&EmptyEvent{},
|
||||
&ExplicitPayloadEvent{
|
||||
LongVal: aws.Int64(1234),
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
StringVal: aws.String("string value goes here"),
|
||||
},
|
||||
&HeaderOnlyEvent{
|
||||
BlobVal: []byte("blob value goes here"),
|
||||
BoolVal: aws.Bool(true),
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
LongVal: aws.Int64(1234),
|
||||
ShortVal: aws.Int64(12),
|
||||
StringVal: aws.String("string value goes here"),
|
||||
TimeVal: aws.Time(time.Unix(1396594860, 0).UTC()),
|
||||
},
|
||||
&ImplicitPayloadEvent{
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
ShortVal: aws.Int64(12),
|
||||
},
|
||||
&PayloadOnlyEvent{
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
},
|
||||
&PayloadOnlyBlobEvent{
|
||||
BlobPayload: []byte("blob value goes here"),
|
||||
},
|
||||
&PayloadOnlyStringEvent{
|
||||
StringPayload: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restxml.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Empty"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ExplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[1].(*ExplicitPayloadEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[1].(*ExplicitPayloadEvent).StringVal),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[1]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Headers"),
|
||||
},
|
||||
{
|
||||
Name: "BlobVal",
|
||||
Value: eventstream.BytesValue(expectEvents[2].(*HeaderOnlyEvent).BlobVal),
|
||||
},
|
||||
{
|
||||
Name: "BoolVal",
|
||||
Value: eventstream.BoolValue(*expectEvents[2].(*HeaderOnlyEvent).BoolVal),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[2].(*HeaderOnlyEvent).ByteVal)),
|
||||
},
|
||||
{
|
||||
Name: "IntegerVal",
|
||||
Value: eventstream.Int32Value(int32(*expectEvents[2].(*HeaderOnlyEvent).IntegerVal)),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[2].(*HeaderOnlyEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "ShortVal",
|
||||
Value: eventstream.Int16Value(int16(*expectEvents[2].(*HeaderOnlyEvent).ShortVal)),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[2].(*HeaderOnlyEvent).StringVal),
|
||||
},
|
||||
{
|
||||
Name: "TimeVal",
|
||||
Value: eventstream.TimestampValue(*expectEvents[2].(*HeaderOnlyEvent).TimeVal),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ImplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[3].(*ImplicitPayloadEvent).ByteVal)),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[3]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnly"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[4]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyBlob"),
|
||||
},
|
||||
},
|
||||
Payload: expectEvents[5].(*PayloadOnlyBlobEvent).BlobPayload,
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyString"),
|
||||
},
|
||||
},
|
||||
Payload: []byte(*expectEvents[6].(*PayloadOnlyStringEvent).StringPayload),
|
||||
},
|
||||
}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
func TestGetEventStream_ReadException(t *testing.T) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(restxml.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventExceptionTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.ExceptionTypeHeader,
|
||||
Value: eventstream.StringValue("Exception"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
|
||||
},
|
||||
}
|
||||
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
err = resp.EventStream.Err()
|
||||
if err == nil {
|
||||
t.Fatalf("expect err, got none")
|
||||
}
|
||||
|
||||
expectErr := &ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
}
|
||||
aerr, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
t.Errorf("expect exception, got %T, %#v", err, err)
|
||||
}
|
||||
if e, a := expectErr.Code(), aerr.Code(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := expectErr.Message(), aerr.Message(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := expectErr, aerr; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
var _ awserr.Error = (*ExceptionEvent)(nil)
|
||||
var _ awserr.Error = (*ExceptionEvent2)(nil)
|
||||
|
||||
type loopReader struct {
|
||||
source *bytes.Reader
|
||||
}
|
||||
|
||||
func (c *loopReader) Read(p []byte) (int, error) {
|
||||
if c.source.Len() == 0 {
|
||||
c.source.Seek(0, 0)
|
||||
}
|
||||
|
||||
return c.source.Read(p)
|
||||
}
|
||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package restxmlserviceiface provides an interface to enable mocking the REST XML Service service client
|
||||
// for testing your code.
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters.
|
||||
package restxmlserviceiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/model/api/codegentest/service/restxmlservice"
|
||||
)
|
||||
|
||||
// RESTXMLServiceAPI provides an interface to enable mocking the
|
||||
// restxmlservice.RESTXMLService service client's API operation,
|
||||
// paginators, and waiters. This make unit testing your code that calls out
|
||||
// to the SDK's service client's calls easier.
|
||||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // REST XML Service.
|
||||
// func myFunc(svc restxmlserviceiface.RESTXMLServiceAPI) bool {
|
||||
// // Make svc.EmptyStream request
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// sess := session.New()
|
||||
// svc := restxmlservice.New(sess)
|
||||
//
|
||||
// myFunc(svc)
|
||||
// }
|
||||
//
|
||||
// In your _test.go file:
|
||||
//
|
||||
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||
// type mockRESTXMLServiceClient struct {
|
||||
// restxmlserviceiface.RESTXMLServiceAPI
|
||||
// }
|
||||
// func (m *mockRESTXMLServiceClient) EmptyStream(input *restxmlservice.EmptyStreamInput) (*restxmlservice.EmptyStreamOutput, error) {
|
||||
// // mock response/functionality
|
||||
// }
|
||||
//
|
||||
// func TestMyFunc(t *testing.T) {
|
||||
// // Setup Test
|
||||
// mockSvc := &mockRESTXMLServiceClient{}
|
||||
//
|
||||
// myfunc(mockSvc)
|
||||
//
|
||||
// // Verify myFunc's functionality
|
||||
// }
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type RESTXMLServiceAPI interface {
|
||||
EmptyStream(*restxmlservice.EmptyStreamInput) (*restxmlservice.EmptyStreamOutput, error)
|
||||
EmptyStreamWithContext(aws.Context, *restxmlservice.EmptyStreamInput, ...request.Option) (*restxmlservice.EmptyStreamOutput, error)
|
||||
EmptyStreamRequest(*restxmlservice.EmptyStreamInput) (*request.Request, *restxmlservice.EmptyStreamOutput)
|
||||
|
||||
GetEventStream(*restxmlservice.GetEventStreamInput) (*restxmlservice.GetEventStreamOutput, error)
|
||||
GetEventStreamWithContext(aws.Context, *restxmlservice.GetEventStreamInput, ...request.Option) (*restxmlservice.GetEventStreamOutput, error)
|
||||
GetEventStreamRequest(*restxmlservice.GetEventStreamInput) (*request.Request, *restxmlservice.GetEventStreamOutput)
|
||||
|
||||
OtherOperation(*restxmlservice.OtherOperationInput) (*restxmlservice.OtherOperationOutput, error)
|
||||
OtherOperationWithContext(aws.Context, *restxmlservice.OtherOperationInput, ...request.Option) (*restxmlservice.OtherOperationOutput, error)
|
||||
OtherOperationRequest(*restxmlservice.OtherOperationInput) (*request.Request, *restxmlservice.OtherOperationOutput)
|
||||
}
|
||||
|
||||
var _ RESTXMLServiceAPI = (*restxmlservice.RESTXMLService)(nil)
|
||||
Generated
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package restxmlservice
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
||||
)
|
||||
|
||||
// RESTXMLService provides the API operation methods for making requests to
|
||||
// REST XML Service. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// RESTXMLService methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type RESTXMLService struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "RESTXMLService" // Name of service.
|
||||
EndpointsID = "restxmlservice" // ID to lookup a service endpoint with.
|
||||
ServiceID = "RESTXMLService" // ServiceID is a unique identifer of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the RESTXMLService client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a RESTXMLService client from just a session.
|
||||
// svc := restxmlservice.New(mySession)
|
||||
//
|
||||
// // Create a RESTXMLService client with additional configuration
|
||||
// svc := restxmlservice.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *RESTXMLService {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *RESTXMLService {
|
||||
svc := &RESTXMLService{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "0000-00-00",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(restxml.UnmarshalErrorHandler)
|
||||
|
||||
svc.Handlers.UnmarshalStream.PushBackNamed(restxml.UnmarshalHandler)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a RESTXMLService operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *RESTXMLService) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
Generated
Vendored
+1452
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package rpcservice provides the client and types for making API
|
||||
// requests to RPC Service.
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/RPCService-0000-00-00 for more information on this service.
|
||||
//
|
||||
// See rpcservice package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/rpcservice/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact RPC Service with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the RPC Service client RPCService for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/rpcservice/#New
|
||||
package rpcservice
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package rpcservice
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeExceptionEvent for service response error code
|
||||
// "ExceptionEvent".
|
||||
ErrCodeExceptionEvent = "ExceptionEvent"
|
||||
|
||||
// ErrCodeExceptionEvent2 for service response error code
|
||||
// "ExceptionEvent2".
|
||||
ErrCodeExceptionEvent2 = "ExceptionEvent2"
|
||||
)
|
||||
Generated
Vendored
+578
@@ -0,0 +1,578 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// +build go1.6
|
||||
|
||||
package rpcservice
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamtest"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
)
|
||||
|
||||
var _ time.Time
|
||||
var _ awserr.Error
|
||||
|
||||
func TestEmptyStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
// Trim off response output type pseudo event so only event messages remain.
|
||||
expectEvents = expectEvents[1:]
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEmptyStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockEmptyStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.EmptyStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockEmptyStreamReadEvents() (
|
||||
[]EmptyEventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EmptyEventStreamEvent{
|
||||
&EmptyStreamOutput{},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(jsonrpc.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("initial-response"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
|
||||
},
|
||||
}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
|
||||
func TestGetEventStream_Read(t *testing.T) {
|
||||
expectEvents, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
expectResp := expectEvents[0].(*GetEventStreamOutput)
|
||||
if e, a := expectResp.IntVal, resp.IntVal; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := expectResp.StrVal, resp.StrVal; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
// Trim off response output type pseudo event so only event messages remain.
|
||||
expectEvents = expectEvents[1:]
|
||||
|
||||
var i int
|
||||
for event := range resp.EventStream.Events() {
|
||||
if event == nil {
|
||||
t.Errorf("%d, expect event, got nil", i)
|
||||
}
|
||||
if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEventStream_ReadClose(t *testing.T) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
resp.EventStream.Close()
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
if err := resp.EventStream.Err(); err != nil {
|
||||
t.Errorf("expect no error, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetEventStream_Read(b *testing.B) {
|
||||
_, eventMsgs := mockGetEventStreamReadEvents()
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
for _, msg := range eventMsgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
}
|
||||
stream := &loopReader{source: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
sess := unit.Session
|
||||
svc := New(sess, &aws.Config{
|
||||
Endpoint: aws.String("https://example.com"),
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
})
|
||||
svc.Handlers.Send.Swap(corehandlers.SendHandler.Name,
|
||||
request.NamedHandler{Name: "mockSend",
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(stream),
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create request, %v", err)
|
||||
}
|
||||
defer resp.EventStream.Close()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = resp.EventStream.Err(); err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
event := <-resp.EventStream.Events()
|
||||
if event == nil {
|
||||
b.Fatalf("expect event, got nil, %v, %d", resp.EventStream.Err(), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mockGetEventStreamReadEvents() (
|
||||
[]EventStreamEvent,
|
||||
[]eventstream.Message,
|
||||
) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&GetEventStreamOutput{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
&EmptyEvent{},
|
||||
&ExplicitPayloadEvent{
|
||||
LongVal: aws.Int64(1234),
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
StringVal: aws.String("string value goes here"),
|
||||
},
|
||||
&HeaderOnlyEvent{
|
||||
BlobVal: []byte("blob value goes here"),
|
||||
BoolVal: aws.Bool(true),
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
LongVal: aws.Int64(1234),
|
||||
ShortVal: aws.Int64(12),
|
||||
StringVal: aws.String("string value goes here"),
|
||||
TimeVal: aws.Time(time.Unix(1396594860, 0).UTC()),
|
||||
},
|
||||
&ImplicitPayloadEvent{
|
||||
ByteVal: aws.Int64(1),
|
||||
IntegerVal: aws.Int64(123),
|
||||
ShortVal: aws.Int64(12),
|
||||
},
|
||||
&PayloadOnlyEvent{
|
||||
NestedVal: &NestedShape{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
},
|
||||
&PayloadOnlyBlobEvent{
|
||||
BlobPayload: []byte("blob value goes here"),
|
||||
},
|
||||
&PayloadOnlyStringEvent{
|
||||
StringPayload: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(jsonrpc.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
_ = payloadMarshaler
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("initial-response"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Empty"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ExplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[2].(*ExplicitPayloadEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[2].(*ExplicitPayloadEvent).StringVal),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[2]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("Headers"),
|
||||
},
|
||||
{
|
||||
Name: "BlobVal",
|
||||
Value: eventstream.BytesValue(expectEvents[3].(*HeaderOnlyEvent).BlobVal),
|
||||
},
|
||||
{
|
||||
Name: "BoolVal",
|
||||
Value: eventstream.BoolValue(*expectEvents[3].(*HeaderOnlyEvent).BoolVal),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[3].(*HeaderOnlyEvent).ByteVal)),
|
||||
},
|
||||
{
|
||||
Name: "IntegerVal",
|
||||
Value: eventstream.Int32Value(int32(*expectEvents[3].(*HeaderOnlyEvent).IntegerVal)),
|
||||
},
|
||||
{
|
||||
Name: "LongVal",
|
||||
Value: eventstream.Int64Value(*expectEvents[3].(*HeaderOnlyEvent).LongVal),
|
||||
},
|
||||
{
|
||||
Name: "ShortVal",
|
||||
Value: eventstream.Int16Value(int16(*expectEvents[3].(*HeaderOnlyEvent).ShortVal)),
|
||||
},
|
||||
{
|
||||
Name: "StringVal",
|
||||
Value: eventstream.StringValue(*expectEvents[3].(*HeaderOnlyEvent).StringVal),
|
||||
},
|
||||
{
|
||||
Name: "TimeVal",
|
||||
Value: eventstream.TimestampValue(*expectEvents[3].(*HeaderOnlyEvent).TimeVal),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("ImplicitPayload"),
|
||||
},
|
||||
{
|
||||
Name: "ByteVal",
|
||||
Value: eventstream.Int8Value(int8(*expectEvents[4].(*ImplicitPayloadEvent).ByteVal)),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[4]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnly"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[5]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyBlob"),
|
||||
},
|
||||
},
|
||||
Payload: expectEvents[6].(*PayloadOnlyBlobEvent).BlobPayload,
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("PayloadOnlyString"),
|
||||
},
|
||||
},
|
||||
Payload: []byte(*expectEvents[7].(*PayloadOnlyStringEvent).StringPayload),
|
||||
},
|
||||
}
|
||||
|
||||
return expectEvents, eventMsgs
|
||||
}
|
||||
func TestGetEventStream_ReadException(t *testing.T) {
|
||||
expectEvents := []EventStreamEvent{
|
||||
&GetEventStreamOutput{
|
||||
IntVal: aws.Int64(123),
|
||||
StrVal: aws.String("string value goes here"),
|
||||
},
|
||||
&ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
},
|
||||
}
|
||||
|
||||
var marshalers request.HandlerList
|
||||
marshalers.PushBackNamed(jsonrpc.BuildHandler)
|
||||
payloadMarshaler := protocol.HandlerPayloadMarshal{
|
||||
Marshalers: marshalers,
|
||||
}
|
||||
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventMessageTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.EventTypeHeader,
|
||||
Value: eventstream.StringValue("initial-response"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]),
|
||||
},
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstreamtest.EventExceptionTypeHeader,
|
||||
{
|
||||
Name: eventstreamapi.ExceptionTypeHeader,
|
||||
Value: eventstream.StringValue("Exception"),
|
||||
},
|
||||
},
|
||||
Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[1]),
|
||||
},
|
||||
}
|
||||
|
||||
sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t,
|
||||
eventstreamtest.ServeEventStream{
|
||||
T: t,
|
||||
Events: eventMsgs,
|
||||
},
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
defer cleanupFn()
|
||||
|
||||
svc := New(sess)
|
||||
resp, err := svc.GetEventStream(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error got, %v", err)
|
||||
}
|
||||
|
||||
defer resp.EventStream.Close()
|
||||
|
||||
<-resp.EventStream.Events()
|
||||
|
||||
err = resp.EventStream.Err()
|
||||
if err == nil {
|
||||
t.Fatalf("expect err, got none")
|
||||
}
|
||||
|
||||
expectErr := &ExceptionEvent{
|
||||
IntVal: aws.Int64(123),
|
||||
Message_: aws.String("string value goes here"),
|
||||
}
|
||||
aerr, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
t.Errorf("expect exception, got %T, %#v", err, err)
|
||||
}
|
||||
if e, a := expectErr.Code(), aerr.Code(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := expectErr.Message(), aerr.Message(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := expectErr, aerr; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
var _ awserr.Error = (*ExceptionEvent)(nil)
|
||||
var _ awserr.Error = (*ExceptionEvent2)(nil)
|
||||
|
||||
type loopReader struct {
|
||||
source *bytes.Reader
|
||||
}
|
||||
|
||||
func (c *loopReader) Read(p []byte) (int, error) {
|
||||
if c.source.Len() == 0 {
|
||||
c.source.Seek(0, 0)
|
||||
}
|
||||
|
||||
return c.source.Read(p)
|
||||
}
|
||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package rpcserviceiface provides an interface to enable mocking the RPC Service service client
|
||||
// for testing your code.
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters.
|
||||
package rpcserviceiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/model/api/codegentest/service/rpcservice"
|
||||
)
|
||||
|
||||
// RPCServiceAPI provides an interface to enable mocking the
|
||||
// rpcservice.RPCService service client's API operation,
|
||||
// paginators, and waiters. This make unit testing your code that calls out
|
||||
// to the SDK's service client's calls easier.
|
||||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // RPC Service.
|
||||
// func myFunc(svc rpcserviceiface.RPCServiceAPI) bool {
|
||||
// // Make svc.EmptyStream request
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// sess := session.New()
|
||||
// svc := rpcservice.New(sess)
|
||||
//
|
||||
// myFunc(svc)
|
||||
// }
|
||||
//
|
||||
// In your _test.go file:
|
||||
//
|
||||
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||
// type mockRPCServiceClient struct {
|
||||
// rpcserviceiface.RPCServiceAPI
|
||||
// }
|
||||
// func (m *mockRPCServiceClient) EmptyStream(input *rpcservice.EmptyStreamInput) (*rpcservice.EmptyStreamOutput, error) {
|
||||
// // mock response/functionality
|
||||
// }
|
||||
//
|
||||
// func TestMyFunc(t *testing.T) {
|
||||
// // Setup Test
|
||||
// mockSvc := &mockRPCServiceClient{}
|
||||
//
|
||||
// myfunc(mockSvc)
|
||||
//
|
||||
// // Verify myFunc's functionality
|
||||
// }
|
||||
//
|
||||
// It is important to note that this interface will have breaking changes
|
||||
// when the service model is updated and adds new API operations, paginators,
|
||||
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||
// tooling to generate mocks to satisfy the interfaces.
|
||||
type RPCServiceAPI interface {
|
||||
EmptyStream(*rpcservice.EmptyStreamInput) (*rpcservice.EmptyStreamOutput, error)
|
||||
EmptyStreamWithContext(aws.Context, *rpcservice.EmptyStreamInput, ...request.Option) (*rpcservice.EmptyStreamOutput, error)
|
||||
EmptyStreamRequest(*rpcservice.EmptyStreamInput) (*request.Request, *rpcservice.EmptyStreamOutput)
|
||||
|
||||
GetEventStream(*rpcservice.GetEventStreamInput) (*rpcservice.GetEventStreamOutput, error)
|
||||
GetEventStreamWithContext(aws.Context, *rpcservice.GetEventStreamInput, ...request.Option) (*rpcservice.GetEventStreamOutput, error)
|
||||
GetEventStreamRequest(*rpcservice.GetEventStreamInput) (*request.Request, *rpcservice.GetEventStreamOutput)
|
||||
|
||||
OtherOperation(*rpcservice.OtherOperationInput) (*rpcservice.OtherOperationOutput, error)
|
||||
OtherOperationWithContext(aws.Context, *rpcservice.OtherOperationInput, ...request.Option) (*rpcservice.OtherOperationOutput, error)
|
||||
OtherOperationRequest(*rpcservice.OtherOperationInput) (*request.Request, *rpcservice.OtherOperationOutput)
|
||||
}
|
||||
|
||||
var _ RPCServiceAPI = (*rpcservice.RPCService)(nil)
|
||||
Generated
Vendored
+99
@@ -0,0 +1,99 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package rpcservice
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
)
|
||||
|
||||
// RPCService provides the API operation methods for making requests to
|
||||
// RPC Service. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// RPCService methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type RPCService struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "RPCService" // Name of service.
|
||||
EndpointsID = "rpcservice" // ID to lookup a service endpoint with.
|
||||
ServiceID = "RPCService" // ServiceID is a unique identifer of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the RPCService client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a RPCService client from just a session.
|
||||
// svc := rpcservice.New(mySession)
|
||||
//
|
||||
// // Create a RPCService client with additional configuration
|
||||
// svc := rpcservice.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *RPCService {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *RPCService {
|
||||
svc := &RPCService{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "0000-00-00",
|
||||
JSONVersion: "1.1",
|
||||
TargetPrefix: "RPCService_00000000",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
|
||||
|
||||
svc.Handlers.UnmarshalStream.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a RPCService operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *RPCService) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
+90
-4
@@ -3,7 +3,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
@@ -27,10 +29,24 @@ var mergeServices = map[string]service{
|
||||
},
|
||||
}
|
||||
|
||||
var serviceAliaseNames = map[string]string{
|
||||
"costandusagereportservice": "CostandUsageReportService",
|
||||
"elasticloadbalancing": "ELB",
|
||||
"elasticloadbalancingv2": "ELBV2",
|
||||
"config": "ConfigService",
|
||||
}
|
||||
|
||||
func (a *API) setServiceAliaseName() {
|
||||
if newName, ok := serviceAliaseNames[a.PackageName()]; ok {
|
||||
a.name = newName
|
||||
}
|
||||
}
|
||||
|
||||
// customizationPasses Executes customization logic for the API by package name.
|
||||
func (a *API) customizationPasses() {
|
||||
var svcCustomizations = map[string]func(*API){
|
||||
"s3": s3Customizations,
|
||||
"s3control": s3ControlCustomizations,
|
||||
"cloudfront": cloudfrontCustomizations,
|
||||
"rds": rdsCustomizations,
|
||||
|
||||
@@ -38,6 +54,23 @@ func (a *API) customizationPasses() {
|
||||
// to provide endpoint them selves.
|
||||
"cloudsearchdomain": disableEndpointResolving,
|
||||
"iotdataplane": disableEndpointResolving,
|
||||
|
||||
// MTurk smoke test is invalid. The service requires AWS account to be
|
||||
// linked to Amazon Mechanical Turk Account.
|
||||
"mturk": supressSmokeTest,
|
||||
|
||||
// Backfill the authentication type for cognito identity and sts.
|
||||
// Removes the need for the customizations in these services.
|
||||
"cognitoidentity": backfillAuthType(NoneAuthType,
|
||||
"GetId",
|
||||
"GetOpenIdToken",
|
||||
"UnlinkIdentity",
|
||||
"GetCredentialsForIdentity",
|
||||
),
|
||||
"sts": backfillAuthType(NoneAuthType,
|
||||
"AssumeRoleWithSAML",
|
||||
"AssumeRoleWithWebIdentity",
|
||||
),
|
||||
}
|
||||
|
||||
for k := range mergeServices {
|
||||
@@ -49,13 +82,17 @@ func (a *API) customizationPasses() {
|
||||
}
|
||||
}
|
||||
|
||||
func supressSmokeTest(a *API) {
|
||||
a.SmokeTests.TestCases = []SmokeTestCase{}
|
||||
}
|
||||
|
||||
// s3Customizations customizes the API generation to replace values specific to S3.
|
||||
func s3Customizations(a *API) {
|
||||
var strExpires *Shape
|
||||
|
||||
var keepContentMD5Ref = map[string]struct{}{
|
||||
"PutObjectInput": struct{}{},
|
||||
"UploadPartInput": struct{}{},
|
||||
"PutObjectInput": {},
|
||||
"UploadPartInput": {},
|
||||
}
|
||||
|
||||
for name, s := range a.Shapes {
|
||||
@@ -73,6 +110,22 @@ func s3Customizations(a *API) {
|
||||
}
|
||||
}
|
||||
|
||||
// Decorate member references that are modeled with the wrong type.
|
||||
// Specifically the case where a member was modeled as a string, but is
|
||||
// expected to sent across the wire as a base64 value.
|
||||
//
|
||||
// e.g. S3's SSECustomerKey and CopySourceSSECustomerKey
|
||||
for _, refName := range []string{
|
||||
"SSECustomerKey",
|
||||
"CopySourceSSECustomerKey",
|
||||
} {
|
||||
if ref, ok := s.MemberRefs[refName]; ok {
|
||||
ref.CustomTags = append(ref.CustomTags, ShapeTag{
|
||||
"marshal-as", "blob",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Expires should be a string not time.Time since the format is not
|
||||
// enforced by S3, and any value can be set to this field outside of the SDK.
|
||||
if strings.HasSuffix(name, "Output") {
|
||||
@@ -110,6 +163,22 @@ func s3CustRemoveHeadObjectModeledErrors(a *API) {
|
||||
op.ErrorRefs = []ShapeRef{}
|
||||
}
|
||||
|
||||
// S3 service operations with an AccountId need accessors to be generated for
|
||||
// them so the fields can be dynamically accessed without reflection.
|
||||
func s3ControlCustomizations(a *API) {
|
||||
for opName, op := range a.Operations {
|
||||
// Add moving AccountId into the hostname instead of header.
|
||||
if ref, ok := op.InputRef.Shape.MemberRefs["AccountId"]; ok {
|
||||
if op.Endpoint != nil {
|
||||
fmt.Fprintf(os.Stderr, "S3 Control, %s, model already defining endpoint trait, remove this customization.\n", opName)
|
||||
}
|
||||
|
||||
op.Endpoint = &EndpointTrait{HostPrefix: "{AccountId}."}
|
||||
ref.HostLabel = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cloudfrontCustomizations customized the API generation to replace values
|
||||
// specific to CloudFront.
|
||||
func cloudfrontCustomizations(a *API) {
|
||||
@@ -129,7 +198,7 @@ func mergeServicesCustomizations(a *API) {
|
||||
p := strings.Replace(a.path, info.srcName, info.dstName, -1)
|
||||
|
||||
if info.serviceVersion != "" {
|
||||
index := strings.LastIndex(p, "/")
|
||||
index := strings.LastIndex(p, string(filepath.Separator))
|
||||
files, _ := ioutil.ReadDir(p[:index])
|
||||
if len(files) > 1 {
|
||||
panic("New version was introduced")
|
||||
@@ -145,7 +214,7 @@ func mergeServicesCustomizations(a *API) {
|
||||
|
||||
for n := range a.Shapes {
|
||||
if _, ok := serviceAPI.Shapes[n]; ok {
|
||||
a.Shapes[n].resolvePkg = "github.com/aws/aws-sdk-go/service/" + info.dstName
|
||||
a.Shapes[n].resolvePkg = SDKImportRoot + "/service/" + info.dstName
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,3 +247,20 @@ func rdsCustomizations(a *API) {
|
||||
func disableEndpointResolving(a *API) {
|
||||
a.Metadata.NoResolveEndpoint = true
|
||||
}
|
||||
|
||||
func backfillAuthType(typ AuthType, opNames ...string) func(*API) {
|
||||
return func(a *API) {
|
||||
for _, opName := range opNames {
|
||||
op, ok := a.Operations[opName]
|
||||
if !ok {
|
||||
panic("unable to backfill auth-type for unknown operation " + opName)
|
||||
}
|
||||
if v := op.AuthType; len(v) != 0 {
|
||||
fmt.Fprintf(os.Stderr, "unable to backfill auth-type for %s, already set, %s", opName, v)
|
||||
continue
|
||||
}
|
||||
|
||||
op.AuthType = typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+372
-239
@@ -3,15 +3,17 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
xhtml "golang.org/x/net/html"
|
||||
"golang.org/x/net/html/atom"
|
||||
)
|
||||
|
||||
type apiDocumentation struct {
|
||||
@@ -47,8 +49,13 @@ func (a *API) AttachDocs(filename string) {
|
||||
func (d *apiDocumentation) setup() {
|
||||
d.API.Documentation = docstring(d.Service)
|
||||
|
||||
for op, doc := range d.Operations {
|
||||
d.API.Operations[op].Documentation = docstring(doc)
|
||||
for opName, doc := range d.Operations {
|
||||
if _, ok := d.API.Operations[opName]; !ok {
|
||||
panic(fmt.Sprintf("%s, doc op %q not found in API op set",
|
||||
d.API.name, opName),
|
||||
)
|
||||
}
|
||||
d.API.Operations[opName].Documentation = docstring(doc)
|
||||
}
|
||||
|
||||
for shape, info := range d.Shapes {
|
||||
@@ -108,7 +115,6 @@ func docstring(doc string) string {
|
||||
doc = html.UnescapeString(doc)
|
||||
|
||||
// Replace doc with full name if doc is empty.
|
||||
doc = strings.TrimSpace(doc)
|
||||
if len(doc) == 0 {
|
||||
doc = fullname
|
||||
}
|
||||
@@ -120,17 +126,6 @@ const (
|
||||
indent = " "
|
||||
)
|
||||
|
||||
// style is what we want to prefix a string with.
|
||||
// For instance, <li>Foo</li><li>Bar</li>, will generate
|
||||
// * Foo
|
||||
// * Bar
|
||||
var style = map[string]string{
|
||||
"ul": indent + "* ",
|
||||
"li": indent + "* ",
|
||||
"code": indent,
|
||||
"pre": indent,
|
||||
}
|
||||
|
||||
// commentify converts a string to a Go comment
|
||||
func commentify(doc string) string {
|
||||
if len(doc) == 0 {
|
||||
@@ -155,257 +150,395 @@ func commentify(doc string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// wrap returns a rewritten version of text to have line breaks
|
||||
// at approximately length characters. Line breaks will only be
|
||||
// inserted into whitespace.
|
||||
func wrap(text string, length int, isIndented bool) string {
|
||||
var buf bytes.Buffer
|
||||
var last rune
|
||||
var lastNL bool
|
||||
var col int
|
||||
func wrap(text string, length int) string {
|
||||
var b strings.Builder
|
||||
|
||||
for _, c := range text {
|
||||
switch c {
|
||||
case '\r': // ignore this
|
||||
continue // and also don't track `last`
|
||||
case '\n': // ignore this too, but reset col
|
||||
if col >= length || last == '\n' {
|
||||
buf.WriteString("\n")
|
||||
s := bufio.NewScanner(strings.NewReader(text))
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
|
||||
// cleanup the line's spaces
|
||||
var i int
|
||||
for i = 0; i < len(line); i++ {
|
||||
c := line[i]
|
||||
// Ignore leading spaces, e.g indents.
|
||||
if !(c == ' ' || c == '\t') {
|
||||
break
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
col = 0
|
||||
case ' ', '\t': // opportunity to split
|
||||
if col >= length {
|
||||
buf.WriteByte('\n')
|
||||
col = 0
|
||||
if isIndented {
|
||||
buf.WriteString(indent)
|
||||
col += 3
|
||||
}
|
||||
} else {
|
||||
// We only want to write a leading space if the col is greater than zero.
|
||||
// This will provide the proper spacing for documentation.
|
||||
buf.WriteRune(c)
|
||||
col++ // count column
|
||||
}
|
||||
default:
|
||||
buf.WriteRune(c)
|
||||
col++
|
||||
}
|
||||
lastNL = c == '\n'
|
||||
_ = lastNL
|
||||
last = c
|
||||
line = line[:i] + strings.Join(strings.Fields(line[i:]), " ")
|
||||
splitLine(&b, line, length)
|
||||
}
|
||||
return buf.String()
|
||||
|
||||
return strings.TrimRight(b.String(), "\n")
|
||||
}
|
||||
|
||||
type tagInfo struct {
|
||||
tag string
|
||||
key string
|
||||
val string
|
||||
txt string
|
||||
raw string
|
||||
closingTag bool
|
||||
func splitLine(w stringWriter, line string, length int) {
|
||||
leading := getLeadingWhitespace(line)
|
||||
|
||||
line = line[len(leading):]
|
||||
length -= len(leading)
|
||||
|
||||
const splitOn = " "
|
||||
for len(line) > length {
|
||||
// Find the next whitespace to the length
|
||||
idx := strings.Index(line[length:], splitOn)
|
||||
if idx == -1 {
|
||||
break
|
||||
}
|
||||
offset := length + idx
|
||||
|
||||
if v := line[offset+len(splitOn):]; len(v) == 1 && strings.ContainsAny(v, `,.!?'"`) {
|
||||
// Workaround for long lines with space before the punctuation mark.
|
||||
break
|
||||
}
|
||||
|
||||
w.WriteString(leading)
|
||||
w.WriteString(line[:offset])
|
||||
w.WriteByte('\n')
|
||||
line = strings.TrimLeft(line[offset+len(splitOn):], " \t")
|
||||
}
|
||||
|
||||
if len(line) > 0 {
|
||||
w.WriteString(leading)
|
||||
w.WriteString(line)
|
||||
}
|
||||
// Add the newline back in that was stripped out by scanner.
|
||||
w.WriteByte('\n')
|
||||
}
|
||||
|
||||
func getLeadingWhitespace(v string) string {
|
||||
var o strings.Builder
|
||||
for _, c := range v {
|
||||
if c == ' ' || c == '\t' {
|
||||
o.WriteRune(c)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return o.String()
|
||||
}
|
||||
|
||||
// generateDoc will generate the proper doc string for html encoded or plain text doc entries.
|
||||
func generateDoc(htmlSrc string) string {
|
||||
tokenizer := xhtml.NewTokenizer(strings.NewReader(htmlSrc))
|
||||
tokens := buildTokenArray(tokenizer)
|
||||
scopes := findScopes(tokens)
|
||||
return walk(scopes)
|
||||
var builder strings.Builder
|
||||
if err := encodeHTMLToText(&builder, tokenizer); err != nil {
|
||||
panic(fmt.Sprintf("failed to generated docs, %v", err))
|
||||
}
|
||||
|
||||
return wrap(strings.Trim(builder.String(), "\n"), 72)
|
||||
}
|
||||
|
||||
func buildTokenArray(tokenizer *xhtml.Tokenizer) []tagInfo {
|
||||
tokens := []tagInfo{}
|
||||
for tt := tokenizer.Next(); tt != xhtml.ErrorToken; tt = tokenizer.Next() {
|
||||
switch tt {
|
||||
case xhtml.TextToken:
|
||||
txt := string(tokenizer.Text())
|
||||
if len(tokens) == 0 {
|
||||
info := tagInfo{
|
||||
raw: txt,
|
||||
}
|
||||
tokens = append(tokens, info)
|
||||
}
|
||||
tn, _ := tokenizer.TagName()
|
||||
key, val, _ := tokenizer.TagAttr()
|
||||
info := tagInfo{
|
||||
tag: string(tn),
|
||||
key: string(key),
|
||||
val: string(val),
|
||||
txt: txt,
|
||||
}
|
||||
tokens = append(tokens, info)
|
||||
case xhtml.StartTagToken:
|
||||
tn, _ := tokenizer.TagName()
|
||||
key, val, _ := tokenizer.TagAttr()
|
||||
info := tagInfo{
|
||||
tag: string(tn),
|
||||
key: string(key),
|
||||
val: string(val),
|
||||
}
|
||||
tokens = append(tokens, info)
|
||||
case xhtml.SelfClosingTagToken, xhtml.EndTagToken:
|
||||
tn, _ := tokenizer.TagName()
|
||||
key, val, _ := tokenizer.TagAttr()
|
||||
info := tagInfo{
|
||||
tag: string(tn),
|
||||
key: string(key),
|
||||
val: string(val),
|
||||
closingTag: true,
|
||||
}
|
||||
tokens = append(tokens, info)
|
||||
}
|
||||
}
|
||||
return tokens
|
||||
type stringWriter interface {
|
||||
Write([]byte) (int, error)
|
||||
WriteByte(byte) error
|
||||
WriteRune(rune) (int, error)
|
||||
WriteString(string) (int, error)
|
||||
}
|
||||
|
||||
// walk is used to traverse each scoped block. These scoped
|
||||
// blocks will act as blocked text where we do most of our
|
||||
// text manipulation.
|
||||
func walk(scopes [][]tagInfo) string {
|
||||
doc := ""
|
||||
// Documentation will be chunked by scopes.
|
||||
// Meaning, for each scope will be divided by one or more newlines.
|
||||
for _, scope := range scopes {
|
||||
indentStr, isIndented := priorityIndentation(scope)
|
||||
block := ""
|
||||
href := ""
|
||||
after := false
|
||||
level := 0
|
||||
lastTag := ""
|
||||
for _, token := range scope {
|
||||
if token.closingTag {
|
||||
endl := closeTag(token, level)
|
||||
block += endl
|
||||
level--
|
||||
lastTag = ""
|
||||
} else if token.txt == "" {
|
||||
if token.val != "" {
|
||||
href, after = formatText(token, "")
|
||||
}
|
||||
if level == 1 && isIndented {
|
||||
block += indentStr
|
||||
}
|
||||
level++
|
||||
lastTag = token.tag
|
||||
} else {
|
||||
if token.txt != " " {
|
||||
str, _ := formatText(token, lastTag)
|
||||
block += str
|
||||
if after {
|
||||
block += href
|
||||
after = false
|
||||
}
|
||||
} else {
|
||||
fmt.Println(token.tag)
|
||||
str, _ := formatText(tagInfo{}, lastTag)
|
||||
block += str
|
||||
}
|
||||
func encodeHTMLToText(w stringWriter, z *xhtml.Tokenizer) error {
|
||||
encoder := newHTMLTokenEncoder(w)
|
||||
defer encoder.Flush()
|
||||
|
||||
for {
|
||||
tt := z.Next()
|
||||
if tt == xhtml.ErrorToken {
|
||||
if err := z.Err(); err == io.EOF {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !isIndented {
|
||||
block = strings.TrimPrefix(block, " ")
|
||||
|
||||
if err := encoder.Encode(z.Token()); err != nil {
|
||||
return err
|
||||
}
|
||||
block = wrap(block, 72, isIndented)
|
||||
doc += block
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
// closeTag will divide up the blocks of documentation to be formated properly.
|
||||
func closeTag(token tagInfo, level int) string {
|
||||
switch token.tag {
|
||||
case "pre", "li", "div":
|
||||
return "\n"
|
||||
case "p", "h1", "h2", "h3", "h4", "h5", "h6":
|
||||
return "\n\n"
|
||||
case "code":
|
||||
// indented code is only at the 0th level.
|
||||
if level == 0 {
|
||||
return "\n"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
type htmlTokenHandler interface {
|
||||
OnStartTagToken(xhtml.Token) htmlTokenHandler
|
||||
OnEndTagToken(xhtml.Token, bool)
|
||||
OnSelfClosingTagToken(xhtml.Token)
|
||||
OnTextTagToken(xhtml.Token)
|
||||
}
|
||||
|
||||
// formatText will format any sort of text based off of a tag. It will also return
|
||||
// a boolean to add the string after the text token.
|
||||
func formatText(token tagInfo, lastTag string) (string, bool) {
|
||||
switch token.tag {
|
||||
case "a":
|
||||
if token.val != "" {
|
||||
return fmt.Sprintf(" (%s)", token.val), true
|
||||
}
|
||||
}
|
||||
|
||||
// We don't care about a single space nor no text.
|
||||
if len(token.txt) == 0 || token.txt == " " {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Here we want to indent code blocks that are newlines
|
||||
if lastTag == "code" {
|
||||
// Greater than one, because we don't care about newlines in the beginning
|
||||
block := ""
|
||||
if lines := strings.Split(token.txt, "\n"); len(lines) > 1 {
|
||||
for _, line := range lines {
|
||||
block += indent + line
|
||||
}
|
||||
block += "\n"
|
||||
return block, false
|
||||
}
|
||||
}
|
||||
return token.txt, false
|
||||
type htmlTokenEncoder struct {
|
||||
w stringWriter
|
||||
depth int
|
||||
handlers []tokenHandlerItem
|
||||
baseHandler tokenHandlerItem
|
||||
}
|
||||
|
||||
// This is a parser to check what type of indention is needed.
|
||||
func priorityIndentation(blocks []tagInfo) (string, bool) {
|
||||
if len(blocks) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
v, ok := style[blocks[0].tag]
|
||||
return v, ok
|
||||
type tokenHandlerItem struct {
|
||||
handler htmlTokenHandler
|
||||
depth int
|
||||
}
|
||||
|
||||
// Divides into scopes based off levels.
|
||||
// For instance,
|
||||
// <p>Testing<code>123</code></p><ul><li>Foo</li></ul>
|
||||
// This has 2 scopes, the <p> and <ul>
|
||||
func findScopes(tokens []tagInfo) [][]tagInfo {
|
||||
level := 0
|
||||
scope := []tagInfo{}
|
||||
scopes := [][]tagInfo{}
|
||||
for _, token := range tokens {
|
||||
// we will clear empty tagged tokens from the array
|
||||
txt := strings.TrimSpace(token.txt)
|
||||
tag := strings.TrimSpace(token.tag)
|
||||
if len(txt) == 0 && len(tag) == 0 {
|
||||
continue
|
||||
}
|
||||
func newHTMLTokenEncoder(w stringWriter) *htmlTokenEncoder {
|
||||
baseHandler := newBlockTokenHandler(w)
|
||||
baseHandler.rootBlock = true
|
||||
|
||||
scope = append(scope, token)
|
||||
|
||||
// If it is a closing tag then we check what level
|
||||
// we are on. If it is 0, then that means we have found a
|
||||
// scoped block.
|
||||
if token.closingTag {
|
||||
level--
|
||||
if level == 0 {
|
||||
scopes = append(scopes, scope)
|
||||
scope = []tagInfo{}
|
||||
}
|
||||
// Check opening tags and increment the level
|
||||
} else if token.txt == "" {
|
||||
level++
|
||||
}
|
||||
return &htmlTokenEncoder{
|
||||
w: w,
|
||||
baseHandler: tokenHandlerItem{
|
||||
handler: baseHandler,
|
||||
},
|
||||
}
|
||||
// In this case, we did not run into a closing tag. This would mean
|
||||
// we have plaintext for documentation.
|
||||
if len(scopes) == 0 {
|
||||
scopes = append(scopes, scope)
|
||||
}
|
||||
return scopes
|
||||
}
|
||||
|
||||
func (e *htmlTokenEncoder) Flush() error {
|
||||
e.baseHandler.handler.OnEndTagToken(xhtml.Token{Type: xhtml.TextToken}, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *htmlTokenEncoder) Encode(token xhtml.Token) error {
|
||||
h := e.baseHandler
|
||||
if len(e.handlers) != 0 {
|
||||
h = e.handlers[len(e.handlers)-1]
|
||||
}
|
||||
|
||||
switch token.Type {
|
||||
case xhtml.StartTagToken:
|
||||
e.depth++
|
||||
|
||||
next := h.handler.OnStartTagToken(token)
|
||||
if next != nil {
|
||||
e.handlers = append(e.handlers, tokenHandlerItem{
|
||||
handler: next,
|
||||
depth: e.depth,
|
||||
})
|
||||
}
|
||||
|
||||
case xhtml.EndTagToken:
|
||||
handlerBlockClosing := e.depth == h.depth
|
||||
|
||||
h.handler.OnEndTagToken(token, handlerBlockClosing)
|
||||
|
||||
// Remove all but the root handler as the handler is no longer needed.
|
||||
if handlerBlockClosing {
|
||||
e.handlers = e.handlers[:len(e.handlers)-1]
|
||||
}
|
||||
e.depth--
|
||||
|
||||
case xhtml.SelfClosingTagToken:
|
||||
h.handler.OnSelfClosingTagToken(token)
|
||||
|
||||
case xhtml.TextToken:
|
||||
h.handler.OnTextTagToken(token)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type baseTokenHandler struct {
|
||||
w stringWriter
|
||||
}
|
||||
|
||||
func (e *baseTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler { return nil }
|
||||
func (e *baseTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool) {}
|
||||
func (e *baseTokenHandler) OnSelfClosingTagToken(token xhtml.Token) {}
|
||||
func (e *baseTokenHandler) OnTextTagToken(token xhtml.Token) {
|
||||
e.w.WriteString(token.Data)
|
||||
}
|
||||
|
||||
type blockTokenHandler struct {
|
||||
baseTokenHandler
|
||||
|
||||
rootBlock bool
|
||||
origWriter stringWriter
|
||||
strBuilder *strings.Builder
|
||||
|
||||
started bool
|
||||
newlineBeforeNextBlock bool
|
||||
}
|
||||
|
||||
func newBlockTokenHandler(w stringWriter) *blockTokenHandler {
|
||||
strBuilder := &strings.Builder{}
|
||||
return &blockTokenHandler{
|
||||
origWriter: w,
|
||||
strBuilder: strBuilder,
|
||||
baseTokenHandler: baseTokenHandler{
|
||||
w: strBuilder,
|
||||
},
|
||||
}
|
||||
}
|
||||
func (e *blockTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler {
|
||||
e.started = true
|
||||
if e.newlineBeforeNextBlock {
|
||||
e.w.WriteString("\n")
|
||||
e.newlineBeforeNextBlock = false
|
||||
}
|
||||
|
||||
switch token.DataAtom {
|
||||
case atom.A:
|
||||
return newLinkTokenHandler(e.w, token)
|
||||
case atom.Ul:
|
||||
e.w.WriteString("\n")
|
||||
e.newlineBeforeNextBlock = true
|
||||
return newListTokenHandler(e.w)
|
||||
|
||||
case atom.Div, atom.Dt, atom.P, atom.H1, atom.H2, atom.H3, atom.H4, atom.H5, atom.H6:
|
||||
e.w.WriteString("\n")
|
||||
e.newlineBeforeNextBlock = true
|
||||
return newBlockTokenHandler(e.w)
|
||||
|
||||
case atom.Pre, atom.Code:
|
||||
if e.rootBlock {
|
||||
e.w.WriteString("\n")
|
||||
e.w.WriteString(indent)
|
||||
e.newlineBeforeNextBlock = true
|
||||
}
|
||||
return newBlockTokenHandler(e.w)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (e *blockTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool) {
|
||||
if !blockClosing {
|
||||
return
|
||||
}
|
||||
|
||||
e.origWriter.WriteString(e.strBuilder.String())
|
||||
if e.newlineBeforeNextBlock {
|
||||
e.origWriter.WriteString("\n")
|
||||
e.newlineBeforeNextBlock = false
|
||||
}
|
||||
|
||||
e.strBuilder.Reset()
|
||||
}
|
||||
|
||||
func (e *blockTokenHandler) OnTextTagToken(token xhtml.Token) {
|
||||
if e.newlineBeforeNextBlock {
|
||||
e.w.WriteString("\n")
|
||||
e.newlineBeforeNextBlock = false
|
||||
}
|
||||
if !e.started {
|
||||
token.Data = strings.TrimLeft(token.Data, " \t\n")
|
||||
}
|
||||
if len(token.Data) != 0 {
|
||||
e.started = true
|
||||
}
|
||||
e.baseTokenHandler.OnTextTagToken(token)
|
||||
}
|
||||
|
||||
type linkTokenHandler struct {
|
||||
baseTokenHandler
|
||||
linkToken xhtml.Token
|
||||
}
|
||||
|
||||
func newLinkTokenHandler(w stringWriter, token xhtml.Token) *linkTokenHandler {
|
||||
return &linkTokenHandler{
|
||||
baseTokenHandler: baseTokenHandler{
|
||||
w: w,
|
||||
},
|
||||
linkToken: token,
|
||||
}
|
||||
}
|
||||
func (e *linkTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool) {
|
||||
if !blockClosing {
|
||||
return
|
||||
}
|
||||
|
||||
if href, ok := getHTMLTokenAttr(e.linkToken.Attr, "href"); ok && len(href) != 0 {
|
||||
fmt.Fprintf(e.w, " (%s)", strings.TrimSpace(href))
|
||||
}
|
||||
}
|
||||
|
||||
type listTokenHandler struct {
|
||||
baseTokenHandler
|
||||
|
||||
items int
|
||||
}
|
||||
|
||||
func newListTokenHandler(w stringWriter) *listTokenHandler {
|
||||
return &listTokenHandler{
|
||||
baseTokenHandler: baseTokenHandler{
|
||||
w: w,
|
||||
},
|
||||
}
|
||||
}
|
||||
func (e *listTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler {
|
||||
switch token.DataAtom {
|
||||
case atom.Li:
|
||||
if e.items >= 1 {
|
||||
e.w.WriteString("\n\n")
|
||||
}
|
||||
e.items++
|
||||
return newListItemTokenHandler(e.w)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *listTokenHandler) OnTextTagToken(token xhtml.Token) {
|
||||
// Squash whitespace between list and items
|
||||
}
|
||||
|
||||
type listItemTokenHandler struct {
|
||||
baseTokenHandler
|
||||
|
||||
origWriter stringWriter
|
||||
strBuilder *strings.Builder
|
||||
}
|
||||
|
||||
func newListItemTokenHandler(w stringWriter) *listItemTokenHandler {
|
||||
strBuilder := &strings.Builder{}
|
||||
return &listItemTokenHandler{
|
||||
origWriter: w,
|
||||
strBuilder: strBuilder,
|
||||
baseTokenHandler: baseTokenHandler{
|
||||
w: strBuilder,
|
||||
},
|
||||
}
|
||||
}
|
||||
func (e *listItemTokenHandler) OnStartTagToken(token xhtml.Token) htmlTokenHandler {
|
||||
switch token.DataAtom {
|
||||
case atom.P:
|
||||
return newBlockTokenHandler(e.w)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (e *listItemTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool) {
|
||||
if !blockClosing {
|
||||
return
|
||||
}
|
||||
|
||||
e.origWriter.WriteString(indent + "* ")
|
||||
e.origWriter.WriteString(strings.TrimSpace(e.strBuilder.String()))
|
||||
}
|
||||
|
||||
type trimSpaceTokenHandler struct {
|
||||
baseTokenHandler
|
||||
|
||||
origWriter stringWriter
|
||||
strBuilder *strings.Builder
|
||||
}
|
||||
|
||||
func newTrimSpaceTokenHandler(w stringWriter) *trimSpaceTokenHandler {
|
||||
strBuilder := &strings.Builder{}
|
||||
return &trimSpaceTokenHandler{
|
||||
origWriter: w,
|
||||
strBuilder: strBuilder,
|
||||
baseTokenHandler: baseTokenHandler{
|
||||
w: strBuilder,
|
||||
},
|
||||
}
|
||||
}
|
||||
func (e *trimSpaceTokenHandler) OnEndTagToken(token xhtml.Token, blockClosing bool) {
|
||||
if !blockClosing {
|
||||
return
|
||||
}
|
||||
|
||||
e.origWriter.WriteString(strings.TrimSpace(e.strBuilder.String()))
|
||||
}
|
||||
|
||||
func getHTMLTokenAttr(attr []xhtml.Attribute, name string) (string, bool) {
|
||||
for _, a := range attr {
|
||||
if strings.EqualFold(a.Key, name) {
|
||||
return a.Val, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
+71
-90
@@ -1,4 +1,4 @@
|
||||
// +build 1.6,codegen
|
||||
// +build go1.8,codegen
|
||||
|
||||
package api
|
||||
|
||||
@@ -6,95 +6,76 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNonHTMLDocGen(t *testing.T) {
|
||||
doc := "Testing 1 2 3"
|
||||
expected := "// Testing 1 2 3\n"
|
||||
doc = docstring(doc)
|
||||
func TestDocstring(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
In string
|
||||
Expect string
|
||||
}{
|
||||
"non HTML": {
|
||||
In: "Testing 1 2 3",
|
||||
Expect: "// Testing 1 2 3",
|
||||
},
|
||||
"link": {
|
||||
In: `<a href="https://example.com">a link</a>`,
|
||||
Expect: "// a link (https://example.com)",
|
||||
},
|
||||
"link with space": {
|
||||
In: `<a href=" https://example.com">a link</a>`,
|
||||
Expect: "// a link (https://example.com)",
|
||||
},
|
||||
"list HTML 01": {
|
||||
In: "<ul><li>Testing 1 2 3</li> <li>FooBar</li></ul>",
|
||||
Expect: "// * Testing 1 2 3\n// \n// * FooBar",
|
||||
},
|
||||
"list HTML 02": {
|
||||
In: "<ul> <li>Testing 1 2 3</li> <li>FooBar</li> </ul>",
|
||||
Expect: "// * Testing 1 2 3\n// \n// * FooBar",
|
||||
},
|
||||
"list HTML leading spaces": {
|
||||
In: " <ul> <li>Testing 1 2 3</li> <li>FooBar</li> </ul>",
|
||||
Expect: "// * Testing 1 2 3\n// \n// * FooBar",
|
||||
},
|
||||
"list HTML paragraph": {
|
||||
In: "<ul> <li> <p>Testing 1 2 3</p> </li><li> <p>FooBar</p></li></ul>",
|
||||
Expect: "// * Testing 1 2 3\n// \n// * FooBar",
|
||||
},
|
||||
"inline code HTML": {
|
||||
In: "<ul> <li><code>Testing</code>: 1 2 3</li> <li>FooBar</li> </ul>",
|
||||
Expect: "// * Testing: 1 2 3\n// \n// * FooBar",
|
||||
},
|
||||
"complex list paragraph": {
|
||||
In: "<ul> <li><p><code>FOO</code> Bar</p></li><li><p><code>Xyz</code> ABC</p></li></ul>",
|
||||
Expect: "// * FOO Bar\n// \n// * Xyz ABC",
|
||||
},
|
||||
"inline code in paragraph": {
|
||||
In: "<p><code>Testing</code>: 1 2 3</p>",
|
||||
Expect: "// Testing: 1 2 3",
|
||||
},
|
||||
"root pre": {
|
||||
In: "<pre><code>Testing</code></pre>",
|
||||
Expect: "// Testing",
|
||||
},
|
||||
"paragraph": {
|
||||
In: "<p>Testing 1 2 3</p>",
|
||||
Expect: "// Testing 1 2 3",
|
||||
},
|
||||
"wrap lines": {
|
||||
In: "<span data-target-type=\"operation\" data-service=\"secretsmanager\" data-target=\"CreateSecret\">CreateSecret</span> <span data-target-type=\"structure\" data-service=\"secretsmanager\" data-target=\"SecretListEntry\">SecretListEntry</span> <span data-target-type=\"structure\" data-service=\"secretsmanager\" data-target=\"CreateSecret$SecretName\">SecretName</span> <span data-target-type=\"structure\" data-service=\"secretsmanager\" data-target=\"SecretListEntry$KmsKeyId\">KmsKeyId</span>",
|
||||
Expect: "// CreateSecret SecretListEntry SecretName KmsKeyId",
|
||||
},
|
||||
"links with spaces": {
|
||||
In: "<p> Deletes the replication configuration from the bucket. For information about replication configuration, see <a href=\" https://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html\">Cross-Region Replication (CRR)</a> in the <i>Amazon S3 Developer Guide</i>. </p>",
|
||||
Expect: "// Deletes the replication configuration from the bucket. For information about\n// replication configuration, see Cross-Region Replication (CRR) (https://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html)\n// in the Amazon S3 Developer Guide.",
|
||||
},
|
||||
}
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListsHTMLDocGen(t *testing.T) {
|
||||
doc := "<ul><li>Testing 1 2 3</li> <li>FooBar</li></ul>"
|
||||
expected := "// * Testing 1 2 3\n// * FooBar\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
|
||||
doc = "<ul> <li>Testing 1 2 3</li> <li>FooBar</li> </ul>"
|
||||
expected = "// * Testing 1 2 3\n// * FooBar\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
|
||||
// Test leading spaces
|
||||
doc = " <ul> <li>Testing 1 2 3</li> <li>FooBar</li> </ul>"
|
||||
doc = docstring(doc)
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
|
||||
// Paragraph check
|
||||
doc = "<ul> <li> <p>Testing 1 2 3</p> </li><li> <p>FooBar</p></li></ul>"
|
||||
expected = "// * Testing 1 2 3\n// \n// * FooBar\n"
|
||||
doc = docstring(doc)
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInlineCodeHTMLDocGen(t *testing.T) {
|
||||
doc := "<ul> <li><code>Testing</code>: 1 2 3</li> <li>FooBar</li> </ul>"
|
||||
expected := "// * Testing: 1 2 3\n// * FooBar\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInlineCodeInParagraphHTMLDocGen(t *testing.T) {
|
||||
doc := "<p><code>Testing</code>: 1 2 3</p>"
|
||||
expected := "// Testing: 1 2 3\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyPREInlineCodeHTMLDocGen(t *testing.T) {
|
||||
doc := "<pre><code>Testing</code></pre>"
|
||||
expected := "// Testing\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParagraph(t *testing.T) {
|
||||
doc := "<p>Testing 1 2 3</p>"
|
||||
expected := "// Testing 1 2 3\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComplexListParagraphCode(t *testing.T) {
|
||||
doc := "<ul> <li><p><code>FOO</code> Bar</p></li><li><p><code>Xyz</code> ABC</p></li></ul>"
|
||||
expected := "// * FOO Bar\n// \n// * Xyz ABC\n"
|
||||
doc = docstring(doc)
|
||||
|
||||
if expected != doc {
|
||||
t.Errorf("Expected %s, but received %s", expected, doc)
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Log("Input", c.In)
|
||||
actual := docstring(c.In)
|
||||
if e, a := c.Expect, actual; e != a {
|
||||
t.Errorf("expect %q, got %q", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func setupEndpointHostPrefix(op *Operation) {
|
||||
op.API.AddSDKImport("private/protocol")
|
||||
|
||||
buildHandler := fmt.Sprintf("protocol.NewHostPrefixHandler(%q, ",
|
||||
op.Endpoint.HostPrefix)
|
||||
|
||||
if op.InputRef.Shape.HasHostLabelMembers() {
|
||||
buildHandler += "input.hostLabels"
|
||||
} else {
|
||||
buildHandler += "nil"
|
||||
}
|
||||
|
||||
buildHandler += ")"
|
||||
|
||||
op.CustomBuildHandlers = append(op.CustomBuildHandlers,
|
||||
buildHandler,
|
||||
"protocol.ValidateEndpointHostHandler",
|
||||
)
|
||||
}
|
||||
|
||||
// HasHostLabelMembers returns true if the shape contains any members which are
|
||||
// decorated with the hostLabel trait.
|
||||
func (s *Shape) HasHostLabelMembers() bool {
|
||||
for _, ref := range s.MemberRefs {
|
||||
if ref.HostLabel {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var hostLabelsShapeTmpl = template.Must(
|
||||
template.New("hostLabelsShapeTmpl").
|
||||
Parse(hostLabelsShapeTmplDef),
|
||||
)
|
||||
|
||||
const hostLabelsShapeTmplDef = `
|
||||
{{- define "hostLabelsShapeTmpl" }}
|
||||
func (s *{{ $.ShapeName }}) hostLabels() map[string]string {
|
||||
return map[string]string{
|
||||
{{- range $name, $ref := $.MemberRefs }}
|
||||
{{- if $ref.HostLabel }}
|
||||
"{{ $name }}": aws.StringValue(s.{{ $name }}),
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
`
|
||||
+1165
-9
File diff suppressed because it is too large
Load Diff
-79
@@ -1,79 +0,0 @@
|
||||
// +build go1.6,codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSuppressEventStream(t *testing.T) {
|
||||
cases := []struct {
|
||||
API *API
|
||||
Ops []string
|
||||
Shapes []string
|
||||
}{
|
||||
{
|
||||
API: &API{
|
||||
Operations: map[string]*Operation{
|
||||
"abc": {
|
||||
InputRef: ShapeRef{
|
||||
ShapeName: "abcRequest",
|
||||
},
|
||||
OutputRef: ShapeRef{
|
||||
ShapeName: "abcResponse",
|
||||
},
|
||||
},
|
||||
"eventStreamOp": {
|
||||
InputRef: ShapeRef{
|
||||
ShapeName: "eventStreamOpRequest",
|
||||
},
|
||||
OutputRef: ShapeRef{
|
||||
ShapeName: "eventStreamOpResponse",
|
||||
},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"abcRequest": {},
|
||||
"abcResponse": {},
|
||||
"eventStreamOpRequest": {},
|
||||
"eventStreamOpResponse": {
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"eventStreamShape": {
|
||||
ShapeName: "eventStreamShape",
|
||||
},
|
||||
},
|
||||
},
|
||||
"eventStreamShape": {
|
||||
IsEventStream: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Ops: []string{"Abc"},
|
||||
Shapes: []string{"AbcInput", "AbcOutput"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
c.API.Setup()
|
||||
if e, a := c.Ops, c.API.OperationNames(); !stringsEqual(e, a) {
|
||||
t.Errorf("expect %v ops, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := c.Shapes, c.API.ShapeNames(); !stringsEqual(e, a) {
|
||||
t.Errorf("expect %v ops, got %v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stringsEqual(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
+7
-6
@@ -54,14 +54,12 @@ var exampleCustomizations = map[string]template.FuncMap{}
|
||||
|
||||
var exampleTmpls = template.Must(template.New("example").Funcs(exampleFuncMap).Parse(`
|
||||
{{ generateTypes . }}
|
||||
{{ commentify (wrap .Title 80 false) }}
|
||||
{{ commentify (wrap .Title 80) }}
|
||||
//
|
||||
{{ commentify (wrap .Description 80 false) }}
|
||||
{{ commentify (wrap .Description 80) }}
|
||||
func Example{{ .API.StructName }}_{{ .MethodName }}() {
|
||||
svc := {{ .API.PackageName }}.New(session.New())
|
||||
input := &{{ .Operation.InputRef.Shape.GoTypeWithPkgNameElem }} {
|
||||
{{ generateExampleInput . -}}
|
||||
}
|
||||
input := {{ generateExampleInput . }}
|
||||
|
||||
result, err := svc.{{ .OperationName }}(input)
|
||||
if err != nil {
|
||||
@@ -130,7 +128,10 @@ func (ex Example) GoCode() string {
|
||||
|
||||
func generateExampleInput(ex Example) string {
|
||||
if ex.Operation.HasInput() {
|
||||
return ex.Builder.BuildShape(&ex.Operation.InputRef, ex.Input, false)
|
||||
return fmt.Sprintf("&%s{\n%s\n}",
|
||||
ex.Builder.GoType(&ex.Operation.InputRef, true),
|
||||
ex.Builder.BuildShape(&ex.Operation.InputRef, ex.Input, false),
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
+4
-4
@@ -220,10 +220,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/fooservice"
|
||||
"` + SDKImportRoot + `/aws"
|
||||
"` + SDKImportRoot + `/aws/awserr"
|
||||
"` + SDKImportRoot + `/aws/session"
|
||||
"` + SDKImportRoot + `/service/fooservice"
|
||||
)
|
||||
|
||||
var _ time.Duration
|
||||
|
||||
+9
-204
@@ -2,221 +2,26 @@
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type examplesBuilder interface {
|
||||
BuildShape(*ShapeRef, map[string]interface{}, bool) string
|
||||
BuildList(string, string, *ShapeRef, []interface{}) string
|
||||
BuildComplex(string, string, *ShapeRef, map[string]interface{}) string
|
||||
GoType(*ShapeRef, bool) string
|
||||
Imports(*API) string
|
||||
}
|
||||
|
||||
type defaultExamplesBuilder struct{}
|
||||
|
||||
// BuildShape will recursively build the referenced shape based on the json object
|
||||
// provided.
|
||||
// isMap will dictate how the field name is specified. If isMap is true, we will expect
|
||||
// the member name to be quotes like "Foo".
|
||||
func (builder defaultExamplesBuilder) BuildShape(ref *ShapeRef, shapes map[string]interface{}, isMap bool) string {
|
||||
order := make([]string, len(shapes))
|
||||
for k := range shapes {
|
||||
order = append(order, k)
|
||||
}
|
||||
sort.Strings(order)
|
||||
|
||||
ret := ""
|
||||
for _, name := range order {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
shape := shapes[name]
|
||||
|
||||
// If the shape isn't a map, we want to export the value, since every field
|
||||
// defined in our shapes are exported.
|
||||
if len(name) > 0 && !isMap && strings.ToLower(name[0:1]) == name[0:1] {
|
||||
name = strings.Title(name)
|
||||
}
|
||||
|
||||
memName := name
|
||||
passRef := ref.Shape.MemberRefs[name]
|
||||
|
||||
if isMap {
|
||||
memName = fmt.Sprintf("%q", memName)
|
||||
passRef = &ref.Shape.ValueRef
|
||||
}
|
||||
|
||||
switch v := shape.(type) {
|
||||
case map[string]interface{}:
|
||||
ret += builder.BuildComplex(name, memName, passRef, v)
|
||||
case []interface{}:
|
||||
ret += builder.BuildList(name, memName, passRef, v)
|
||||
default:
|
||||
ret += builder.BuildScalar(name, memName, passRef, v, ref.Shape.Payload == name)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// BuildList will construct a list shape based off the service's definition
|
||||
// of that list.
|
||||
func (builder defaultExamplesBuilder) BuildList(name, memName string, ref *ShapeRef, v []interface{}) string {
|
||||
ret := ""
|
||||
|
||||
if len(v) == 0 || ref == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
passRef := &ref.Shape.MemberRef
|
||||
ret += fmt.Sprintf("%s: %s {\n", memName, builder.GoType(ref, false))
|
||||
ret += builder.buildListElements(passRef, v)
|
||||
ret += "},\n"
|
||||
return ret
|
||||
}
|
||||
|
||||
func (builder defaultExamplesBuilder) buildListElements(ref *ShapeRef, v []interface{}) string {
|
||||
if len(v) == 0 || ref == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
ret := ""
|
||||
format := ""
|
||||
isComplex := false
|
||||
isList := false
|
||||
|
||||
// get format for atomic type. If it is not an atomic type,
|
||||
// get the element.
|
||||
switch v[0].(type) {
|
||||
case string:
|
||||
format = "%s"
|
||||
case bool:
|
||||
format = "%t"
|
||||
case float64:
|
||||
switch ref.Shape.Type {
|
||||
case "integer", "int64", "long":
|
||||
format = "%d"
|
||||
default:
|
||||
format = "%f"
|
||||
}
|
||||
case []interface{}:
|
||||
isList = true
|
||||
case map[string]interface{}:
|
||||
isComplex = true
|
||||
}
|
||||
|
||||
for _, elem := range v {
|
||||
if isComplex {
|
||||
ret += fmt.Sprintf("{\n%s\n},\n", builder.BuildShape(ref, elem.(map[string]interface{}), ref.Shape.Type == "map"))
|
||||
} else if isList {
|
||||
ret += fmt.Sprintf("{\n%s\n},\n", builder.buildListElements(&ref.Shape.MemberRef, elem.([]interface{})))
|
||||
} else {
|
||||
switch ref.Shape.Type {
|
||||
case "integer", "int64", "long":
|
||||
elem = int(elem.(float64))
|
||||
}
|
||||
ret += fmt.Sprintf("%s,\n", getValue(ref.Shape.Type, fmt.Sprintf(format, elem)))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// BuildScalar will build atomic Go types.
|
||||
func (builder defaultExamplesBuilder) BuildScalar(name, memName string, ref *ShapeRef, shape interface{}, isPayload bool) string {
|
||||
if ref == nil || ref.Shape == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch v := shape.(type) {
|
||||
case bool:
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%t", v))
|
||||
case int:
|
||||
if ref.Shape.Type == "timestamp" {
|
||||
return parseTimeString(ref, memName, fmt.Sprintf("%d", v))
|
||||
}
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%d", v))
|
||||
case float64:
|
||||
dataType := ref.Shape.Type
|
||||
if dataType == "integer" || dataType == "int64" || dataType == "long" {
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%d", int(shape.(float64))))
|
||||
}
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%f", v))
|
||||
case string:
|
||||
t := ref.Shape.Type
|
||||
switch t {
|
||||
case "timestamp":
|
||||
return parseTimeString(ref, memName, fmt.Sprintf("%s", v))
|
||||
case "blob":
|
||||
if (ref.Streaming || ref.Shape.Streaming) && isPayload {
|
||||
return fmt.Sprintf("%s: aws.ReadSeekCloser(strings.NewReader(%q)),\n", memName, v)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s: []byte(%q),\n", memName, v)
|
||||
default:
|
||||
return convertToCorrectType(memName, t, v)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("Unsupported scalar type: %v", reflect.TypeOf(v)))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (builder defaultExamplesBuilder) BuildComplex(name, memName string, ref *ShapeRef, v map[string]interface{}) string {
|
||||
switch ref.Shape.Type {
|
||||
case "structure":
|
||||
return fmt.Sprintf(`%s: &%s{
|
||||
%s
|
||||
},
|
||||
`, memName, builder.GoType(ref, true), builder.BuildShape(ref, v, false))
|
||||
case "map":
|
||||
return fmt.Sprintf(`%s: %s{
|
||||
%s
|
||||
},
|
||||
`, name, builder.GoType(ref, false), builder.BuildShape(ref, v, true))
|
||||
default:
|
||||
panic(fmt.Sprintf("Expected complex type but recieved %q", ref.Shape.Type))
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (builder defaultExamplesBuilder) GoType(ref *ShapeRef, elem bool) string {
|
||||
if ref.Shape.Type != "structure" && ref.Shape.Type != "list" && ref.Shape.Type != "map" {
|
||||
return ref.GoTypeWithPkgName()
|
||||
}
|
||||
|
||||
prefix := ""
|
||||
if ref.Shape.Type == "list" {
|
||||
ref = &ref.Shape.MemberRef
|
||||
prefix = "[]"
|
||||
}
|
||||
|
||||
name := ref.GoTypeWithPkgName()
|
||||
if elem {
|
||||
name = ref.GoTypeElem()
|
||||
if !strings.Contains(name, ".") {
|
||||
name = strings.Join([]string{ref.API.PackageName(), name}, ".")
|
||||
}
|
||||
}
|
||||
|
||||
return prefix + name
|
||||
type defaultExamplesBuilder struct {
|
||||
ShapeValueBuilder
|
||||
}
|
||||
|
||||
func (builder defaultExamplesBuilder) Imports(a *API) string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString(`"fmt"
|
||||
return `"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
`)
|
||||
|
||||
buf.WriteString(fmt.Sprintf("\"%s/%s\"", "github.com/aws/aws-sdk-go/service", a.PackageName()))
|
||||
return buf.String()
|
||||
"` + SDKImportRoot + `/aws"
|
||||
"` + SDKImportRoot + `/aws/awserr"
|
||||
"` + SDKImportRoot + `/aws/session"
|
||||
"` + a.ImportPath() + `"
|
||||
`
|
||||
}
|
||||
|
||||
Generated
Vendored
+7
-15
@@ -2,27 +2,19 @@
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type wafregionalExamplesBuilder struct {
|
||||
defaultExamplesBuilder
|
||||
}
|
||||
|
||||
func (builder wafregionalExamplesBuilder) Imports(a *API) string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString(`"fmt"
|
||||
return `"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/waf"
|
||||
`)
|
||||
|
||||
buf.WriteString(fmt.Sprintf("\"%s/%s\"", "github.com/aws/aws-sdk-go/service", a.PackageName()))
|
||||
return buf.String()
|
||||
"` + SDKImportRoot + `/aws"
|
||||
"` + SDKImportRoot + `/aws/awserr"
|
||||
"` + SDKImportRoot + `/aws/session"
|
||||
"` + SDKImportRoot + `/service/waf"
|
||||
"` + SDKImportRoot + `/service/` + a.PackageName() + `"
|
||||
`
|
||||
}
|
||||
|
||||
+92
-4
@@ -1,13 +1,34 @@
|
||||
package api
|
||||
|
||||
type persistAPIType struct {
|
||||
output bool
|
||||
input bool
|
||||
}
|
||||
|
||||
type persistAPITypes map[string]map[string]persistAPIType
|
||||
|
||||
func (ts persistAPITypes) Lookup(serviceName, opName string) persistAPIType {
|
||||
service, ok := shamelist[serviceName]
|
||||
if !ok {
|
||||
return persistAPIType{}
|
||||
}
|
||||
|
||||
return service[opName]
|
||||
}
|
||||
|
||||
func (ts persistAPITypes) Input(serviceName, opName string) bool {
|
||||
return ts.Lookup(serviceName, opName).input
|
||||
}
|
||||
|
||||
func (ts persistAPITypes) Output(serviceName, opName string) bool {
|
||||
return ts.Lookup(serviceName, opName).output
|
||||
}
|
||||
|
||||
// shamelist is used to not rename certain operation's input and output shapes.
|
||||
// We need to maintain backwards compatibility with pre-existing services. Since
|
||||
// not generating unique input/output shapes is not desired, we will generate
|
||||
// unique input/output shapes for new operations.
|
||||
var shamelist = map[string]map[string]struct {
|
||||
input bool
|
||||
output bool
|
||||
}{
|
||||
var shamelist = persistAPITypes{
|
||||
"APIGateway": {
|
||||
"CreateApiKey": {
|
||||
output: true,
|
||||
@@ -352,6 +373,11 @@ var shamelist = map[string]map[string]struct {
|
||||
output: true,
|
||||
},
|
||||
},
|
||||
"ElasticTranscoder": {
|
||||
"CreateJob": {
|
||||
output: true,
|
||||
},
|
||||
},
|
||||
"Glacier": {
|
||||
"DescribeJob": {
|
||||
output: true,
|
||||
@@ -431,6 +457,54 @@ var shamelist = map[string]map[string]struct {
|
||||
output: true,
|
||||
},
|
||||
},
|
||||
"MQ": {
|
||||
"CreateBroker": {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
"CreateConfiguration": {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
"CreateUser": {
|
||||
input: true,
|
||||
},
|
||||
"DeleteBroker": {
|
||||
output: true,
|
||||
},
|
||||
"DescribeBroker": {
|
||||
output: true,
|
||||
},
|
||||
"DescribeUser": {
|
||||
output: true,
|
||||
},
|
||||
"DescribeConfigurationRevision": {
|
||||
output: true,
|
||||
},
|
||||
"ListBrokers": {
|
||||
output: true,
|
||||
},
|
||||
"ListConfigurations": {
|
||||
output: true,
|
||||
},
|
||||
"ListConfigurationRevisions": {
|
||||
output: true,
|
||||
},
|
||||
"ListUsers": {
|
||||
output: true,
|
||||
},
|
||||
"UpdateBroker": {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
"UpdateConfiguration": {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
"UpdateUser": {
|
||||
input: true,
|
||||
},
|
||||
},
|
||||
"RDS": {
|
||||
"ModifyDBClusterParameterGroup": {
|
||||
output: true,
|
||||
@@ -472,6 +546,20 @@ var shamelist = map[string]map[string]struct {
|
||||
output: true,
|
||||
},
|
||||
},
|
||||
"ServerlessApplicationRepository": {
|
||||
"CreateApplication": {
|
||||
input: true,
|
||||
},
|
||||
"CreateApplicationVersion": {
|
||||
input: true,
|
||||
},
|
||||
"CreateCloudFormationChangeSet": {
|
||||
input: true,
|
||||
},
|
||||
"UpdateApplication": {
|
||||
input: true,
|
||||
},
|
||||
},
|
||||
"SWF": {
|
||||
"CountClosedWorkflowExecutions": {
|
||||
output: true,
|
||||
|
||||
+140
-6
@@ -7,8 +7,136 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// APIs provides a set of API models loaded by API package name.
|
||||
type APIs map[string]*API
|
||||
|
||||
// LoadAPIs loads the API model files from disk returning the map of API
|
||||
// package. Returns error if multiple API model resolve to the same package
|
||||
// name.
|
||||
func LoadAPIs(modelPaths []string, baseImport string) (APIs, error) {
|
||||
apis := APIs{}
|
||||
for _, modelPath := range modelPaths {
|
||||
a, err := loadAPI(modelPath, baseImport)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load API, %v, %v", modelPath, err)
|
||||
}
|
||||
importPath := a.ImportPath()
|
||||
if _, ok := apis[importPath]; ok {
|
||||
return nil, fmt.Errorf(
|
||||
"package names must be unique attempted to load %v twice. Second model file: %v",
|
||||
importPath, modelPath)
|
||||
}
|
||||
apis[importPath] = a
|
||||
}
|
||||
|
||||
return apis, nil
|
||||
}
|
||||
|
||||
func loadAPI(modelPath, baseImport string) (*API, error) {
|
||||
a := &API{
|
||||
BaseImportPath: baseImport,
|
||||
BaseCrosslinkURL: "https://docs.aws.amazon.com",
|
||||
}
|
||||
|
||||
modelFile := filepath.Base(modelPath)
|
||||
modelDir := filepath.Dir(modelPath)
|
||||
err := attachModelFiles(modelDir,
|
||||
modelLoader{modelFile, a.Attach, true},
|
||||
modelLoader{"docs-2.json", a.AttachDocs, false},
|
||||
modelLoader{"paginators-1.json", a.AttachPaginators, false},
|
||||
modelLoader{"waiters-2.json", a.AttachWaiters, false},
|
||||
modelLoader{"examples-1.json", a.AttachExamples, false},
|
||||
modelLoader{"smoke.json", a.AttachSmokeTests, false},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
a.Setup()
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
type modelLoader struct {
|
||||
Filename string
|
||||
Loader func(string)
|
||||
Required bool
|
||||
}
|
||||
|
||||
func attachModelFiles(modelPath string, modelFiles ...modelLoader) error {
|
||||
for _, m := range modelFiles {
|
||||
filepath := filepath.Join(modelPath, m.Filename)
|
||||
_, err := os.Stat(filepath)
|
||||
if os.IsNotExist(err) && !m.Required {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to load model file %v, %v", m.Filename, err)
|
||||
}
|
||||
|
||||
m.Loader(filepath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExpandModelGlobPath returns a slice of model paths expanded from the glob
|
||||
// pattern passed in. Returns the path of the model file to be loaded. Includes
|
||||
// all versions of a service model.
|
||||
//
|
||||
// e.g:
|
||||
// models/apis/*/*/api-2.json
|
||||
//
|
||||
// Or with specific model file:
|
||||
// models/apis/service/version/api-2.json
|
||||
func ExpandModelGlobPath(globs ...string) ([]string, error) {
|
||||
modelPaths := []string{}
|
||||
|
||||
for _, g := range globs {
|
||||
filepaths, err := filepath.Glob(g)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range filepaths {
|
||||
modelPaths = append(modelPaths, p)
|
||||
}
|
||||
}
|
||||
|
||||
return modelPaths, nil
|
||||
}
|
||||
|
||||
// TrimModelServiceVersions sorts the model paths by service version then
|
||||
// returns recent model versions, and model version excluded.
|
||||
//
|
||||
// Uses the third from last path element to determine unique service. Only one
|
||||
// service version will be included.
|
||||
//
|
||||
// models/apis/service/version/api-2.json
|
||||
func TrimModelServiceVersions(modelPaths []string) (include, exclude []string) {
|
||||
sort.Strings(modelPaths)
|
||||
|
||||
// Remove old API versions from list
|
||||
m := map[string]struct{}{}
|
||||
for i := len(modelPaths) - 1; i >= 0; i-- {
|
||||
// service name is 2nd-to-last component
|
||||
parts := strings.Split(modelPaths[i], string(filepath.Separator))
|
||||
svc := parts[len(parts)-3]
|
||||
|
||||
if _, ok := m[svc]; ok {
|
||||
// Removed unused service version
|
||||
exclude = append(exclude, modelPaths[i])
|
||||
continue
|
||||
}
|
||||
include = append(include, modelPaths[i])
|
||||
m[svc] = struct{}{}
|
||||
}
|
||||
|
||||
return include, exclude
|
||||
}
|
||||
|
||||
// Attach opens a file by name, and unmarshal its JSON data.
|
||||
// Will proceed to setup the API if not already done so.
|
||||
func (a *API) Attach(filename string) {
|
||||
@@ -35,19 +163,25 @@ func (a *API) AttachString(str string) {
|
||||
|
||||
// Setup initializes the API.
|
||||
func (a *API) Setup() {
|
||||
a.setServiceAliaseName()
|
||||
a.setMetadataEndpointsKey()
|
||||
a.writeShapeNames()
|
||||
a.resolveReferences()
|
||||
a.fixStutterNames()
|
||||
a.renameExportable()
|
||||
if !a.NoRenameToplevelShapes {
|
||||
a.renameToplevelShapes()
|
||||
|
||||
if !a.NoRemoveUnusedShapes {
|
||||
a.removeUnusedShapes()
|
||||
}
|
||||
|
||||
a.fixStutterNames()
|
||||
a.renameExportable()
|
||||
a.applyShapeNameAliases()
|
||||
a.createInputOutputShapes()
|
||||
a.renameAPIPayloadShapes()
|
||||
a.renameCollidingFields()
|
||||
a.updateTopLevelShapeReferences()
|
||||
a.createInputOutputShapes()
|
||||
a.suppressEventStreams()
|
||||
a.setupEventStreams()
|
||||
a.findEndpointDiscoveryOp()
|
||||
a.injectUnboundedOutputStreaming()
|
||||
a.customizationPasses()
|
||||
|
||||
if !a.NoRemoveUnusedShapes {
|
||||
|
||||
+45
-1
@@ -1,8 +1,11 @@
|
||||
// +build 1.6,codegen
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -30,3 +33,44 @@ func TestResolvedReferences(t *testing.T) {
|
||||
t.Errorf("Expected %d, but received %d", 2, len(a.Shapes["OtherTest"].refs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrimModelServiceVersions(t *testing.T) {
|
||||
cases := []struct {
|
||||
Paths []string
|
||||
Include []string
|
||||
Exclude []string
|
||||
}{
|
||||
{
|
||||
Paths: []string{
|
||||
filepath.Join("foo", "baz", "2018-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "baz", "2019-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "baz", "2017-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2019-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2013-04-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2019-01-03", "api-2.json"),
|
||||
},
|
||||
Include: []string{
|
||||
filepath.Join("foo", "baz", "2019-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2019-01-03", "api-2.json"),
|
||||
},
|
||||
Exclude: []string{
|
||||
filepath.Join("foo", "baz", "2018-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "baz", "2017-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2019-01-02", "api-2.json"),
|
||||
filepath.Join("foo", "bar", "2013-04-02", "api-2.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
include, exclude := TrimModelServiceVersions(c.Paths)
|
||||
if e, a := c.Include, include; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect include %v, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Exclude, exclude; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect exclude %v, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var debugLogger *logger
|
||||
var initDebugLoggerOnce sync.Once
|
||||
|
||||
// logger provides a basic logging
|
||||
type logger struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// LogDebug initialize's the debug logger for the components in the api
|
||||
// package to log debug lines to.
|
||||
//
|
||||
// Panics if called multiple times.
|
||||
//
|
||||
// Must be used prior to any model loading or code gen.
|
||||
func LogDebug(w io.Writer) {
|
||||
var initialized bool
|
||||
initDebugLoggerOnce.Do(func() {
|
||||
debugLogger = &logger{
|
||||
w: w,
|
||||
}
|
||||
initialized = true
|
||||
})
|
||||
|
||||
if !initialized && debugLogger != nil {
|
||||
panic("LogDebug called multiple times. Can only be called once")
|
||||
}
|
||||
}
|
||||
|
||||
// Logf logs using the fmt printf pattern. Appends a new line to the end of the
|
||||
// logged statement.
|
||||
func (l *logger) Logf(format string, args ...interface{}) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(l.w, format+"\n", args...)
|
||||
}
|
||||
|
||||
// Logln logs using the fmt println pattern.
|
||||
func (l *logger) Logln(args ...interface{}) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(l.w, args...)
|
||||
}
|
||||
+261
-32
@@ -13,18 +13,58 @@ import (
|
||||
|
||||
// An Operation defines a specific API Operation.
|
||||
type Operation struct {
|
||||
API *API `json:"-"`
|
||||
ExportedName string
|
||||
Name string
|
||||
Documentation string
|
||||
HTTP HTTPInfo
|
||||
InputRef ShapeRef `json:"input"`
|
||||
OutputRef ShapeRef `json:"output"`
|
||||
ErrorRefs []ShapeRef `json:"errors"`
|
||||
Paginator *Paginator
|
||||
Deprecated bool `json:"deprecated"`
|
||||
AuthType string `json:"authtype"`
|
||||
imports map[string]bool
|
||||
API *API `json:"-"`
|
||||
ExportedName string
|
||||
Name string
|
||||
Documentation string
|
||||
HTTP HTTPInfo
|
||||
Host string `json:"host"`
|
||||
InputRef ShapeRef `json:"input"`
|
||||
OutputRef ShapeRef `json:"output"`
|
||||
ErrorRefs []ShapeRef `json:"errors"`
|
||||
Paginator *Paginator
|
||||
Deprecated bool `json:"deprecated"`
|
||||
DeprecatedMsg string `json:"deprecatedMessage"`
|
||||
AuthType AuthType `json:"authtype"`
|
||||
imports map[string]bool
|
||||
CustomBuildHandlers []string
|
||||
|
||||
EventStreamAPI *EventStreamAPI
|
||||
|
||||
IsEndpointDiscoveryOp bool `json:"endpointoperation"`
|
||||
EndpointDiscovery *EndpointDiscovery `json:"endpointdiscovery"`
|
||||
Endpoint *EndpointTrait `json:"endpoint"`
|
||||
}
|
||||
|
||||
// EndpointTrait provides the structure of the modeled enpdoint trait, and its
|
||||
// properties.
|
||||
type EndpointTrait struct {
|
||||
// Specifies the hostPrefix template to prepend to the operation's request
|
||||
// endpoint host.
|
||||
HostPrefix string `json:"hostPrefix"`
|
||||
}
|
||||
|
||||
// EndpointDiscovery represents a map of key values pairs that represents
|
||||
// metadata about how a given API will make a call to the discovery endpoint.
|
||||
type EndpointDiscovery struct {
|
||||
// Required indicates that for a given operation that endpoint is required.
|
||||
// Any required endpoint discovery operation cannot have endpoint discovery
|
||||
// turned off.
|
||||
Required bool `json:"required"`
|
||||
}
|
||||
|
||||
// OperationForMethod returns the API operation name that corresponds to the
|
||||
// client method name provided.
|
||||
func (a *API) OperationForMethod(name string) *Operation {
|
||||
for _, op := range a.Operations {
|
||||
for _, m := range op.Methods() {
|
||||
if m == name {
|
||||
return op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// A HTTPInfo defines the method of HTTP request for the Operation.
|
||||
@@ -34,6 +74,24 @@ type HTTPInfo struct {
|
||||
ResponseCode uint
|
||||
}
|
||||
|
||||
// Methods Returns a list of method names that will be generated.
|
||||
func (o *Operation) Methods() []string {
|
||||
methods := []string{
|
||||
o.ExportedName,
|
||||
o.ExportedName + "Request",
|
||||
o.ExportedName + "WithContext",
|
||||
}
|
||||
|
||||
if o.Paginator != nil {
|
||||
methods = append(methods, []string{
|
||||
o.ExportedName + "Pages",
|
||||
o.ExportedName + "PagesWithContext",
|
||||
}...)
|
||||
}
|
||||
|
||||
return methods
|
||||
}
|
||||
|
||||
// HasInput returns if the Operation accepts an input paramater
|
||||
func (o *Operation) HasInput() bool {
|
||||
return o.InputRef.ShapeName != ""
|
||||
@@ -44,17 +102,27 @@ func (o *Operation) HasOutput() bool {
|
||||
return o.OutputRef.ShapeName != ""
|
||||
}
|
||||
|
||||
func (o *Operation) GetSigner() string {
|
||||
if o.AuthType == "v4-unsigned-body" {
|
||||
o.API.imports["github.com/aws/aws-sdk-go/aws/signer/v4"] = true
|
||||
}
|
||||
// AuthType provides the enumeration of AuthType trait.
|
||||
type AuthType string
|
||||
|
||||
// Enumeration values for AuthType trait
|
||||
const (
|
||||
NoneAuthType AuthType = "none"
|
||||
V4UnsignedBodyAuthType AuthType = "v4-unsigned-body"
|
||||
)
|
||||
|
||||
// GetSigner returns the signer that should be used for a API request.
|
||||
func (o *Operation) GetSigner() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
switch o.AuthType {
|
||||
case "none":
|
||||
case NoneAuthType:
|
||||
o.API.AddSDKImport("aws/credentials")
|
||||
|
||||
buf.WriteString("req.Config.Credentials = credentials.AnonymousCredentials")
|
||||
case "v4-unsigned-body":
|
||||
case V4UnsignedBodyAuthType:
|
||||
o.API.AddSDKImport("aws/signer/v4")
|
||||
|
||||
buf.WriteString("req.Handlers.Sign.Remove(v4.SignRequestHandler)\n")
|
||||
buf.WriteString("handler := v4.BuildNamedHandler(\"v4.CustomSignerHandler\", v4.WithUnsignedPayload)\n")
|
||||
buf.WriteString("req.Handlers.Sign.PushFrontNamed(handler)")
|
||||
@@ -64,16 +132,18 @@ func (o *Operation) GetSigner() string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// tplOperation defines a template for rendering an API Operation
|
||||
var tplOperation = template.Must(template.New("operation").Funcs(template.FuncMap{
|
||||
"GetCrosslinkURL": GetCrosslinkURL,
|
||||
// operationTmpl defines a template for rendering an API Operation
|
||||
var operationTmpl = template.Must(template.New("operation").Funcs(template.FuncMap{
|
||||
"GetCrosslinkURL": GetCrosslinkURL,
|
||||
"EnableStopOnSameToken": enableStopOnSameToken,
|
||||
"GetDeprecatedMsg": getDeprecatedMessage,
|
||||
}).Parse(`
|
||||
const op{{ .ExportedName }} = "{{ .Name }}"
|
||||
|
||||
// {{ .ExportedName }}Request generates a "aws/request.Request" representing the
|
||||
// client's request for the {{ .ExportedName }} operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -93,16 +163,19 @@ const op{{ .ExportedName }} = "{{ .Name }}"
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
{{ $crosslinkURL := GetCrosslinkURL $.API.BaseCrosslinkURL $.API.Metadata.UID $.ExportedName -}}
|
||||
{{ if ne $crosslinkURL "" -}}
|
||||
{{ if ne $crosslinkURL "" -}}
|
||||
//
|
||||
// See also, {{ $crosslinkURL }}
|
||||
{{ end -}}
|
||||
{{- if .Deprecated }}//
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg .ExportedName }}
|
||||
{{ end -}}
|
||||
func (c *{{ .API.StructName }}) {{ .ExportedName }}Request(` +
|
||||
`input {{ .InputRef.GoType }}) (req *request.Request, output {{ .OutputRef.GoType }}) {
|
||||
{{ if (or .Deprecated (or .InputRef.Deprecated .OutputRef.Deprecated)) }}if c.Client.Config.Logger != nil {
|
||||
c.Client.Config.Logger.Log("This operation, {{ .ExportedName }}, has been deprecated")
|
||||
}
|
||||
op := &request.Operation{ {{ else }} op := &request.Operation{ {{ end }}
|
||||
op := &request.Operation{ {{ else }} op := &request.Operation{ {{ end }}
|
||||
Name: op{{ .ExportedName }},
|
||||
{{ if ne .HTTP.Method "" }}HTTPMethod: "{{ .HTTP.Method }}",
|
||||
{{ end }}HTTPPath: {{ if ne .HTTP.RequestURI "" }}"{{ .HTTP.RequestURI }}"{{ else }}"/"{{ end }},
|
||||
@@ -120,10 +193,57 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}Request(` +
|
||||
}
|
||||
|
||||
output = &{{ .OutputRef.GoTypeElem }}{}
|
||||
req = c.newRequest(op, input, output){{ if eq .OutputRef.Shape.Placeholder true }}
|
||||
req.Handlers.Unmarshal.Remove({{ .API.ProtocolPackage }}.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler){{ end }}
|
||||
{{ if ne .AuthType "" }}{{ .GetSigner }}{{ end -}}
|
||||
req = c.newRequest(op, input, output)
|
||||
{{ if ne .AuthType "" }}{{ .GetSigner }}{{ end }}
|
||||
{{- if .ShouldDiscardResponse -}}
|
||||
{{- $_ := .API.AddSDKImport "private/protocol" -}}
|
||||
{{- $_ := .API.AddSDKImport "private/protocol" .API.ProtocolPackage -}}
|
||||
req.Handlers.Unmarshal.Swap({{ .API.ProtocolPackage }}.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
{{ else if .OutputRef.Shape.EventStreamsMemberName -}}
|
||||
{{- $_ := .API.AddSDKImport "private/protocol" .API.ProtocolPackage -}}
|
||||
{{- $_ := .API.AddSDKImport "private/protocol/rest" -}}
|
||||
req.Handlers.Send.Swap(client.LogHTTPResponseHandler.Name, client.LogHTTPResponseHeaderHandler)
|
||||
req.Handlers.Unmarshal.Swap({{ .API.ProtocolPackage }}.UnmarshalHandler.Name, rest.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBack(output.runEventStreamLoop)
|
||||
{{ if eq .API.Metadata.Protocol "json" -}}
|
||||
req.Handlers.Unmarshal.PushBack(output.unmarshalInitialResponse)
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ if .EndpointDiscovery -}}
|
||||
{{if not .EndpointDiscovery.Required -}}
|
||||
if aws.BoolValue(req.Config.EnableEndpointDiscovery) {
|
||||
{{end -}}
|
||||
de := discoverer{{ .API.EndpointDiscoveryOp.Name }}{
|
||||
Required: {{ .EndpointDiscovery.Required }},
|
||||
EndpointCache: c.endpointCache,
|
||||
Params: map[string]*string{
|
||||
"op": aws.String(req.Operation.Name),
|
||||
{{ range $key, $ref := .InputRef.Shape.MemberRefs -}}
|
||||
{{ if $ref.EndpointDiscoveryID -}}
|
||||
"{{ $ref.OrigShapeName }}": input.{{ $key }},
|
||||
{{ end -}}
|
||||
{{- end }}
|
||||
},
|
||||
Client: c,
|
||||
}
|
||||
|
||||
for k, v := range de.Params {
|
||||
if v == nil {
|
||||
delete(de.Params, k)
|
||||
}
|
||||
}
|
||||
|
||||
req.Handlers.Build.PushFrontNamed(request.NamedHandler{
|
||||
Name: "crr.endpointdiscovery",
|
||||
Fn: de.Handler,
|
||||
})
|
||||
{{if not .EndpointDiscovery.Required -}}
|
||||
}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{- range $_, $handler := $.CustomBuildHandlers -}}
|
||||
req.Handlers.Build.PushBackNamed({{ $handler }})
|
||||
{{ end -}}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -151,9 +271,12 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}Request(` +
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ $crosslinkURL := GetCrosslinkURL $.API.BaseCrosslinkURL $.API.Metadata.UID $.ExportedName -}}
|
||||
{{ if ne $crosslinkURL "" -}}
|
||||
{{ if ne $crosslinkURL "" -}}
|
||||
// See also, {{ $crosslinkURL }}
|
||||
{{ end -}}
|
||||
{{- if .Deprecated }}//
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg .ExportedName }}
|
||||
{{ end -}}
|
||||
func (c *{{ .API.StructName }}) {{ .ExportedName }}(` +
|
||||
`input {{ .InputRef.GoType }}) ({{ .OutputRef.GoType }}, error) {
|
||||
req, out := c.{{ .ExportedName }}Request(input)
|
||||
@@ -169,6 +292,9 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}(` +
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
{{ if .Deprecated }}//
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg (printf "%s%s" .ExportedName "WithContext") }}
|
||||
{{ end -}}
|
||||
func (c *{{ .API.StructName }}) {{ .ExportedName }}WithContext(` +
|
||||
`ctx aws.Context, input {{ .InputRef.GoType }}, opts ...request.Option) ` +
|
||||
`({{ .OutputRef.GoType }}, error) {
|
||||
@@ -190,12 +316,15 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}WithContext(` +
|
||||
// // Example iterating over at most 3 pages of a {{ .ExportedName }} operation.
|
||||
// pageNum := 0
|
||||
// err := client.{{ .ExportedName }}Pages(params,
|
||||
// func(page {{ .OutputRef.GoType }}, lastPage bool) bool {
|
||||
// func(page {{ .OutputRef.Shape.GoTypeWithPkgName }}, lastPage bool) bool {
|
||||
// pageNum++
|
||||
// fmt.Println(page)
|
||||
// return pageNum <= 3
|
||||
// })
|
||||
//
|
||||
{{ if .Deprecated }}//
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg (printf "%s%s" .ExportedName "Pages") }}
|
||||
{{ end -}}
|
||||
func (c *{{ .API.StructName }}) {{ .ExportedName }}Pages(` +
|
||||
`input {{ .InputRef.GoType }}, fn func({{ .OutputRef.GoType }}, bool) bool) error {
|
||||
return c.{{ .ExportedName }}PagesWithContext(aws.BackgroundContext(), input, fn)
|
||||
@@ -208,12 +337,17 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}Pages(` +
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
{{ if .Deprecated }}//
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg (printf "%s%s" .ExportedName "PagesWithContext") }}
|
||||
{{ end -}}
|
||||
func (c *{{ .API.StructName }}) {{ .ExportedName }}PagesWithContext(` +
|
||||
`ctx aws.Context, ` +
|
||||
`input {{ .InputRef.GoType }}, ` +
|
||||
`fn func({{ .OutputRef.GoType }}, bool) bool, ` +
|
||||
`opts ...request.Option) error {
|
||||
p := request.Pagination {
|
||||
{{ if EnableStopOnSameToken .API.PackageName -}}EndPageOnSameToken: true,
|
||||
{{ end -}}
|
||||
NewRequest: func() (*request.Request, error) {
|
||||
var inCpy {{ .InputRef.GoType }}
|
||||
if input != nil {
|
||||
@@ -234,12 +368,100 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}PagesWithContext(` +
|
||||
return p.Err()
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if .IsEndpointDiscoveryOp -}}
|
||||
|
||||
type discoverer{{ .ExportedName }} struct {
|
||||
Client *{{ .API.StructName }}
|
||||
Required bool
|
||||
EndpointCache *crr.EndpointCache
|
||||
Params map[string]*string
|
||||
Key string
|
||||
}
|
||||
|
||||
func (d *discoverer{{ .ExportedName }}) Discover() (crr.Endpoint, error) {
|
||||
input := &{{ .API.EndpointDiscoveryOp.InputRef.ShapeName }}{
|
||||
{{ if .API.EndpointDiscoveryOp.InputRef.Shape.HasMember "Operation" -}}
|
||||
Operation: d.Params["op"],
|
||||
{{ end -}}
|
||||
{{ if .API.EndpointDiscoveryOp.InputRef.Shape.HasMember "Identifiers" -}}
|
||||
Identifiers: d.Params,
|
||||
{{ end -}}
|
||||
}
|
||||
|
||||
resp, err := d.Client.{{ .API.EndpointDiscoveryOp.Name }}(input)
|
||||
if err != nil {
|
||||
return crr.Endpoint{}, err
|
||||
}
|
||||
|
||||
endpoint := crr.Endpoint{
|
||||
Key: d.Key,
|
||||
}
|
||||
|
||||
for _, e := range resp.Endpoints {
|
||||
if e.Address == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cachedInMinutes := aws.Int64Value(e.CachePeriodInMinutes)
|
||||
u, err := url.Parse(*e.Address)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
addr := crr.WeightedAddress{
|
||||
URL: u,
|
||||
Expired: time.Now().Add(time.Duration(cachedInMinutes) * time.Minute),
|
||||
}
|
||||
|
||||
endpoint.Add(addr)
|
||||
}
|
||||
|
||||
d.EndpointCache.Add(endpoint)
|
||||
|
||||
return endpoint, nil
|
||||
}
|
||||
|
||||
func (d *discoverer{{ .ExportedName }}) Handler(r *request.Request) {
|
||||
endpointKey := crr.BuildEndpointKey(d.Params)
|
||||
d.Key = endpointKey
|
||||
|
||||
endpoint, err := d.EndpointCache.Get(d, endpointKey, d.Required)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return
|
||||
}
|
||||
|
||||
if endpoint.URL != nil && len(endpoint.URL.String()) > 0 {
|
||||
r.HTTPRequest.URL = endpoint.URL
|
||||
}
|
||||
}
|
||||
{{ end -}}
|
||||
|
||||
`))
|
||||
|
||||
// GoCode returns a string of rendered GoCode for this Operation
|
||||
func (o *Operation) GoCode() string {
|
||||
var buf bytes.Buffer
|
||||
err := tplOperation.Execute(&buf, o)
|
||||
|
||||
if len(o.OutputRef.Shape.EventStreamsMemberName) != 0 {
|
||||
o.API.AddSDKImport("aws/client")
|
||||
o.API.AddSDKImport("private/protocol")
|
||||
o.API.AddSDKImport("private/protocol/rest")
|
||||
o.API.AddSDKImport("private/protocol", o.API.ProtocolPackage())
|
||||
}
|
||||
|
||||
if o.API.EndpointDiscoveryOp != nil {
|
||||
o.API.AddSDKImport("aws/crr")
|
||||
o.API.AddImport("time")
|
||||
o.API.AddImport("net/url")
|
||||
}
|
||||
|
||||
if o.Endpoint != nil && len(o.Endpoint.HostPrefix) != 0 {
|
||||
setupEndpointHostPrefix(o)
|
||||
}
|
||||
|
||||
err := operationTmpl.Execute(&buf, o)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -308,7 +530,7 @@ func (o *Operation) Example() string {
|
||||
func (o *Operation) ExampleInput() string {
|
||||
if len(o.InputRef.Shape.MemberRefs) == 0 {
|
||||
if strings.Contains(o.InputRef.GoTypeElem(), ".") {
|
||||
o.imports["github.com/aws/aws-sdk-go/service/"+strings.Split(o.InputRef.GoTypeElem(), ".")[0]] = true
|
||||
o.imports[SDKImportRoot+"service/"+strings.Split(o.InputRef.GoTypeElem(), ".")[0]] = true
|
||||
return fmt.Sprintf("var params *%s", o.InputRef.GoTypeElem())
|
||||
}
|
||||
return fmt.Sprintf("var params *%s.%s",
|
||||
@@ -318,6 +540,13 @@ func (o *Operation) ExampleInput() string {
|
||||
return "params := " + e.traverseAny(o.InputRef.Shape, false, false)
|
||||
}
|
||||
|
||||
// ShouldDiscardResponse returns if the operation should discard the response
|
||||
// returned by the service.
|
||||
func (o *Operation) ShouldDiscardResponse() bool {
|
||||
s := o.OutputRef.Shape
|
||||
return s.Placeholder || len(s.MemberRefs) == 0
|
||||
}
|
||||
|
||||
// A example provides
|
||||
type example struct {
|
||||
*Operation
|
||||
|
||||
+9
@@ -89,3 +89,12 @@ func (p *paginationDefinitions) setup() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func enableStopOnSameToken(service string) bool {
|
||||
switch service {
|
||||
case "cloudwatchlogs":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
@@ -83,7 +83,7 @@ func (f paramFiller) paramsStructAny(value interface{}, shape *Shape) string {
|
||||
case "jsonvalue":
|
||||
v, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
panic("failed to marshal JSONValue, "+err.Error())
|
||||
panic("failed to marshal JSONValue, " + err.Error())
|
||||
}
|
||||
const tmpl = `func() aws.JSONValue {
|
||||
var m aws.JSONValue
|
||||
|
||||
+115
-61
@@ -58,7 +58,8 @@ func (a *API) resolveReferences() {
|
||||
// Resolve references for errors also
|
||||
for i := range o.ErrorRefs {
|
||||
resolver.resolveReference(&o.ErrorRefs[i])
|
||||
o.ErrorRefs[i].Shape.IsError = true
|
||||
o.ErrorRefs[i].Shape.Exception = true
|
||||
o.ErrorRefs[i].Shape.ErrorInfo.Type = o.ErrorRefs[i].Shape.ShapeName
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,14 +71,6 @@ type referenceResolver struct {
|
||||
visited map[*ShapeRef]bool
|
||||
}
|
||||
|
||||
var jsonvalueShape = &Shape{
|
||||
ShapeName: "JSONValue",
|
||||
Type: "jsonvalue",
|
||||
ValueRef: ShapeRef{
|
||||
JSONValue: true,
|
||||
},
|
||||
}
|
||||
|
||||
// resolveReference updates a shape reference to reference the API and
|
||||
// its shape definition. All other nested references are also resolved.
|
||||
func (r *referenceResolver) resolveReference(ref *ShapeRef) {
|
||||
@@ -88,12 +81,20 @@ func (r *referenceResolver) resolveReference(ref *ShapeRef) {
|
||||
shape, ok := r.API.Shapes[ref.ShapeName]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("unable resolve reference, %s", ref.ShapeName))
|
||||
return
|
||||
}
|
||||
|
||||
if ref.JSONValue {
|
||||
ref.ShapeName = "JSONValue"
|
||||
r.API.Shapes[ref.ShapeName] = jsonvalueShape
|
||||
if _, ok := r.API.Shapes[ref.ShapeName]; !ok {
|
||||
r.API.Shapes[ref.ShapeName] = &Shape{
|
||||
API: r.API,
|
||||
ShapeName: "JSONValue",
|
||||
Type: "jsonvalue",
|
||||
ValueRef: ShapeRef{
|
||||
JSONValue: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref.API = r.API // resolve reference back to API
|
||||
@@ -121,40 +122,6 @@ func (r *referenceResolver) resolveShape(shape *Shape) {
|
||||
}
|
||||
}
|
||||
|
||||
// renameToplevelShapes renames all top level shapes of an API to their
|
||||
// exportable variant. The shapes are also updated to include notations
|
||||
// if they are Input or Outputs.
|
||||
func (a *API) renameToplevelShapes() {
|
||||
for _, v := range a.OperationList() {
|
||||
if v.HasInput() {
|
||||
name := v.ExportedName + "Input"
|
||||
switch {
|
||||
case a.Shapes[name] == nil:
|
||||
if service, ok := shamelist[a.name]; ok {
|
||||
if check, ok := service[v.Name]; ok && check.input {
|
||||
break
|
||||
}
|
||||
}
|
||||
v.InputRef.Shape.Rename(name)
|
||||
}
|
||||
}
|
||||
if v.HasOutput() {
|
||||
name := v.ExportedName + "Output"
|
||||
switch {
|
||||
case a.Shapes[name] == nil:
|
||||
if service, ok := shamelist[a.name]; ok {
|
||||
if check, ok := service[v.Name]; ok && check.output {
|
||||
break
|
||||
}
|
||||
}
|
||||
v.OutputRef.Shape.Rename(name)
|
||||
}
|
||||
}
|
||||
v.InputRef.Payload = a.ExportableName(v.InputRef.Payload)
|
||||
v.OutputRef.Payload = a.ExportableName(v.OutputRef.Payload)
|
||||
}
|
||||
}
|
||||
|
||||
// fixStutterNames fixes all name struttering based on Go naming conventions.
|
||||
// "Stuttering" is when the prefix of a structure or function matches the
|
||||
// package name (case insensitive).
|
||||
@@ -205,6 +172,10 @@ func (a *API) renameExportable() {
|
||||
}
|
||||
|
||||
for mName, member := range s.MemberRefs {
|
||||
ref := s.MemberRefs[mName]
|
||||
ref.OrigShapeName = mName
|
||||
s.MemberRefs[mName] = ref
|
||||
|
||||
newName := a.ExportableName(mName)
|
||||
if newName != mName {
|
||||
delete(s.MemberRefs, mName)
|
||||
@@ -254,28 +225,26 @@ func (a *API) renameCollidingFields() {
|
||||
for _, v := range a.Shapes {
|
||||
namesWithSet := map[string]struct{}{}
|
||||
for k, field := range v.MemberRefs {
|
||||
if strings.HasPrefix(k, "Set") {
|
||||
namesWithSet[k] = struct{}{}
|
||||
if _, ok := v.MemberRefs["Set"+k]; ok {
|
||||
namesWithSet["Set"+k] = struct{}{}
|
||||
}
|
||||
|
||||
if collides(k) {
|
||||
if collides(k) || (v.Exception && exceptionCollides(k)) {
|
||||
renameCollidingField(k, v, field)
|
||||
}
|
||||
}
|
||||
|
||||
// checks if any field names collide with setters.
|
||||
for name := range namesWithSet {
|
||||
if field, ok := v.MemberRefs["Set"+name]; ok {
|
||||
renameCollidingField(name, v, field)
|
||||
}
|
||||
field := v.MemberRefs[name]
|
||||
renameCollidingField(name, v, field)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func renameCollidingField(name string, v *Shape, field *ShapeRef) {
|
||||
newName := name + "_"
|
||||
fmt.Printf("Shape %s's field %q renamed to %q\n", v.ShapeName, name, newName)
|
||||
debugLogger.Logf("Shape %s's field %q renamed to %q", v.ShapeName, name, newName)
|
||||
delete(v.MemberRefs, name)
|
||||
v.MemberRefs[newName] = field
|
||||
}
|
||||
@@ -287,8 +256,32 @@ func collides(name string) bool {
|
||||
"GoString",
|
||||
"Validate":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func exceptionCollides(name string) bool {
|
||||
switch name {
|
||||
case "Code",
|
||||
"Message",
|
||||
"OrigErr":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *API) applyShapeNameAliases() {
|
||||
service, ok := shapeNameAliases[a.name]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Generic Shape Aliases
|
||||
for name, s := range a.Shapes {
|
||||
if alias, ok := service[name]; ok {
|
||||
s.Rename(alias)
|
||||
s.AliasedShapeName = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,15 +290,47 @@ func collides(name string) bool {
|
||||
// have an input and output structure in the signature.
|
||||
func (a *API) createInputOutputShapes() {
|
||||
for _, op := range a.Operations {
|
||||
if !op.HasInput() {
|
||||
setAsPlacholderShape(&op.InputRef, op.ExportedName+"Input", a)
|
||||
}
|
||||
if !op.HasOutput() {
|
||||
setAsPlacholderShape(&op.OutputRef, op.ExportedName+"Output", a)
|
||||
}
|
||||
createAPIParamShape(a, op.Name, &op.InputRef, op.ExportedName+"Input",
|
||||
shamelist.Input,
|
||||
)
|
||||
createAPIParamShape(a, op.Name, &op.OutputRef, op.ExportedName+"Output",
|
||||
shamelist.Output,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) renameAPIPayloadShapes() {
|
||||
for _, op := range a.Operations {
|
||||
op.InputRef.Payload = a.ExportableName(op.InputRef.Payload)
|
||||
op.OutputRef.Payload = a.ExportableName(op.OutputRef.Payload)
|
||||
}
|
||||
}
|
||||
|
||||
func createAPIParamShape(a *API, opName string, ref *ShapeRef, shapeName string, shamelistLookup func(string, string) bool) {
|
||||
if len(ref.ShapeName) == 0 {
|
||||
setAsPlacholderShape(ref, shapeName, a)
|
||||
return
|
||||
}
|
||||
|
||||
// nothing to do if already the correct name.
|
||||
if s := ref.Shape; s.AliasedShapeName || s.ShapeName == shapeName || shamelistLookup(a.name, opName) {
|
||||
return
|
||||
}
|
||||
|
||||
if s, ok := a.Shapes[shapeName]; ok {
|
||||
panic(fmt.Sprintf(
|
||||
"attempting to create duplicate API parameter shape, %v, %v, %v, %v\n",
|
||||
shapeName, opName, ref.ShapeName, s.OrigShapeName,
|
||||
))
|
||||
}
|
||||
|
||||
ref.Shape.removeRef(ref)
|
||||
ref.OrigShapeName = shapeName
|
||||
ref.ShapeName = shapeName
|
||||
ref.Shape = ref.Shape.Clone(shapeName)
|
||||
ref.Shape.refs = append(ref.Shape.refs, ref)
|
||||
}
|
||||
|
||||
func setAsPlacholderShape(tgtShapeRef *ShapeRef, name string, a *API) {
|
||||
shape := a.makeIOShape(name)
|
||||
shape.Placeholder = true
|
||||
@@ -352,3 +377,32 @@ func (a *API) setMetadataEndpointsKey() {
|
||||
a.Metadata.EndpointsID = a.Metadata.EndpointPrefix
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) findEndpointDiscoveryOp() {
|
||||
for _, op := range a.Operations {
|
||||
if op.IsEndpointDiscoveryOp {
|
||||
a.EndpointDiscoveryOp = op
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
func (a *API) injectUnboundedOutputStreaming() {
|
||||
for _, op := range a.Operations {
|
||||
if op.AuthType != V4UnsignedBodyAuthType {
|
||||
continue
|
||||
}
|
||||
for _, ref := range op.InputRef.Shape.MemberRefs {
|
||||
if ref.Streaming || ref.Shape.Streaming {
|
||||
if len(ref.Documentation) != 0 {
|
||||
ref.Documentation += `
|
||||
//`
|
||||
}
|
||||
ref.Documentation += `
|
||||
// To use an non-seekable io.Reader for this request wrap the io.Reader with
|
||||
// "aws.ReadSeekCloser". The SDK will not retry request errors for non-seekable
|
||||
// readers. This will allow the SDK to send the reader's payload as chunked
|
||||
// transfer encoding.`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+461
-111
@@ -1,35 +1,35 @@
|
||||
// +build 1.6,codegen
|
||||
// +build go1.8,codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUniqueInputAndOutputs(t *testing.T) {
|
||||
shamelist["FooService"] = map[string]struct {
|
||||
input bool
|
||||
output bool
|
||||
}{}
|
||||
v := shamelist["FooService"]["OpOutputNoRename"]
|
||||
v.output = true
|
||||
shamelist["FooService"]["OpOutputNoRename"] = v
|
||||
v = shamelist["FooService"]["InputNoRename"]
|
||||
v.input = true
|
||||
shamelist["FooService"]["OpInputNoRename"] = v
|
||||
v = shamelist["FooService"]["BothNoRename"]
|
||||
v.input = true
|
||||
v.output = true
|
||||
shamelist["FooService"]["OpBothNoRename"] = v
|
||||
const serviceName = "FooService"
|
||||
|
||||
shamelist[serviceName] = map[string]persistAPIType{
|
||||
"OpOutputNoRename": {
|
||||
output: true,
|
||||
},
|
||||
"OpInputNoRename": {
|
||||
input: true,
|
||||
},
|
||||
"OpBothNoRename": {
|
||||
input: true,
|
||||
output: true,
|
||||
},
|
||||
}
|
||||
|
||||
cases := [][]struct {
|
||||
expectedInput string
|
||||
expectedOutput string
|
||||
operation string
|
||||
input string
|
||||
inputRef string
|
||||
output string
|
||||
outputRef string
|
||||
}{
|
||||
{
|
||||
{
|
||||
@@ -37,18 +37,14 @@ func TestUniqueInputAndOutputs(t *testing.T) {
|
||||
expectedOutput: "FooOperationOutput",
|
||||
operation: "FooOperation",
|
||||
input: "FooInputShape",
|
||||
inputRef: "FooInputShapeRef",
|
||||
output: "FooOutputShape",
|
||||
outputRef: "FooOutputShapeRef",
|
||||
},
|
||||
{
|
||||
expectedInput: "BarOperationInput",
|
||||
expectedOutput: "BarOperationOutput",
|
||||
operation: "BarOperation",
|
||||
input: "FooInputShape",
|
||||
inputRef: "FooInputShapeRef",
|
||||
output: "FooOutputShape",
|
||||
outputRef: "FooOutputShapeRef",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -57,18 +53,14 @@ func TestUniqueInputAndOutputs(t *testing.T) {
|
||||
expectedOutput: "FooOperationOutput",
|
||||
operation: "FooOperation",
|
||||
input: "FooInputShape",
|
||||
inputRef: "FooInputShapeRef",
|
||||
output: "FooOutputShape",
|
||||
outputRef: "FooOutputShapeRef",
|
||||
},
|
||||
{
|
||||
expectedInput: "OpOutputNoRenameInput",
|
||||
expectedOutput: "OpOutputNoRenameOutputShape",
|
||||
operation: "OpOutputNoRename",
|
||||
input: "OpOutputNoRenameInputShape",
|
||||
inputRef: "OpOutputNoRenameInputRef",
|
||||
output: "OpOutputNoRenameOutputShape",
|
||||
outputRef: "OpOutputNoRenameOutputRef",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -77,18 +69,14 @@ func TestUniqueInputAndOutputs(t *testing.T) {
|
||||
expectedOutput: "FooOperationOutput",
|
||||
operation: "FooOperation",
|
||||
input: "FooInputShape",
|
||||
inputRef: "FooInputShapeRef",
|
||||
output: "FooOutputShape",
|
||||
outputRef: "FooOutputShapeRef",
|
||||
},
|
||||
{
|
||||
expectedInput: "OpInputNoRenameInputShape",
|
||||
expectedOutput: "OpInputNoRenameOutput",
|
||||
operation: "OpInputNoRename",
|
||||
input: "OpInputNoRenameInputShape",
|
||||
inputRef: "OpInputNoRenameInputRef",
|
||||
output: "OpInputNoRenameOutputShape",
|
||||
outputRef: "OpInputNoRenameOutputRef",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -97,115 +85,477 @@ func TestUniqueInputAndOutputs(t *testing.T) {
|
||||
expectedOutput: "FooOperationOutput",
|
||||
operation: "FooOperation",
|
||||
input: "FooInputShape",
|
||||
inputRef: "FooInputShapeRef",
|
||||
output: "FooOutputShape",
|
||||
outputRef: "FooOutputShapeRef",
|
||||
},
|
||||
{
|
||||
expectedInput: "OpInputNoRenameInputShape",
|
||||
expectedOutput: "OpInputNoRenameOutputShape",
|
||||
operation: "OpBothNoRename",
|
||||
input: "OpInputNoRenameInputShape",
|
||||
inputRef: "OpInputNoRenameInputRef",
|
||||
output: "OpInputNoRenameOutputShape",
|
||||
outputRef: "OpInputNoRenameOutputRef",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
a := &API{
|
||||
name: "FooService",
|
||||
Operations: map[string]*Operation{},
|
||||
}
|
||||
|
||||
expected := map[string][]string{}
|
||||
a.Shapes = map[string]*Shape{}
|
||||
for _, op := range c {
|
||||
a.Operations[op.operation] = &Operation{
|
||||
ExportedName: op.operation,
|
||||
}
|
||||
a.Operations[op.operation].Name = op.operation
|
||||
a.Operations[op.operation].InputRef = ShapeRef{
|
||||
API: a,
|
||||
ShapeName: op.inputRef,
|
||||
Shape: &Shape{
|
||||
API: a,
|
||||
ShapeName: op.input,
|
||||
},
|
||||
}
|
||||
a.Operations[op.operation].OutputRef = ShapeRef{
|
||||
API: a,
|
||||
ShapeName: op.outputRef,
|
||||
Shape: &Shape{
|
||||
API: a,
|
||||
ShapeName: op.output,
|
||||
},
|
||||
for i, c := range cases {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
a := &API{
|
||||
name: serviceName,
|
||||
Operations: map[string]*Operation{},
|
||||
Shapes: map[string]*Shape{},
|
||||
}
|
||||
|
||||
a.Shapes[op.input] = &Shape{
|
||||
ShapeName: op.input,
|
||||
}
|
||||
a.Shapes[op.output] = &Shape{
|
||||
ShapeName: op.output,
|
||||
expected := map[string][]string{}
|
||||
for _, op := range c {
|
||||
o := &Operation{
|
||||
Name: op.operation,
|
||||
ExportedName: op.operation,
|
||||
InputRef: ShapeRef{
|
||||
API: a,
|
||||
ShapeName: op.input,
|
||||
Shape: &Shape{
|
||||
API: a,
|
||||
ShapeName: op.input,
|
||||
},
|
||||
},
|
||||
OutputRef: ShapeRef{
|
||||
API: a,
|
||||
ShapeName: op.input,
|
||||
Shape: &Shape{
|
||||
API: a,
|
||||
ShapeName: op.input,
|
||||
},
|
||||
},
|
||||
}
|
||||
o.InputRef.Shape.refs = append(o.InputRef.Shape.refs, &o.InputRef)
|
||||
o.OutputRef.Shape.refs = append(o.OutputRef.Shape.refs, &o.OutputRef)
|
||||
|
||||
a.Operations[o.Name] = o
|
||||
|
||||
a.Shapes[op.input] = o.InputRef.Shape
|
||||
a.Shapes[op.output] = o.OutputRef.Shape
|
||||
|
||||
expected[op.operation] = append(expected[op.operation],
|
||||
op.expectedInput,
|
||||
op.expectedOutput,
|
||||
)
|
||||
}
|
||||
|
||||
expected[op.operation] = append(expected[op.operation], op.expectedInput)
|
||||
expected[op.operation] = append(expected[op.operation], op.expectedOutput)
|
||||
}
|
||||
|
||||
a.fixStutterNames()
|
||||
a.renameToplevelShapes()
|
||||
for k, v := range expected {
|
||||
if a.Operations[k].InputRef.Shape.ShapeName != v[0] {
|
||||
t.Errorf("Error %d case: Expected %q, but received %q", k, v[0], a.Operations[k].InputRef.Shape.ShapeName)
|
||||
a.fixStutterNames()
|
||||
a.applyShapeNameAliases()
|
||||
a.createInputOutputShapes()
|
||||
for k, v := range expected {
|
||||
if a.Operations[k].InputRef.Shape.ShapeName != v[0] {
|
||||
t.Errorf("Error %s case: Expected %q, but received %q", k, v[0], a.Operations[k].InputRef.Shape.ShapeName)
|
||||
}
|
||||
if a.Operations[k].OutputRef.Shape.ShapeName != v[1] {
|
||||
t.Errorf("Error %s case: Expected %q, but received %q", k, v[1], a.Operations[k].OutputRef.Shape.ShapeName)
|
||||
}
|
||||
}
|
||||
if a.Operations[k].OutputRef.Shape.ShapeName != v[1] {
|
||||
t.Errorf("Error %d case: Expected %q, but received %q", k, v[1], a.Operations[k].OutputRef.Shape.ShapeName)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollidingFields(t *testing.T) {
|
||||
cases := []struct {
|
||||
api *API
|
||||
expected []*Shapes
|
||||
cases := map[string]struct {
|
||||
MemberRefs map[string]*ShapeRef
|
||||
Expect []string
|
||||
IsException bool
|
||||
}{
|
||||
{
|
||||
&API{
|
||||
name: "FooService",
|
||||
Shapes: []*Shapes{
|
||||
{
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"String": &ShapeRef{},
|
||||
"GoString": &ShapeRef{},
|
||||
"Validate": &ShapeRef{},
|
||||
"Foo": &ShapeRef{},
|
||||
"SetFoo": &ShapeRef{},
|
||||
},
|
||||
},
|
||||
},
|
||||
"SimpleMembers": {
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Code": {},
|
||||
"Foo": {},
|
||||
"GoString": {},
|
||||
"Message": {},
|
||||
"OrigErr": {},
|
||||
"SetFoo": {},
|
||||
"String": {},
|
||||
"Validate": {},
|
||||
},
|
||||
[]*Shapes{
|
||||
{
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"String_": &ShapeRef{},
|
||||
"GoString_": &ShapeRef{},
|
||||
"Validate_": &ShapeRef{},
|
||||
"Foo": &ShapeRef{},
|
||||
"SetFoo_": &ShapeRef{},
|
||||
},
|
||||
},
|
||||
Expect: []string{
|
||||
"Code",
|
||||
"Foo",
|
||||
"GoString_",
|
||||
"Message",
|
||||
"OrigErr",
|
||||
"SetFoo_",
|
||||
"String_",
|
||||
"Validate_",
|
||||
},
|
||||
},
|
||||
"ExceptionShape": {
|
||||
IsException: true,
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Code": {},
|
||||
"Message": {},
|
||||
"OrigErr": {},
|
||||
"Other": {},
|
||||
"String": {},
|
||||
},
|
||||
Expect: []string{
|
||||
"Code_",
|
||||
"Message_",
|
||||
"OrigErr_",
|
||||
"Other",
|
||||
"String_",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range testCases {
|
||||
c.api.renameCollidingFields()
|
||||
if !reflect.DeepEqual(c.api.Shapes, c.expected) {
|
||||
t.Errorf("expected %v, but received %v", c.expected, c.api.Shapes)
|
||||
}
|
||||
for k, c := range cases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
a := &API{
|
||||
Shapes: map[string]*Shape{
|
||||
"shapename": {
|
||||
ShapeName: k,
|
||||
MemberRefs: c.MemberRefs,
|
||||
Exception: c.IsException,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a.renameCollidingFields()
|
||||
|
||||
for i, name := range a.Shapes["shapename"].MemberNames() {
|
||||
if e, a := c.Expect[i], name; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInputOutputShapes(t *testing.T) {
|
||||
meta := Metadata{
|
||||
APIVersion: "0000-00-00",
|
||||
EndpointPrefix: "rpcservice",
|
||||
JSONVersion: "1.1",
|
||||
Protocol: "json",
|
||||
ServiceAbbreviation: "RPCService",
|
||||
ServiceFullName: "RPC Service",
|
||||
ServiceID: "RPCService",
|
||||
SignatureVersion: "v4",
|
||||
TargetPrefix: "RPCService_00000000",
|
||||
UID: "RPCService-0000-00-00",
|
||||
}
|
||||
|
||||
type OpExpect struct {
|
||||
Input string
|
||||
Output string
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
API *API
|
||||
ExpectOps map[string]OpExpect
|
||||
ExpectShapes []string
|
||||
}{
|
||||
"allRename": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpResponse"},
|
||||
},
|
||||
"SecondOp": {Name: "SecondOp",
|
||||
InputRef: ShapeRef{ShapeName: "SecondOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "SecondOpResponse"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure"},
|
||||
"FirstOpResponse": {ShapeName: "FirstOpResponse", Type: "structure"},
|
||||
"SecondOpRequest": {ShapeName: "SecondOpRequest", Type: "structure"},
|
||||
"SecondOpResponse": {ShapeName: "SecondOpResponse", Type: "structure"},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
"SecondOp": {
|
||||
Input: "SecondOpInput",
|
||||
Output: "SecondOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
"SecondOpInput", "SecondOpOutput",
|
||||
},
|
||||
},
|
||||
"noRename": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpInput"},
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpOutput"},
|
||||
},
|
||||
"SecondOp": {Name: "SecondOp",
|
||||
InputRef: ShapeRef{ShapeName: "SecondOpInput"},
|
||||
OutputRef: ShapeRef{ShapeName: "SecondOpOutput"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpInput": {ShapeName: "FirstOpInput", Type: "structure"},
|
||||
"FirstOpOutput": {ShapeName: "FirstOpOutput", Type: "structure"},
|
||||
"SecondOpInput": {ShapeName: "SecondOpInput", Type: "structure"},
|
||||
"SecondOpOutput": {ShapeName: "SecondOpOutput", Type: "structure"},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
"SecondOp": {
|
||||
Input: "SecondOpInput",
|
||||
Output: "SecondOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
"SecondOpInput", "SecondOpOutput",
|
||||
},
|
||||
},
|
||||
"renameWithNested": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpWriteMe"},
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpReadMe"},
|
||||
},
|
||||
"SecondOp": {Name: "SecondOp",
|
||||
InputRef: ShapeRef{ShapeName: "SecondOpWriteMe"},
|
||||
OutputRef: ShapeRef{ShapeName: "SecondOpReadMe"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpWriteMe": {ShapeName: "FirstOpWriteMe", Type: "structure",
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Foo": {ShapeName: "String"},
|
||||
},
|
||||
},
|
||||
"FirstOpReadMe": {ShapeName: "FirstOpReadMe", Type: "structure",
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Bar": {ShapeName: "Struct"},
|
||||
"Once": {ShapeName: "Once"},
|
||||
},
|
||||
},
|
||||
"SecondOpWriteMe": {ShapeName: "SecondOpWriteMe", Type: "structure"},
|
||||
"SecondOpReadMe": {ShapeName: "SecondOpReadMe", Type: "structure"},
|
||||
"Once": {ShapeName: "Once", Type: "string"},
|
||||
"String": {ShapeName: "String", Type: "string"},
|
||||
"Struct": {ShapeName: "Struct", Type: "structure",
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Foo": {ShapeName: "String"},
|
||||
"Bar": {ShapeName: "Struct"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
"SecondOp": {
|
||||
Input: "SecondOpInput",
|
||||
Output: "SecondOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
"Once",
|
||||
"SecondOpInput", "SecondOpOutput",
|
||||
"String", "Struct",
|
||||
},
|
||||
},
|
||||
"aliasedInput": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpResponse"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure",
|
||||
AliasedShapeName: true,
|
||||
},
|
||||
"FirstOpResponse": {ShapeName: "FirstOpResponse", Type: "structure"},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpRequest",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpOutput", "FirstOpRequest",
|
||||
},
|
||||
},
|
||||
"aliasedOutput": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpResponse"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure"},
|
||||
"FirstOpResponse": {ShapeName: "FirstOpResponse", Type: "structure",
|
||||
AliasedShapeName: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpResponse",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpResponse",
|
||||
},
|
||||
},
|
||||
"resusedShape": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "ReusedShape"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure",
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Foo": {ShapeName: "ReusedShape"},
|
||||
"ooF": {ShapeName: "ReusedShapeList"},
|
||||
},
|
||||
},
|
||||
"ReusedShape": {ShapeName: "ReusedShape", Type: "structure"},
|
||||
"ReusedShapeList": {ShapeName: "ReusedShapeList", Type: "list",
|
||||
MemberRef: ShapeRef{ShapeName: "ReusedShape"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
"ReusedShape", "ReusedShapeList",
|
||||
},
|
||||
},
|
||||
"aliasedResusedShape": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
OutputRef: ShapeRef{ShapeName: "ReusedShape"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure",
|
||||
MemberRefs: map[string]*ShapeRef{
|
||||
"Foo": {ShapeName: "ReusedShape"},
|
||||
"ooF": {ShapeName: "ReusedShapeList"},
|
||||
},
|
||||
},
|
||||
"ReusedShape": {ShapeName: "ReusedShape", Type: "structure",
|
||||
AliasedShapeName: true,
|
||||
},
|
||||
"ReusedShapeList": {ShapeName: "ReusedShapeList", Type: "list",
|
||||
MemberRef: ShapeRef{ShapeName: "ReusedShape"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "ReusedShape",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput",
|
||||
"ReusedShape", "ReusedShapeList",
|
||||
},
|
||||
},
|
||||
"unsetInput": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
OutputRef: ShapeRef{ShapeName: "FirstOpResponse"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpResponse": {ShapeName: "FirstOpResponse", Type: "structure"},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
"unsetOutput": {
|
||||
API: &API{Metadata: meta,
|
||||
Operations: map[string]*Operation{
|
||||
"FirstOp": {Name: "FirstOp",
|
||||
InputRef: ShapeRef{ShapeName: "FirstOpRequest"},
|
||||
},
|
||||
},
|
||||
Shapes: map[string]*Shape{
|
||||
"FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure"},
|
||||
},
|
||||
},
|
||||
ExpectOps: map[string]OpExpect{
|
||||
"FirstOp": {
|
||||
Input: "FirstOpInput",
|
||||
Output: "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
ExpectShapes: []string{
|
||||
"FirstOpInput", "FirstOpOutput",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
a := c.API
|
||||
a.Setup()
|
||||
|
||||
for opName, op := range a.Operations {
|
||||
if e, a := op.InputRef.ShapeName, op.InputRef.Shape.ShapeName; e != a {
|
||||
t.Errorf("expect input ref and shape names to match, %s, %s", e, a)
|
||||
}
|
||||
if e, a := c.ExpectOps[opName].Input, op.InputRef.ShapeName; e != a {
|
||||
t.Errorf("expect %v input shape, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := op.OutputRef.ShapeName, op.OutputRef.Shape.ShapeName; e != a {
|
||||
t.Errorf("expect output ref and shape names to match, %s, %s", e, a)
|
||||
}
|
||||
if e, a := c.ExpectOps[opName].Output, op.OutputRef.ShapeName; e != a {
|
||||
t.Errorf("expect %v output shape, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
if e, a := c.ExpectShapes, a.ShapeNames(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v shapes, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// S3ManagerUploadInputGoCode returns the Go code for the S3 Upload Manager's
|
||||
// input structure.
|
||||
func S3ManagerUploadInputGoCode(a *API) string {
|
||||
if v := a.PackageName(); v != "s3" {
|
||||
panic(fmt.Sprintf("unexpected API model %s", v))
|
||||
}
|
||||
|
||||
s, ok := a.Shapes["PutObjectInput"]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("unable to find PutObjectInput shape in S3 model"))
|
||||
}
|
||||
|
||||
a.resetImports()
|
||||
a.AddImport("io")
|
||||
a.AddImport("time")
|
||||
|
||||
var w bytes.Buffer
|
||||
if err := s3managerUploadInputTmpl.Execute(&w, s); err != nil {
|
||||
panic(fmt.Sprintf("failed to execute %s template, %v",
|
||||
s3managerUploadInputTmpl.Name(), err))
|
||||
}
|
||||
|
||||
return a.importsGoCode() + w.String()
|
||||
}
|
||||
|
||||
var s3managerUploadInputTmpl = template.Must(
|
||||
template.New("s3managerUploadInputTmpl").
|
||||
Funcs(template.FuncMap{
|
||||
"GetDeprecatedMsg": getDeprecatedMessage,
|
||||
}).
|
||||
Parse(s3managerUploadInputTmplDef),
|
||||
)
|
||||
|
||||
const s3managerUploadInputTmplDef = `
|
||||
// UploadInput provides the input parameters for uploading a stream or buffer
|
||||
// to an object in an Amazon S3 bucket. This type is similar to the s3
|
||||
// package's PutObjectInput with the exception that the Body member is an
|
||||
// io.Reader instead of an io.ReadSeeker.
|
||||
type UploadInput struct {
|
||||
_ struct{} {{ .GoTags true false }}
|
||||
|
||||
{{ range $name, $ref := $.MemberRefs -}}
|
||||
{{ if eq $name "Body" }}
|
||||
// The readable body payload to send to S3.
|
||||
Body io.Reader
|
||||
{{ else if eq $name "ContentLength" }}
|
||||
{{/* S3 Upload Manager does not use modeled content length */}}
|
||||
{{ else }}
|
||||
{{ $isBlob := $.WillRefBeBase64Encoded $name -}}
|
||||
{{ $isRequired := $.IsRequired $name -}}
|
||||
{{ $doc := $ref.Docstring -}}
|
||||
|
||||
{{ if $doc -}}
|
||||
{{ $doc }}
|
||||
{{ if $ref.Deprecated -}}
|
||||
//
|
||||
// Deprecated: {{ GetDeprecatedMsg $ref.DeprecatedMsg $name }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ if $isBlob -}}
|
||||
{{ if $doc -}}
|
||||
//
|
||||
{{ end -}}
|
||||
// {{ $name }} is automatically base64 encoded/decoded by the SDK.
|
||||
{{ end -}}
|
||||
{{ if $isRequired -}}
|
||||
{{ if or $doc $isBlob -}}
|
||||
//
|
||||
{{ end -}}
|
||||
// {{ $name }} is a required field
|
||||
{{ end -}}
|
||||
{{ $name }} {{ $.GoStructType $name $ref }} {{ $ref.GoTags false $isRequired }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
`
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
// ServiceName returns the SDK's naming of the service. Has
|
||||
// backwards compatibility built in for services that were
|
||||
// incorrectly named with the service's endpoint prefix.
|
||||
func ServiceName(a *API) string {
|
||||
if oldName, ok := oldServiceNames[a.PackageName()]; ok {
|
||||
return oldName
|
||||
}
|
||||
|
||||
return ServiceID(a)
|
||||
}
|
||||
|
||||
var oldServiceNames = map[string]string{
|
||||
"migrationhub": "mgh",
|
||||
"acmpca": "acm-pca",
|
||||
"acm": "acm",
|
||||
"alexaforbusiness": "a4b",
|
||||
"apigateway": "apigateway",
|
||||
"applicationautoscaling": "autoscaling",
|
||||
"appstream": "appstream2",
|
||||
"appsync": "appsync",
|
||||
"athena": "athena",
|
||||
"autoscalingplans": "autoscaling",
|
||||
"autoscaling": "autoscaling",
|
||||
"batch": "batch",
|
||||
"budgets": "budgets",
|
||||
"costexplorer": "ce",
|
||||
"cloud9": "cloud9",
|
||||
"clouddirectory": "clouddirectory",
|
||||
"cloudformation": "cloudformation",
|
||||
"cloudfront": "cloudfront",
|
||||
"cloudhsm": "cloudhsm",
|
||||
"cloudhsmv2": "cloudhsmv2",
|
||||
"cloudsearch": "cloudsearch",
|
||||
"cloudsearchdomain": "cloudsearchdomain",
|
||||
"cloudtrail": "cloudtrail",
|
||||
"codebuild": "codebuild",
|
||||
"codecommit": "codecommit",
|
||||
"codedeploy": "codedeploy",
|
||||
"codepipeline": "codepipeline",
|
||||
"codestar": "codestar",
|
||||
"cognitoidentity": "cognito-identity",
|
||||
"cognitoidentityprovider": "cognito-idp",
|
||||
"cognitosync": "cognito-sync",
|
||||
"comprehend": "comprehend",
|
||||
"configservice": "config",
|
||||
"connect": "connect",
|
||||
"costandusagereportservice": "cur",
|
||||
"datapipeline": "datapipeline",
|
||||
"dax": "dax",
|
||||
"devicefarm": "devicefarm",
|
||||
"directconnect": "directconnect",
|
||||
"applicationdiscoveryservice": "discovery",
|
||||
"databasemigrationservice": "dms",
|
||||
"directoryservice": "ds",
|
||||
"dynamodb": "dynamodb",
|
||||
"ec2": "ec2",
|
||||
"ecr": "ecr",
|
||||
"ecs": "ecs",
|
||||
"eks": "eks",
|
||||
"elasticache": "elasticache",
|
||||
"elasticbeanstalk": "elasticbeanstalk",
|
||||
"efs": "elasticfilesystem",
|
||||
"elb": "elasticloadbalancing",
|
||||
"elbv2": "elasticloadbalancing",
|
||||
"emr": "elasticmapreduce",
|
||||
"elastictranscoder": "elastictranscoder",
|
||||
"ses": "email",
|
||||
"marketplaceentitlementservice": "entitlement.marketplace",
|
||||
"elasticsearchservice": "es",
|
||||
"cloudwatchevents": "events",
|
||||
"firehose": "firehose",
|
||||
"fms": "fms",
|
||||
"gamelift": "gamelift",
|
||||
"glacier": "glacier",
|
||||
"glue": "glue",
|
||||
"greengrass": "greengrass",
|
||||
"guardduty": "guardduty",
|
||||
"health": "health",
|
||||
"iam": "iam",
|
||||
"inspector": "inspector",
|
||||
"iotdataplane": "data.iot",
|
||||
"iotjobsdataplane": "data.jobs.iot",
|
||||
"iot": "iot",
|
||||
"iot1clickdevicesservice": "devices.iot1click",
|
||||
"iot1clickprojects": "projects.iot1click",
|
||||
"iotanalytics": "iotanalytics",
|
||||
"kinesisvideoarchivedmedia": "kinesisvideo",
|
||||
"kinesisvideomedia": "kinesisvideo",
|
||||
"kinesis": "kinesis",
|
||||
"kinesisanalytics": "kinesisanalytics",
|
||||
"kinesisvideo": "kinesisvideo",
|
||||
"kms": "kms",
|
||||
"lambda": "lambda",
|
||||
"lexmodelbuildingservice": "models.lex",
|
||||
"lightsail": "lightsail",
|
||||
"cloudwatchlogs": "logs",
|
||||
"machinelearning": "machinelearning",
|
||||
"marketplacecommerceanalytics": "marketplacecommerceanalytics",
|
||||
"mediaconvert": "mediaconvert",
|
||||
"medialive": "medialive",
|
||||
"mediapackage": "mediapackage",
|
||||
"mediastoredata": "data.mediastore",
|
||||
"mediastore": "mediastore",
|
||||
"mediatailor": "api.mediatailor",
|
||||
"marketplacemetering": "metering.marketplace",
|
||||
"mobile": "mobile",
|
||||
"mobileanalytics": "mobileanalytics",
|
||||
"cloudwatch": "monitoring",
|
||||
"mq": "mq",
|
||||
"mturk": "mturk-requester",
|
||||
"neptune": "rds",
|
||||
"opsworks": "opsworks",
|
||||
"opsworkscm": "opsworks-cm",
|
||||
"organizations": "organizations",
|
||||
"pi": "pi",
|
||||
"pinpoint": "pinpoint",
|
||||
"polly": "polly",
|
||||
"pricing": "api.pricing",
|
||||
"rds": "rds",
|
||||
"redshift": "redshift",
|
||||
"rekognition": "rekognition",
|
||||
"resourcegroups": "resource-groups",
|
||||
"resourcegroupstaggingapi": "tagging",
|
||||
"route53": "route53",
|
||||
"route53domains": "route53domains",
|
||||
"lexruntimeservice": "runtime.lex",
|
||||
"sagemakerruntime": "runtime.sagemaker",
|
||||
"s3": "s3",
|
||||
"sagemaker": "sagemaker",
|
||||
"simpledb": "sdb",
|
||||
"secretsmanager": "secretsmanager",
|
||||
"serverlessapplicationrepository": "serverlessrepo",
|
||||
"servicecatalog": "servicecatalog",
|
||||
"servicediscovery": "servicediscovery",
|
||||
"shield": "shield",
|
||||
"sms": "sms",
|
||||
"snowball": "snowball",
|
||||
"sns": "sns",
|
||||
"sqs": "sqs",
|
||||
"ssm": "ssm",
|
||||
"sfn": "states",
|
||||
"storagegateway": "storagegateway",
|
||||
"dynamodbstreams": "streams.dynamodb",
|
||||
"sts": "sts",
|
||||
"support": "support",
|
||||
"swf": "swf",
|
||||
"transcribeservice": "transcribe",
|
||||
"translate": "translate",
|
||||
"wafregional": "waf-regional",
|
||||
"waf": "waf",
|
||||
"workdocs": "workdocs",
|
||||
"workmail": "workmail",
|
||||
"workspaces": "workspaces",
|
||||
"xray": "xray",
|
||||
}
|
||||
+314
-77
@@ -10,8 +10,23 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// ErrorInfo represents the error block of a shape's structure
|
||||
type ErrorInfo struct {
|
||||
Type string
|
||||
Code string
|
||||
HTTPStatusCode int
|
||||
}
|
||||
|
||||
// A XMLInfo defines URL and prefix for Shapes when rendered as XML
|
||||
type XMLInfo struct {
|
||||
Prefix string
|
||||
URI string
|
||||
}
|
||||
|
||||
// A ShapeRef defines the usage of a shape within the API.
|
||||
type ShapeRef struct {
|
||||
API *API `json:"-"`
|
||||
@@ -25,28 +40,26 @@ type ShapeRef struct {
|
||||
Streaming bool
|
||||
XMLAttribute bool
|
||||
// Ignore, if set, will not be sent over the wire
|
||||
Ignore bool
|
||||
XMLNamespace XMLInfo
|
||||
Payload string
|
||||
IdempotencyToken bool `json:"idempotencyToken"`
|
||||
JSONValue bool `json:"jsonvalue"`
|
||||
Deprecated bool `json:"deprecated"`
|
||||
Ignore bool
|
||||
XMLNamespace XMLInfo
|
||||
Payload string
|
||||
IdempotencyToken bool `json:"idempotencyToken"`
|
||||
TimestampFormat string `json:"timestampFormat"`
|
||||
JSONValue bool `json:"jsonvalue"`
|
||||
Deprecated bool `json:"deprecated"`
|
||||
DeprecatedMsg string `json:"deprecatedMessage"`
|
||||
EndpointDiscoveryID bool `json:"endpointdiscoveryid"`
|
||||
HostLabel bool `json:"hostLabel"`
|
||||
|
||||
OrigShapeName string `json:"-"`
|
||||
|
||||
GenerateGetter bool
|
||||
}
|
||||
|
||||
// ErrorInfo represents the error block of a shape's structure
|
||||
type ErrorInfo struct {
|
||||
Code string
|
||||
HTTPStatusCode int
|
||||
}
|
||||
IsEventPayload bool `json:"eventpayload"`
|
||||
IsEventHeader bool `json:"eventheader"`
|
||||
|
||||
// A XMLInfo defines URL and prefix for Shapes when rendered as XML
|
||||
type XMLInfo struct {
|
||||
Prefix string
|
||||
URI string
|
||||
// Collection of custom tags the shape reference includes.
|
||||
CustomTags ShapeTags
|
||||
}
|
||||
|
||||
// A Shape defines the definition of a shape type
|
||||
@@ -68,12 +81,17 @@ type Shape struct {
|
||||
Streaming bool
|
||||
Location string
|
||||
LocationName string
|
||||
IdempotencyToken bool `json:"idempotencyToken"`
|
||||
IdempotencyToken bool `json:"idempotencyToken"`
|
||||
TimestampFormat string `json:"timestampFormat"`
|
||||
XMLNamespace XMLInfo
|
||||
Min float64 // optional Minimum length (string, list) or value (number)
|
||||
Max float64 // optional Maximum length (string, list) or value (number)
|
||||
|
||||
EventStreamsMemberName string `json:"-"`
|
||||
EventStreamAPI *EventStreamAPI `json:"-"`
|
||||
EventFor []*EventStream `json:"-"`
|
||||
|
||||
IsEventStream bool `json:"eventstream"`
|
||||
IsEvent bool `json:"event"`
|
||||
|
||||
refs []*ShapeRef // References to this shape
|
||||
resolvePkg string // use this package in the goType() if present
|
||||
@@ -83,13 +101,34 @@ type Shape struct {
|
||||
// Defines if the shape is a placeholder and should not be used directly
|
||||
Placeholder bool
|
||||
|
||||
Deprecated bool `json:"deprecated"`
|
||||
Deprecated bool `json:"deprecated"`
|
||||
DeprecatedMsg string `json:"deprecatedMessage"`
|
||||
|
||||
Validations ShapeValidations
|
||||
|
||||
// Error information that is set if the shape is an error shape.
|
||||
IsError bool
|
||||
ErrorInfo ErrorInfo `json:"error"`
|
||||
|
||||
// Flags that the shape cannot be rename. Prevents the shape from being
|
||||
// renamed further by the Input/Output.
|
||||
AliasedShapeName bool
|
||||
|
||||
// Sensitive types should not be logged by SDK type loggers.
|
||||
Sensitive bool `json:"sensitive"`
|
||||
}
|
||||
|
||||
// CanBeEmpty returns if the shape value can sent request as an empty value.
|
||||
// String, blob, list, and map are types must not be empty when the member is
|
||||
// serialized to the uri path, or decorated with HostLabel.
|
||||
func (ref *ShapeRef) CanBeEmpty() bool {
|
||||
switch ref.Shape.Type {
|
||||
case "string":
|
||||
return !(ref.Location == "uri" || ref.HostLabel)
|
||||
case "blob", "map", "list":
|
||||
return !(ref.Location == "uri")
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorCodeName will return the error shape's name formated for
|
||||
@@ -101,7 +140,7 @@ func (s *Shape) ErrorCodeName() string {
|
||||
// ErrorName will return the shape's name or error code if available based
|
||||
// on the API's protocol. This is the error code string returned by the service.
|
||||
func (s *Shape) ErrorName() string {
|
||||
name := s.ShapeName
|
||||
name := s.ErrorInfo.Type
|
||||
switch s.API.Metadata.Protocol {
|
||||
case "query", "ec2query", "rest-xml":
|
||||
if len(s.ErrorInfo.Code) > 0 {
|
||||
@@ -109,9 +148,33 @@ func (s *Shape) ErrorName() string {
|
||||
}
|
||||
}
|
||||
|
||||
if len(name) == 0 {
|
||||
name = s.OrigShapeName
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = s.ShapeName
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// PayloadRefName returns the payload member of the shape if there is one
|
||||
// modeled. If no payload is modeled, empty string will be returned.
|
||||
func (s *Shape) PayloadRefName() string {
|
||||
if name := s.Payload; len(name) != 0 {
|
||||
// Root shape
|
||||
return name
|
||||
}
|
||||
|
||||
for name, ref := range s.MemberRefs {
|
||||
if ref.IsEventPayload {
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GoTags returns the struct tags for a shape.
|
||||
func (s *Shape) GoTags(root, required bool) string {
|
||||
ref := &ShapeRef{ShapeName: s.ShapeName, API: s.API, Shape: s}
|
||||
@@ -121,6 +184,11 @@ func (s *Shape) GoTags(root, required bool) string {
|
||||
// Rename changes the name of the Shape to newName. Also updates
|
||||
// the associated API's reference to use newName.
|
||||
func (s *Shape) Rename(newName string) {
|
||||
if s.AliasedShapeName {
|
||||
panic(fmt.Sprintf("attempted to rename %s, but flagged as aliased",
|
||||
s.ShapeName))
|
||||
}
|
||||
|
||||
for _, r := range s.refs {
|
||||
r.OrigShapeName = r.ShapeName
|
||||
r.ShapeName = newName
|
||||
@@ -143,12 +211,21 @@ func (s *Shape) MemberNames() []string {
|
||||
return names
|
||||
}
|
||||
|
||||
// HasMember will return whether or not the shape has a given
|
||||
// member by name.
|
||||
func (s *Shape) HasMember(name string) bool {
|
||||
_, ok := s.MemberRefs[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
// GoTypeWithPkgName returns a shape's type as a string with the package name in
|
||||
// <packageName>.<type> format. Package naming only applies to structures.
|
||||
func (s *Shape) GoTypeWithPkgName() string {
|
||||
return goType(s, true)
|
||||
}
|
||||
|
||||
// GoTypeWithPkgNameElem returns the shapes type as a string with the "*"
|
||||
// removed if there was one preset.
|
||||
func (s *Shape) GoTypeWithPkgNameElem() string {
|
||||
t := goType(s, true)
|
||||
if strings.HasPrefix(t, "*") {
|
||||
@@ -157,7 +234,7 @@ func (s *Shape) GoTypeWithPkgNameElem() string {
|
||||
return t
|
||||
}
|
||||
|
||||
// GenAccessors returns if the shape's reference should have setters generated.
|
||||
// UseIndirection returns if the shape's reference should use indirection or not.
|
||||
func (s *ShapeRef) UseIndirection() bool {
|
||||
switch s.Shape.Type {
|
||||
case "map", "list", "blob", "structure", "jsonvalue":
|
||||
@@ -175,6 +252,32 @@ func (s *ShapeRef) UseIndirection() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s Shape) GetTimestampFormat() string {
|
||||
format := s.TimestampFormat
|
||||
|
||||
if len(format) > 0 && !protocol.IsKnownTimestampFormat(format) {
|
||||
panic(fmt.Sprintf("Unknown timestampFormat %s, for %s",
|
||||
format, s.ShapeName))
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
func (ref ShapeRef) GetTimestampFormat() string {
|
||||
format := ref.TimestampFormat
|
||||
|
||||
if len(format) == 0 {
|
||||
format = ref.Shape.TimestampFormat
|
||||
}
|
||||
|
||||
if len(format) > 0 && !protocol.IsKnownTimestampFormat(format) {
|
||||
panic(fmt.Sprintf("Unknown timestampFormat %s, for %s",
|
||||
format, ref.ShapeName))
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
// GoStructValueType returns the Shape's Go type value instead of a pointer
|
||||
// for the type.
|
||||
func (s *Shape) GoStructValueType(name string, ref *ShapeRef) string {
|
||||
@@ -201,7 +304,7 @@ func (s *Shape) GoStructType(name string, ref *ShapeRef) string {
|
||||
}
|
||||
|
||||
if ref.JSONValue {
|
||||
s.API.imports["github.com/aws/aws-sdk-go/aws"] = true
|
||||
s.API.AddSDKImport("aws")
|
||||
return "aws.JSONValue"
|
||||
}
|
||||
|
||||
@@ -267,7 +370,7 @@ func goType(s *Shape, withPkgName bool) string {
|
||||
return "*string"
|
||||
case "blob":
|
||||
return "[]byte"
|
||||
case "integer", "long":
|
||||
case "byte", "short", "integer", "long":
|
||||
return "*int64"
|
||||
case "float", "double":
|
||||
return "*float64"
|
||||
@@ -334,18 +437,23 @@ func (s ShapeTags) String() string {
|
||||
|
||||
// GoTags returns the rendered tags string for the ShapeRef
|
||||
func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string {
|
||||
tags := ShapeTags{}
|
||||
tags := append(ShapeTags{}, ref.CustomTags...)
|
||||
|
||||
if ref.Location != "" {
|
||||
tags = append(tags, ShapeTag{"location", ref.Location})
|
||||
} else if ref.Shape.Location != "" {
|
||||
tags = append(tags, ShapeTag{"location", ref.Shape.Location})
|
||||
} else if ref.IsEventHeader {
|
||||
tags = append(tags, ShapeTag{"location", "header"})
|
||||
}
|
||||
|
||||
if ref.LocationName != "" {
|
||||
tags = append(tags, ShapeTag{"locationName", ref.LocationName})
|
||||
} else if ref.Shape.LocationName != "" {
|
||||
tags = append(tags, ShapeTag{"locationName", ref.Shape.LocationName})
|
||||
} else if len(ref.Shape.EventFor) != 0 && ref.API.Metadata.Protocol == "rest-xml" {
|
||||
// RPC JSON events need to have location name modeled for round trip testing.
|
||||
tags = append(tags, ShapeTag{"locationName", ref.Shape.ShapeName})
|
||||
}
|
||||
|
||||
if ref.QueryName != "" {
|
||||
@@ -373,18 +481,12 @@ func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string {
|
||||
|
||||
// embed the timestamp type for easier lookups
|
||||
if ref.Shape.Type == "timestamp" {
|
||||
t := ShapeTag{Key: "timestampFormat"}
|
||||
if ref.Location == "header" {
|
||||
t.Val = "rfc822"
|
||||
} else {
|
||||
switch ref.API.Metadata.Protocol {
|
||||
case "json", "rest-json":
|
||||
t.Val = "unix"
|
||||
case "rest-xml", "ec2", "query":
|
||||
t.Val = "iso8601"
|
||||
}
|
||||
if format := ref.GetTimestampFormat(); len(format) > 0 {
|
||||
tags = append(tags, ShapeTag{
|
||||
Key: "timestampFormat",
|
||||
Val: format,
|
||||
})
|
||||
}
|
||||
tags = append(tags, t)
|
||||
}
|
||||
|
||||
if ref.Shape.Flattened || ref.Flattened {
|
||||
@@ -401,8 +503,8 @@ func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string {
|
||||
}
|
||||
|
||||
if toplevel {
|
||||
if ref.Shape.Payload != "" {
|
||||
tags = append(tags, ShapeTag{"payload", ref.Shape.Payload})
|
||||
if name := ref.Shape.PayloadRefName(); len(name) > 0 {
|
||||
tags = append(tags, ShapeTag{"payload", name})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,6 +528,10 @@ func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string {
|
||||
tags = append(tags, ShapeTag{"ignore", "true"})
|
||||
}
|
||||
|
||||
if ref.Shape.Sensitive {
|
||||
tags = append(tags, ShapeTag{"sensitive", "true"})
|
||||
}
|
||||
|
||||
return fmt.Sprintf("`%s`", tags)
|
||||
}
|
||||
|
||||
@@ -514,10 +620,49 @@ func (s *Shape) NestedShape() *Shape {
|
||||
return nestedShape
|
||||
}
|
||||
|
||||
var structShapeTmpl = template.Must(template.New("StructShape").Funcs(template.FuncMap{
|
||||
"GetCrosslinkURL": GetCrosslinkURL,
|
||||
}).Parse(`
|
||||
var structShapeTmpl = func() *template.Template {
|
||||
shapeTmpl := template.Must(
|
||||
template.New("structShapeTmpl").
|
||||
Funcs(template.FuncMap{
|
||||
"GetCrosslinkURL": GetCrosslinkURL,
|
||||
"GetDeprecatedMsg": getDeprecatedMessage,
|
||||
}).
|
||||
Parse(structShapeTmplDef),
|
||||
)
|
||||
|
||||
template.Must(
|
||||
shapeTmpl.AddParseTree(
|
||||
"eventStreamAPILoopMethodTmpl", eventStreamAPILoopMethodTmpl.Tree),
|
||||
)
|
||||
|
||||
template.Must(
|
||||
shapeTmpl.AddParseTree(
|
||||
"eventStreamEventShapeTmpl", eventStreamEventShapeTmpl.Tree),
|
||||
)
|
||||
template.Must(
|
||||
shapeTmpl.AddParseTree(
|
||||
"eventStreamExceptionEventShapeTmpl",
|
||||
eventStreamExceptionEventShapeTmpl.Tree),
|
||||
)
|
||||
shapeTmpl.Funcs(eventStreamEventShapeTmplFuncs)
|
||||
|
||||
template.Must(
|
||||
shapeTmpl.AddParseTree(
|
||||
"hostLabelsShapeTmpl",
|
||||
hostLabelsShapeTmpl.Tree),
|
||||
)
|
||||
|
||||
return shapeTmpl
|
||||
}()
|
||||
|
||||
const structShapeTmplDef = `
|
||||
{{ .Docstring }}
|
||||
{{ if .Deprecated -}}
|
||||
{{ if .Docstring -}}
|
||||
//
|
||||
{{ end -}}
|
||||
// Deprecated: {{ GetDeprecatedMsg .DeprecatedMsg .ShapeName }}
|
||||
{{ end -}}
|
||||
{{ $context := . -}}
|
||||
type {{ .ShapeName }} struct {
|
||||
_ struct{} {{ .GoTags true false }}
|
||||
@@ -530,6 +675,10 @@ type {{ .ShapeName }} struct {
|
||||
|
||||
{{ if $doc -}}
|
||||
{{ $doc }}
|
||||
{{ if $elem.Deprecated -}}
|
||||
//
|
||||
// Deprecated: {{ GetDeprecatedMsg $elem.DeprecatedMsg $name }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ if $isBlob -}}
|
||||
{{ if $doc -}}
|
||||
@@ -550,45 +699,58 @@ type {{ .ShapeName }} struct {
|
||||
{{ if not .API.NoStringerMethods }}
|
||||
{{ .GoCodeStringers }}
|
||||
{{ end }}
|
||||
{{ if not .API.NoValidataShapeMethods }}
|
||||
{{ if not (or .API.NoValidataShapeMethods .Exception) }}
|
||||
{{ if .Validations -}}
|
||||
{{ .Validations.GoCode . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if not .API.NoGenStructFieldAccessors }}
|
||||
{{ if not (or .API.NoGenStructFieldAccessors .Exception) }}
|
||||
{{ $builderShapeName := print .ShapeName -}}
|
||||
{{ range $_, $name := $context.MemberNames -}}
|
||||
{{ $elem := index $context.MemberRefs $name -}}
|
||||
|
||||
{{ $builderShapeName := print .ShapeName -}}
|
||||
|
||||
{{ range $_, $name := $context.MemberNames -}}
|
||||
{{ $elem := index $context.MemberRefs $name -}}
|
||||
|
||||
// Set{{ $name }} sets the {{ $name }} field's value.
|
||||
func (s *{{ $builderShapeName }}) Set{{ $name }}(v {{ $context.GoStructValueType $name $elem }}) *{{ $builderShapeName }} {
|
||||
{{ if $elem.UseIndirection -}}
|
||||
s.{{ $name }} = &v
|
||||
{{ else -}}
|
||||
s.{{ $name }} = v
|
||||
{{ end -}}
|
||||
return s
|
||||
}
|
||||
|
||||
{{ if $elem.GenerateGetter -}}
|
||||
func (s *{{ $builderShapeName }}) get{{ $name }}() (v {{ $context.GoStructValueType $name $elem }}) {
|
||||
{{ if $elem.UseIndirection -}}
|
||||
if s.{{ $name }} == nil {
|
||||
return v
|
||||
// Set{{ $name }} sets the {{ $name }} field's value.
|
||||
func (s *{{ $builderShapeName }}) Set{{ $name }}(v {{ $context.GoStructValueType $name $elem }}) *{{ $builderShapeName }} {
|
||||
{{ if $elem.UseIndirection -}}
|
||||
s.{{ $name }} = &v
|
||||
{{ else -}}
|
||||
s.{{ $name }} = v
|
||||
{{ end -}}
|
||||
return s
|
||||
}
|
||||
return *s.{{ $name }}
|
||||
{{ else -}}
|
||||
return s.{{ $name }}
|
||||
{{ end -}}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ if $elem.GenerateGetter -}}
|
||||
func (s *{{ $builderShapeName }}) get{{ $name }}() (v {{ $context.GoStructValueType $name $elem }}) {
|
||||
{{ if $elem.UseIndirection -}}
|
||||
if s.{{ $name }} == nil {
|
||||
return v
|
||||
}
|
||||
return *s.{{ $name }}
|
||||
{{ else -}}
|
||||
return s.{{ $name }}
|
||||
{{ end -}}
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if $.EventStreamsMemberName }}
|
||||
{{ template "eventStreamAPILoopMethodTmpl" $ }}
|
||||
{{ end }}
|
||||
`))
|
||||
|
||||
{{ if $.EventFor }}
|
||||
{{ template "eventStreamEventShapeTmpl" $ }}
|
||||
|
||||
{{- if $.Exception }}
|
||||
{{ template "eventStreamExceptionEventShapeTmpl" $ }}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ if $.HasHostLabelMembers }}
|
||||
{{ template "hostLabelsShapeTmpl" $ }}
|
||||
{{ end }}
|
||||
`
|
||||
|
||||
var enumShapeTmpl = template.Must(template.New("EnumShape").Parse(`
|
||||
{{ .Docstring }}
|
||||
@@ -605,22 +767,38 @@ const (
|
||||
|
||||
// GoCode returns the rendered Go code for the Shape.
|
||||
func (s *Shape) GoCode() string {
|
||||
b := &bytes.Buffer{}
|
||||
w := &bytes.Buffer{}
|
||||
|
||||
switch {
|
||||
case s.EventStreamAPI != nil:
|
||||
if err := renderEventStreamAPIShape(w, s); err != nil {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"failed to generate eventstream API shape, %s, %v",
|
||||
s.ShapeName, err),
|
||||
)
|
||||
}
|
||||
case s.Type == "structure":
|
||||
if err := structShapeTmpl.Execute(b, s); err != nil {
|
||||
panic(fmt.Sprintf("Failed to generate struct shape %s, %v\n", s.ShapeName, err))
|
||||
if err := structShapeTmpl.Execute(w, s); err != nil {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"Failed to generate struct shape %s, %v",
|
||||
s.ShapeName, err),
|
||||
)
|
||||
}
|
||||
case s.IsEnum():
|
||||
if err := enumShapeTmpl.Execute(b, s); err != nil {
|
||||
panic(fmt.Sprintf("Failed to generate enum shape %s, %v\n", s.ShapeName, err))
|
||||
if err := enumShapeTmpl.Execute(w, s); err != nil {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
"Failed to generate enum shape %s, %v",
|
||||
s.ShapeName, err),
|
||||
)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintln("Cannot generate toplevel shape for", s.Type))
|
||||
}
|
||||
|
||||
return b.String()
|
||||
return w.String()
|
||||
}
|
||||
|
||||
// IsEnum returns whether this shape is an enum list
|
||||
@@ -628,8 +806,22 @@ func (s *Shape) IsEnum() bool {
|
||||
return s.Type == "string" && len(s.Enum) > 0
|
||||
}
|
||||
|
||||
// IsRequired returns if member is a required field.
|
||||
// IsRequired returns if member is a required field. Required fields are fields
|
||||
// marked as required, hostLabels, or location of uri path.
|
||||
func (s *Shape) IsRequired(member string) bool {
|
||||
ref, ok := s.MemberRefs[member]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf(
|
||||
"attempted to check required for unknown member, %s.%s",
|
||||
s.ShapeName, member,
|
||||
))
|
||||
}
|
||||
if ref.IdempotencyToken || ref.Shape.IdempotencyToken {
|
||||
return false
|
||||
}
|
||||
if ref.Location == "uri" || ref.HostLabel {
|
||||
return true
|
||||
}
|
||||
for _, n := range s.Required {
|
||||
if n == member {
|
||||
return true
|
||||
@@ -673,3 +865,48 @@ func (s *Shape) WillRefBeBase64Encoded(refName string) bool {
|
||||
|
||||
return ref.Shape.Type == "blob"
|
||||
}
|
||||
|
||||
// Clone returns a cloned version of the shape with all references clones.
|
||||
//
|
||||
// Does not clone EventStream or Validate related values.
|
||||
func (s *Shape) Clone(newName string) *Shape {
|
||||
if s.AliasedShapeName {
|
||||
panic(fmt.Sprintf("attempted to clone and rename %s, but flagged as aliased",
|
||||
s.ShapeName))
|
||||
}
|
||||
|
||||
n := new(Shape)
|
||||
*n = *s
|
||||
|
||||
debugLogger.Logln("cloning", s.ShapeName, "to", newName)
|
||||
|
||||
n.MemberRefs = map[string]*ShapeRef{}
|
||||
for k, r := range s.MemberRefs {
|
||||
nr := new(ShapeRef)
|
||||
*nr = *r
|
||||
nr.Shape.refs = append(nr.Shape.refs, nr)
|
||||
n.MemberRefs[k] = nr
|
||||
}
|
||||
|
||||
if n.MemberRef.Shape != nil {
|
||||
n.MemberRef.Shape.refs = append(n.MemberRef.Shape.refs, &n.MemberRef)
|
||||
}
|
||||
if n.KeyRef.Shape != nil {
|
||||
n.KeyRef.Shape.refs = append(n.KeyRef.Shape.refs, &n.KeyRef)
|
||||
}
|
||||
if n.ValueRef.Shape != nil {
|
||||
n.ValueRef.Shape.refs = append(n.ValueRef.Shape.refs, &n.ValueRef)
|
||||
}
|
||||
|
||||
n.refs = []*ShapeRef{}
|
||||
|
||||
n.Required = append([]string{}, n.Required...)
|
||||
n.Enum = append([]string{}, n.Enum...)
|
||||
n.EnumConsts = append([]string{}, n.EnumConsts...)
|
||||
|
||||
n.OrigShapeName = n.ShapeName
|
||||
n.API.Shapes[newName] = n
|
||||
n.ShapeName = newName
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package api
|
||||
|
||||
var shapeNameAliases = map[string]map[string]string{
|
||||
"APIGateway": map[string]string{
|
||||
"RequestValidator": "UpdateRequestValidatorOutput",
|
||||
"VpcLink": "UpdateVpcLinkOutput",
|
||||
"GatewayResponse": "UpdateGatewayResponseOutput",
|
||||
},
|
||||
"Lambda": map[string]string{
|
||||
"Concurrency": "PutFunctionConcurrencyOutput",
|
||||
},
|
||||
"Neptune": map[string]string{
|
||||
"DBClusterParameterGroupNameMessage": "ResetDBClusterParameterGroupOutput",
|
||||
"DBParameterGroupNameMessage": "ResetDBParameterGroupOutput",
|
||||
},
|
||||
"RDS": map[string]string{
|
||||
"DBClusterBacktrack": "BacktrackDBClusterOutput",
|
||||
},
|
||||
}
|
||||
+24
-10
@@ -35,29 +35,43 @@ type ShapeValidation struct {
|
||||
Type ShapeValidationType
|
||||
}
|
||||
|
||||
var validationGoCodeTmpls = template.Must(template.New("validationGoCodeTmpls").Parse(`
|
||||
var validationGoCodeTmpls = template.Must(
|
||||
template.New("validationGoCodeTmpls").
|
||||
Funcs(template.FuncMap{
|
||||
"getMin": func(ref *ShapeRef) float64 {
|
||||
if !ref.CanBeEmpty() && ref.Shape.Min <= 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return ref.Shape.Min
|
||||
},
|
||||
}).
|
||||
Parse(`
|
||||
{{ define "requiredValue" -}}
|
||||
if s.{{ .Name }} == nil {
|
||||
if s.{{ .Name }} == nil {
|
||||
invalidParams.Add(request.NewErrParamRequired("{{ .Name }}"))
|
||||
}
|
||||
{{- end }}
|
||||
{{ define "minLen" -}}
|
||||
if s.{{ .Name }} != nil && len(s.{{ .Name }}) < {{ .Ref.Shape.Min }} {
|
||||
invalidParams.Add(request.NewErrParamMinLen("{{ .Name }}", {{ .Ref.Shape.Min }}))
|
||||
{{- $min := getMin .Ref -}}
|
||||
if s.{{ .Name }} != nil && len(s.{{ .Name }}) < {{ $min }} {
|
||||
invalidParams.Add(request.NewErrParamMinLen("{{ .Name }}", {{ $min }}))
|
||||
}
|
||||
{{- end }}
|
||||
{{ define "minLenString" -}}
|
||||
if s.{{ .Name }} != nil && len(*s.{{ .Name }}) < {{ .Ref.Shape.Min }} {
|
||||
invalidParams.Add(request.NewErrParamMinLen("{{ .Name }}", {{ .Ref.Shape.Min }}))
|
||||
{{- $min := getMin .Ref -}}
|
||||
if s.{{ .Name }} != nil && len(*s.{{ .Name }}) < {{ $min }} {
|
||||
invalidParams.Add(request.NewErrParamMinLen("{{ .Name }}", {{ $min }}))
|
||||
}
|
||||
{{- end }}
|
||||
{{ define "minVal" -}}
|
||||
if s.{{ .Name }} != nil && *s.{{ .Name }} < {{ .Ref.Shape.Min }} {
|
||||
invalidParams.Add(request.NewErrParamMinValue("{{ .Name }}", {{ .Ref.Shape.Min }}))
|
||||
{{- $min := getMin .Ref -}}
|
||||
if s.{{ .Name }} != nil && *s.{{ .Name }} < {{ $min }} {
|
||||
invalidParams.Add(request.NewErrParamMinValue("{{ .Name }}", {{ $min }}))
|
||||
}
|
||||
{{- end }}
|
||||
{{ define "nestedMapList" -}}
|
||||
if s.{{ .Name }} != nil {
|
||||
if s.{{ .Name }} != nil {
|
||||
for i, v := range s.{{ .Name }} {
|
||||
if v == nil { continue }
|
||||
if err := v.Validate(); err != nil {
|
||||
@@ -67,7 +81,7 @@ var validationGoCodeTmpls = template.Must(template.New("validationGoCodeTmpls").
|
||||
}
|
||||
{{- end }}
|
||||
{{ define "nestedStruct" -}}
|
||||
if s.{{ .Name }} != nil {
|
||||
if s.{{ .Name }} != nil {
|
||||
if err := s.{{ .Name }}.Validate(); err != nil {
|
||||
invalidParams.AddNested("{{ .Name }}", err.(request.ErrInvalidParams))
|
||||
}
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ShapeValueBuilder provides the logic to build the nested values for a shape.
|
||||
type ShapeValueBuilder struct{}
|
||||
|
||||
// BuildShape will recursively build the referenced shape based on the json
|
||||
// object provided. isMap will dictate how the field name is specified. If
|
||||
// isMap is true, we will expect the member name to be quotes like "Foo".
|
||||
func (b ShapeValueBuilder) BuildShape(ref *ShapeRef, shapes map[string]interface{}, isMap bool) string {
|
||||
order := make([]string, len(shapes))
|
||||
for k := range shapes {
|
||||
order = append(order, k)
|
||||
}
|
||||
sort.Strings(order)
|
||||
|
||||
ret := ""
|
||||
for _, name := range order {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
shape := shapes[name]
|
||||
|
||||
// If the shape isn't a map, we want to export the value, since every field
|
||||
// defined in our shapes are exported.
|
||||
if len(name) > 0 && !isMap && strings.ToLower(name[0:1]) == name[0:1] {
|
||||
name = strings.Title(name)
|
||||
}
|
||||
|
||||
memName := name
|
||||
passRef := ref.Shape.MemberRefs[name]
|
||||
|
||||
if isMap {
|
||||
memName = fmt.Sprintf("%q", memName)
|
||||
passRef = &ref.Shape.ValueRef
|
||||
}
|
||||
|
||||
switch v := shape.(type) {
|
||||
case map[string]interface{}:
|
||||
ret += b.BuildComplex(name, memName, passRef, v)
|
||||
case []interface{}:
|
||||
ret += b.BuildList(name, memName, passRef, v)
|
||||
default:
|
||||
ret += b.BuildScalar(name, memName, passRef, v, ref.Shape.Payload == name)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// BuildList will construct a list shape based off the service's definition of
|
||||
// that list.
|
||||
func (b ShapeValueBuilder) BuildList(name, memName string, ref *ShapeRef, v []interface{}) string {
|
||||
ret := ""
|
||||
|
||||
if len(v) == 0 || ref == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
passRef := &ref.Shape.MemberRef
|
||||
ret += fmt.Sprintf("%s: %s {\n", memName, b.GoType(ref, false))
|
||||
ret += b.buildListElements(passRef, v)
|
||||
ret += "},\n"
|
||||
return ret
|
||||
}
|
||||
|
||||
func (b ShapeValueBuilder) buildListElements(ref *ShapeRef, v []interface{}) string {
|
||||
if len(v) == 0 || ref == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
ret := ""
|
||||
format := ""
|
||||
isComplex := false
|
||||
isList := false
|
||||
|
||||
// get format for atomic type. If it is not an atomic type,
|
||||
// get the element.
|
||||
switch v[0].(type) {
|
||||
case string:
|
||||
format = "%s"
|
||||
case bool:
|
||||
format = "%t"
|
||||
case float64:
|
||||
switch ref.Shape.Type {
|
||||
case "integer", "int64", "long":
|
||||
format = "%d"
|
||||
default:
|
||||
format = "%f"
|
||||
}
|
||||
case []interface{}:
|
||||
isList = true
|
||||
case map[string]interface{}:
|
||||
isComplex = true
|
||||
}
|
||||
|
||||
for _, elem := range v {
|
||||
if isComplex {
|
||||
ret += fmt.Sprintf("{\n%s\n},\n", b.BuildShape(ref, elem.(map[string]interface{}), ref.Shape.Type == "map"))
|
||||
} else if isList {
|
||||
ret += fmt.Sprintf("{\n%s\n},\n", b.buildListElements(&ref.Shape.MemberRef, elem.([]interface{})))
|
||||
} else {
|
||||
switch ref.Shape.Type {
|
||||
case "integer", "int64", "long":
|
||||
elem = int(elem.(float64))
|
||||
}
|
||||
ret += fmt.Sprintf("%s,\n", getValue(ref.Shape.Type, fmt.Sprintf(format, elem)))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// BuildScalar will build atomic Go types.
|
||||
func (b ShapeValueBuilder) BuildScalar(name, memName string, ref *ShapeRef, shape interface{}, isPayload bool) string {
|
||||
if ref == nil || ref.Shape == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch v := shape.(type) {
|
||||
case bool:
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%t", v))
|
||||
case int:
|
||||
if ref.Shape.Type == "timestamp" {
|
||||
return parseTimeString(ref, memName, fmt.Sprintf("%d", v))
|
||||
}
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%d", v))
|
||||
case float64:
|
||||
dataType := ref.Shape.Type
|
||||
if dataType == "integer" || dataType == "int64" || dataType == "long" {
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%d", int(shape.(float64))))
|
||||
}
|
||||
return convertToCorrectType(memName, ref.Shape.Type, fmt.Sprintf("%f", v))
|
||||
case string:
|
||||
t := ref.Shape.Type
|
||||
switch t {
|
||||
case "timestamp":
|
||||
return parseTimeString(ref, memName, fmt.Sprintf("%s", v))
|
||||
case "blob":
|
||||
if (ref.Streaming || ref.Shape.Streaming) && isPayload {
|
||||
return fmt.Sprintf("%s: aws.ReadSeekCloser(strings.NewReader(%q)),\n", memName, v)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s: []byte(%q),\n", memName, v)
|
||||
default:
|
||||
return convertToCorrectType(memName, t, v)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("Unsupported scalar type: %v", reflect.TypeOf(v)))
|
||||
}
|
||||
}
|
||||
|
||||
// BuildComplex will build the shape's value for complex types such as structs,
|
||||
// and maps.
|
||||
func (b ShapeValueBuilder) BuildComplex(name, memName string, ref *ShapeRef, v map[string]interface{}) string {
|
||||
switch ref.Shape.Type {
|
||||
case "structure":
|
||||
return fmt.Sprintf(`%s: &%s{
|
||||
%s
|
||||
},
|
||||
`, memName, b.GoType(ref, true), b.BuildShape(ref, v, false))
|
||||
case "map":
|
||||
return fmt.Sprintf(`%s: %s{
|
||||
%s
|
||||
},
|
||||
`, name, b.GoType(ref, false), b.BuildShape(ref, v, true))
|
||||
default:
|
||||
panic(fmt.Sprintf("Expected complex type but received %q", ref.Shape.Type))
|
||||
}
|
||||
}
|
||||
|
||||
// GoType returns the string of the shape's Go type identifier.
|
||||
func (b ShapeValueBuilder) GoType(ref *ShapeRef, elem bool) string {
|
||||
if ref.Shape.Type != "structure" && ref.Shape.Type != "list" && ref.Shape.Type != "map" {
|
||||
// Scalars are always pointers.
|
||||
return ref.GoTypeWithPkgName()
|
||||
}
|
||||
|
||||
prefix := ""
|
||||
if ref.Shape.Type == "list" {
|
||||
ref = &ref.Shape.MemberRef
|
||||
prefix = "[]"
|
||||
}
|
||||
|
||||
if elem {
|
||||
return prefix + ref.Shape.GoTypeWithPkgNameElem()
|
||||
}
|
||||
return prefix + ref.GoTypeWithPkgName()
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
// +build codegen
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// SmokeTestSuite defines the test suite for smoke tests.
|
||||
type SmokeTestSuite struct {
|
||||
Version int `json:"version"`
|
||||
DefaultRegion string `json:"defaultRegion"`
|
||||
TestCases []SmokeTestCase `json:"testCases"`
|
||||
}
|
||||
|
||||
// SmokeTestCase provides the definition for a integration smoke test case.
|
||||
type SmokeTestCase struct {
|
||||
OpName string `json:"operationName"`
|
||||
Input map[string]interface{} `json:"input"`
|
||||
ExpectErr bool `json:"errorExpectedFromService"`
|
||||
}
|
||||
|
||||
// BuildInputShape returns the Go code as a string for initializing the test
|
||||
// case's input shape.
|
||||
func (c SmokeTestCase) BuildInputShape(ref *ShapeRef) string {
|
||||
var b ShapeValueBuilder
|
||||
return fmt.Sprintf("&%s{\n%s\n}",
|
||||
b.GoType(ref, true),
|
||||
b.BuildShape(ref, c.Input, false),
|
||||
)
|
||||
}
|
||||
|
||||
// AttachSmokeTests attaches the smoke test cases to the API model.
|
||||
func (a *API) AttachSmokeTests(filename string) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to open smoke tests %s, err: %v", filename, err))
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := json.NewDecoder(f).Decode(&a.SmokeTests); err != nil {
|
||||
panic(fmt.Sprintf("failed to decode smoke tests %s, err: %v", filename, err))
|
||||
}
|
||||
|
||||
if v := a.SmokeTests.Version; v != 1 {
|
||||
panic(fmt.Sprintf("invalid smoke test version, %d", v))
|
||||
}
|
||||
}
|
||||
|
||||
// APISmokeTestsGoCode returns the Go Code string for the smoke tests.
|
||||
func (a *API) APISmokeTestsGoCode() string {
|
||||
w := bytes.NewBuffer(nil)
|
||||
|
||||
a.resetImports()
|
||||
a.AddImport("context")
|
||||
a.AddImport("testing")
|
||||
a.AddImport("time")
|
||||
a.AddSDKImport("aws")
|
||||
a.AddSDKImport("aws/request")
|
||||
a.AddSDKImport("aws/awserr")
|
||||
a.AddSDKImport("aws/request")
|
||||
a.AddSDKImport("awstesting/integration")
|
||||
a.AddImport(a.ImportPath())
|
||||
|
||||
smokeTests := struct {
|
||||
API *API
|
||||
SmokeTestSuite
|
||||
}{
|
||||
API: a,
|
||||
SmokeTestSuite: a.SmokeTests,
|
||||
}
|
||||
|
||||
if err := smokeTestTmpl.Execute(w, smokeTests); err != nil {
|
||||
panic(fmt.Sprintf("failed to create smoke tests, %v", err))
|
||||
}
|
||||
|
||||
ignoreImports := `
|
||||
var _ aws.Config
|
||||
var _ awserr.Error
|
||||
var _ request.Request
|
||||
`
|
||||
|
||||
return a.importsGoCode() + ignoreImports + w.String()
|
||||
}
|
||||
|
||||
var smokeTestTmpl = template.Must(template.New(`smokeTestTmpl`).Parse(`
|
||||
{{- range $i, $testCase := $.TestCases }}
|
||||
{{- $op := index $.API.Operations $testCase.OpName }}
|
||||
func TestInteg_{{ printf "%02d" $i }}_{{ $op.ExportedName }}(t *testing.T) {
|
||||
ctx, cancelFn := context.WithTimeout(context.Background(), 5 *time.Second)
|
||||
defer cancelFn()
|
||||
|
||||
sess := integration.SessionWithDefaultRegion("{{ $.DefaultRegion }}")
|
||||
svc := {{ $.API.PackageName }}.New(sess)
|
||||
params := {{ $testCase.BuildInputShape $op.InputRef }}
|
||||
_, err := svc.{{ $op.ExportedName }}WithContext(ctx, params)
|
||||
{{- if $testCase.ExpectErr }}
|
||||
if err == nil {
|
||||
t.Fatalf("expect request to fail")
|
||||
}
|
||||
aerr, ok := err.(awserr.RequestFailure)
|
||||
if !ok {
|
||||
t.Fatalf("expect awserr, was %T", err)
|
||||
}
|
||||
if len(aerr.Code()) == 0 {
|
||||
t.Errorf("expect non-empty error code")
|
||||
}
|
||||
if v := aerr.Code(); v == request.ErrCodeSerialization {
|
||||
t.Errorf("expect API error code got serialization failure")
|
||||
}
|
||||
{{- else }}
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
`))
|
||||
+2
-2
@@ -47,8 +47,8 @@ func (a *API) WaitersGoCode() string {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "import (\n%q\n\n%q\n%q\n)",
|
||||
"time",
|
||||
"github.com/aws/aws-sdk-go/aws",
|
||||
"github.com/aws/aws-sdk-go/aws/request",
|
||||
SDKImportRoot+"/aws",
|
||||
SDKImportRoot+"/aws/request",
|
||||
)
|
||||
|
||||
for _, w := range a.Waiters {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// +build codegen
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/aws/aws-sdk-go/private/model/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
glob := filepath.FromSlash(os.Args[1])
|
||||
modelPaths, err := api.ExpandModelGlobPath(glob)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to expand glob, %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
_, excluded := api.TrimModelServiceVersions(modelPaths)
|
||||
|
||||
for _, exclude := range excluded {
|
||||
modelPath := filepath.Dir(exclude)
|
||||
fmt.Println("removing:", modelPath)
|
||||
os.RemoveAll(modelPath)
|
||||
}
|
||||
}
|
||||
+128
-135
@@ -13,7 +13,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -21,87 +20,21 @@ import (
|
||||
"github.com/aws/aws-sdk-go/private/util"
|
||||
)
|
||||
|
||||
type generateInfo struct {
|
||||
*api.API
|
||||
PackageDir string
|
||||
}
|
||||
func usage() {
|
||||
fmt.Fprintln(os.Stderr, `Usage: api-gen <options> [model path | file path]
|
||||
Loads API models from file and generates SDK clients from the models.
|
||||
|
||||
var excludeServices = map[string]struct{}{
|
||||
"importexport": {},
|
||||
}
|
||||
The model path arguments can be globs, or paths to individual files. The
|
||||
utiliity requires that the API model files follow the following pattern:
|
||||
|
||||
// newGenerateInfo initializes the service API's folder structure for a specific service.
|
||||
// If the SERVICES environment variable is set, and this service is not apart of the list
|
||||
// this service will be skipped.
|
||||
func newGenerateInfo(modelFile, svcPath, svcImportPath string) *generateInfo {
|
||||
g := &generateInfo{API: &api.API{SvcClientImportPath: svcImportPath, BaseCrosslinkURL: "https://docs.aws.amazon.com"}}
|
||||
g.API.Attach(modelFile)
|
||||
<root>/<servicename>/<api-version>/<model json files>
|
||||
|
||||
if _, ok := excludeServices[g.API.PackageName()]; ok {
|
||||
return nil
|
||||
}
|
||||
e.g:
|
||||
|
||||
paginatorsFile := strings.Replace(modelFile, "api-2.json", "paginators-1.json", -1)
|
||||
if _, err := os.Stat(paginatorsFile); err == nil {
|
||||
g.API.AttachPaginators(paginatorsFile)
|
||||
} else if !os.IsNotExist(err) {
|
||||
fmt.Println("api-2.json error:", err)
|
||||
}
|
||||
./models/apis/s3/2006-03-01/*.json
|
||||
|
||||
docsFile := strings.Replace(modelFile, "api-2.json", "docs-2.json", -1)
|
||||
if _, err := os.Stat(docsFile); err == nil {
|
||||
g.API.AttachDocs(docsFile)
|
||||
} else {
|
||||
fmt.Println("docs-2.json error:", err)
|
||||
}
|
||||
|
||||
waitersFile := strings.Replace(modelFile, "api-2.json", "waiters-2.json", -1)
|
||||
if _, err := os.Stat(waitersFile); err == nil {
|
||||
g.API.AttachWaiters(waitersFile)
|
||||
} else if !os.IsNotExist(err) {
|
||||
fmt.Println("waiters-2.json error:", err)
|
||||
}
|
||||
|
||||
examplesFile := strings.Replace(modelFile, "api-2.json", "examples-1.json", -1)
|
||||
if _, err := os.Stat(examplesFile); err == nil {
|
||||
g.API.AttachExamples(examplesFile)
|
||||
} else if !os.IsNotExist(err) {
|
||||
fmt.Println("examples-1.json error:", err)
|
||||
}
|
||||
|
||||
// pkgDocAddonsFile := strings.Replace(modelFile, "api-2.json", "go-pkg-doc.gotmpl", -1)
|
||||
// if _, err := os.Stat(pkgDocAddonsFile); err == nil {
|
||||
// g.API.AttachPackageDocAddons(pkgDocAddonsFile)
|
||||
// } else if !os.IsNotExist(err) {
|
||||
// fmt.Println("go-pkg-doc.gotmpl error:", err)
|
||||
// }
|
||||
|
||||
g.API.Setup()
|
||||
|
||||
if svc := os.Getenv("SERVICES"); svc != "" {
|
||||
svcs := strings.Split(svc, ",")
|
||||
|
||||
included := false
|
||||
for _, s := range svcs {
|
||||
if s == g.API.PackageName() {
|
||||
included = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !included {
|
||||
// skip this non-included service
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ensure the directory exists
|
||||
pkgDir := filepath.Join(svcPath, g.API.PackageName())
|
||||
os.MkdirAll(pkgDir, 0775)
|
||||
os.MkdirAll(filepath.Join(pkgDir, g.API.InterfacePackageName()), 0775)
|
||||
|
||||
g.PackageDir = pkgDir
|
||||
|
||||
return g
|
||||
Flags:`)
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
// Generates service api, examples, and interface from api json definition files.
|
||||
@@ -112,88 +45,109 @@ func newGenerateInfo(modelFile, svcPath, svcImportPath string) *generateInfo {
|
||||
// Env:
|
||||
// SERVICES comma separated list of services to generate.
|
||||
func main() {
|
||||
var svcPath, sessionPath, svcImportPath string
|
||||
flag.StringVar(&svcPath, "path", "service", "directory to generate service clients in")
|
||||
flag.StringVar(&sessionPath, "sessionPath", filepath.Join("aws", "session"), "generate session service client factories")
|
||||
flag.StringVar(&svcImportPath, "svc-import-path", "github.com/aws/aws-sdk-go/service", "namespace to generate service client Go code import path under")
|
||||
var svcPath, svcImportPath string
|
||||
flag.StringVar(&svcPath, "path", "service",
|
||||
"The `path` to generate service clients in to.",
|
||||
)
|
||||
flag.StringVar(&svcImportPath, "svc-import-path",
|
||||
api.SDKImportRoot+"/service",
|
||||
"The Go `import path` to generate client to be under.",
|
||||
)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
api.Bootstrap()
|
||||
|
||||
files := []string{}
|
||||
for i := 0; i < flag.NArg(); i++ {
|
||||
file := flag.Arg(i)
|
||||
if strings.Contains(file, "*") {
|
||||
paths, _ := filepath.Glob(file)
|
||||
files = append(files, paths...)
|
||||
} else {
|
||||
files = append(files, file)
|
||||
if len(os.Getenv("AWS_SDK_CODEGEN_DEBUG")) != 0 {
|
||||
api.LogDebug(os.Stdout)
|
||||
}
|
||||
|
||||
// Make sure all paths are based on platform's pathing not Unix
|
||||
globs := flag.Args()
|
||||
for i, g := range globs {
|
||||
globs[i] = filepath.FromSlash(g)
|
||||
}
|
||||
svcPath = filepath.FromSlash(svcPath)
|
||||
|
||||
modelPaths, err := api.ExpandModelGlobPath(globs...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "failed to glob file pattern", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
modelPaths, _ = api.TrimModelServiceVersions(modelPaths)
|
||||
|
||||
apis, err := api.LoadAPIs(modelPaths, svcImportPath)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "failed to load API models", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(apis) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "expected to load models, but found none")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if v := os.Getenv("SERVICES"); len(v) != 0 {
|
||||
svcs := strings.Split(v, ",")
|
||||
for pkgName, a := range apis {
|
||||
var found bool
|
||||
for _, include := range svcs {
|
||||
if a.PackageName() == include {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
delete(apis, pkgName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for svcName := range excludeServices {
|
||||
if strings.Contains(os.Getenv("SERVICES"), svcName) {
|
||||
fmt.Fprintf(os.Stderr, "Service %s is not supported\n", svcName)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(files)
|
||||
|
||||
// Remove old API versions from list
|
||||
m := map[string]bool{}
|
||||
// caches paths to ensure we are not overriding previously generated
|
||||
// code.
|
||||
var wg sync.WaitGroup
|
||||
servicePaths := map[string]struct{}{}
|
||||
|
||||
for i := range files {
|
||||
idx := len(files) - 1 - i
|
||||
parts := strings.Split(files[idx], string(filepath.Separator))
|
||||
svc := parts[len(parts)-3] // service name is 2nd-to-last component
|
||||
|
||||
if m[svc] {
|
||||
files[idx] = "" // wipe this one out if we already saw the service
|
||||
}
|
||||
m[svc] = true
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
for i := range files {
|
||||
filename := files[i]
|
||||
if filename == "" { // empty file
|
||||
for _, a := range apis {
|
||||
if _, ok := excludeServices[a.PackageName()]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
genInfo := newGenerateInfo(filename, svcPath, svcImportPath)
|
||||
if genInfo == nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := excludeServices[genInfo.API.PackageName()]; ok {
|
||||
// Skip services not yet supported.
|
||||
continue
|
||||
}
|
||||
// Create the output path for the model.
|
||||
pkgDir := filepath.Join(svcPath, a.PackageName())
|
||||
os.MkdirAll(filepath.Join(pkgDir, a.InterfacePackageName()), 0775)
|
||||
|
||||
if _, ok := servicePaths[genInfo.PackageDir]; ok {
|
||||
fmt.Fprintf(os.Stderr, "Path %q has already been generated", genInfo.PackageDir)
|
||||
if _, ok := servicePaths[pkgDir]; ok {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"attempted to generate a client into %s twice. Second model package, %v\n",
|
||||
pkgDir, a.PackageName())
|
||||
os.Exit(1)
|
||||
}
|
||||
servicePaths[pkgDir] = struct{}{}
|
||||
|
||||
servicePaths[genInfo.PackageDir] = struct{}{}
|
||||
g := &generateInfo{
|
||||
API: a,
|
||||
PackageDir: pkgDir,
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(g *generateInfo, filename string) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
writeServiceFiles(g, filename)
|
||||
}(genInfo, filename)
|
||||
writeServiceFiles(g, pkgDir)
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func writeServiceFiles(g *generateInfo, filename string) {
|
||||
type generateInfo struct {
|
||||
*api.API
|
||||
PackageDir string
|
||||
}
|
||||
|
||||
var excludeServices = map[string]struct{}{
|
||||
"importexport": {},
|
||||
}
|
||||
|
||||
func writeServiceFiles(g *generateInfo, pkgDir string) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error generating %s\n%s\n%s\n",
|
||||
filename, r, debug.Stack())
|
||||
pkgDir, r, debug.Stack())
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
@@ -209,6 +163,18 @@ func writeServiceFiles(g *generateInfo, filename string) {
|
||||
Must(writeWaitersFile(g))
|
||||
Must(writeAPIErrorsFile(g))
|
||||
Must(writeExamplesFile(g))
|
||||
|
||||
if g.API.HasEventStream {
|
||||
Must(writeAPIEventStreamTestFile(g))
|
||||
}
|
||||
|
||||
if g.API.PackageName() == "s3" {
|
||||
Must(writeS3ManagerUploadInputFile(g))
|
||||
}
|
||||
|
||||
if len(g.API.SmokeTests.TestCases) > 0 {
|
||||
Must(writeAPISmokeTestsFile(g))
|
||||
}
|
||||
}
|
||||
|
||||
// Must will panic if the error passed in is not nil.
|
||||
@@ -313,3 +279,30 @@ func writeAPIErrorsFile(g *generateInfo) error {
|
||||
g.API.APIErrorsGoCode(),
|
||||
)
|
||||
}
|
||||
|
||||
func writeAPIEventStreamTestFile(g *generateInfo) error {
|
||||
return writeGoFile(filepath.Join(g.PackageDir, "eventstream_test.go"),
|
||||
codeLayout,
|
||||
"// +build go1.6\n",
|
||||
g.API.PackageName(),
|
||||
g.API.APIEventStreamTestGoCode(),
|
||||
)
|
||||
}
|
||||
|
||||
func writeS3ManagerUploadInputFile(g *generateInfo) error {
|
||||
return writeGoFile(filepath.Join(g.PackageDir, "s3manager", "upload_input.go"),
|
||||
codeLayout,
|
||||
"",
|
||||
"s3manager",
|
||||
api.S3ManagerUploadInputGoCode(g.API),
|
||||
)
|
||||
}
|
||||
|
||||
func writeAPISmokeTestsFile(g *generateInfo) error {
|
||||
return writeGoFile(filepath.Join(g.PackageDir, "integ_test.go"),
|
||||
codeLayout,
|
||||
"// +build go1.10,integration\n",
|
||||
g.API.PackageName()+"_test",
|
||||
g.API.APISmokeTestsGoCode(),
|
||||
)
|
||||
}
|
||||
|
||||
+3
-1
@@ -45,7 +45,9 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
if err := endpoints.CodeGenModel(modelFile, outFile); err != nil {
|
||||
if err := endpoints.CodeGenModel(modelFile, outFile, func(o *endpoints.CodeGenOptions) {
|
||||
o.DisableGenerateServiceIDs = true
|
||||
}); err != nil {
|
||||
exitErrorf("failed to codegen model, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ func Build(r *request.Request) {
|
||||
"Version": {r.ClientInfo.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, true); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed encoding EC2 Query request", err)
|
||||
}
|
||||
|
||||
if !r.IsPresigned() {
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ func BenchmarkEC2QueryBuild_Complex_ec2AuthorizeSecurityGroupEgress(b *testing.B
|
||||
IpProtocol: aws.String("String"),
|
||||
SourceSecurityGroupName: aws.String("String"),
|
||||
SourceSecurityGroupOwnerId: aws.String("String"),
|
||||
ToPort: aws.Int64(1),
|
||||
ToPort: aws.Int64(1),
|
||||
}
|
||||
|
||||
benchEC2QueryBuild(b, "AuthorizeSecurityGroupEgress", params)
|
||||
|
||||
+432
-71
@@ -75,7 +75,8 @@ func newInputService1ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice1protocoltest",
|
||||
ServiceName: "InputService1ProtocolTest",
|
||||
ServiceID: "InputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opInputService1TestCaseOperation1 = "OperationName"
|
||||
// InputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -139,8 +140,7 @@ func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService1TestShapeInputService1TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -228,7 +228,8 @@ func newInputService2ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice2protocoltest",
|
||||
ServiceName: "InputService2ProtocolTest",
|
||||
ServiceID: "InputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -261,7 +262,7 @@ const opInputService2TestCaseOperation1 = "OperationName"
|
||||
// InputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -292,8 +293,7 @@ func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService2TestShapeInputService2TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -389,7 +389,8 @@ func newInputService3ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice3protocoltest",
|
||||
ServiceName: "InputService3ProtocolTest",
|
||||
ServiceID: "InputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -422,7 +423,7 @@ const opInputService3TestCaseOperation1 = "OperationName"
|
||||
// InputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -453,8 +454,7 @@ func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService3TestShapeInputService3TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -546,7 +546,8 @@ func newInputService4ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice4protocoltest",
|
||||
ServiceName: "InputService4ProtocolTest",
|
||||
ServiceID: "InputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -579,7 +580,7 @@ const opInputService4TestCaseOperation1 = "OperationName"
|
||||
// InputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -610,8 +611,7 @@ func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService4TestShapeInputService4TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -715,7 +715,8 @@ func newInputService5ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice5protocoltest",
|
||||
ServiceName: "InputService5ProtocolTest",
|
||||
ServiceID: "InputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -748,7 +749,7 @@ const opInputService5TestCaseOperation1 = "OperationName"
|
||||
// InputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -779,8 +780,7 @@ func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService5TestShapeInputService5TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -860,7 +860,8 @@ func newInputService6ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice6protocoltest",
|
||||
ServiceName: "InputService6ProtocolTest",
|
||||
ServiceID: "InputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -893,7 +894,7 @@ const opInputService6TestCaseOperation1 = "OperationName"
|
||||
// InputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -924,8 +925,7 @@ func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService6TestShapeInputService6TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1005,7 +1005,8 @@ func newInputService7ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice7protocoltest",
|
||||
ServiceName: "InputService7ProtocolTest",
|
||||
ServiceID: "InputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1038,7 +1039,7 @@ const opInputService7TestCaseOperation1 = "OperationName"
|
||||
// InputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1069,8 +1070,7 @@ func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService7TestShapeInputService7TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1151,7 +1151,8 @@ func newInputService8ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice8protocoltest",
|
||||
ServiceName: "InputService8ProtocolTest",
|
||||
ServiceID: "InputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1184,7 +1185,7 @@ const opInputService8TestCaseOperation1 = "OperationName"
|
||||
// InputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1215,8 +1216,7 @@ func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService8TestShapeInputService8TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1252,7 +1252,11 @@ func (c *InputService8ProtocolTest) InputService8TestCaseOperation1WithContext(c
|
||||
type InputService8TestShapeInputService8TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
}
|
||||
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
@@ -1261,6 +1265,18 @@ func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeArg(
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeCustom(v time.Time) *InputService8TestShapeInputService8TestCaseOperation1Input {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeFormat(v time.Time) *InputService8TestShapeInputService8TestCaseOperation1Input {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService8TestShapeInputService8TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1296,7 +1312,8 @@ func newInputService9ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice9protocoltest",
|
||||
ServiceName: "InputService9ProtocolTest",
|
||||
ServiceID: "InputService9ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1329,7 +1346,7 @@ const opInputService9TestCaseOperation1 = "OperationName"
|
||||
// InputService9TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService9TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1348,20 +1365,19 @@ const opInputService9TestCaseOperation1 = "OperationName"
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputService9TestCaseOperation2Input) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputService9TestCaseOperation1Input) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService9TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService9TestShapeInputService9TestCaseOperation2Input{}
|
||||
input = &InputService9TestShapeInputService9TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService9TestShapeInputService9TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1373,7 +1389,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService9TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *InputService9TestShapeInputService9TestCaseOperation2Input) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *InputService9TestShapeInputService9TestCaseOperation1Input) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService9TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
@@ -1387,7 +1403,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *Input
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1WithContext(ctx aws.Context, input *InputService9TestShapeInputService9TestCaseOperation2Input, opts ...request.Option) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1WithContext(ctx aws.Context, input *InputService9TestShapeInputService9TestCaseOperation1Input, opts ...request.Option) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService9TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
@@ -1399,7 +1415,7 @@ const opInputService9TestCaseOperation2 = "OperationName"
|
||||
// InputService9TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService9TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1430,8 +1446,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation2Request(input
|
||||
|
||||
output = &InputService9TestShapeInputService9TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1464,6 +1479,18 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation2WithContext(c
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService9TestShapeInputService9TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Token *string `type:"string" idempotencyToken:"true"`
|
||||
}
|
||||
|
||||
// SetToken sets the Token field's value.
|
||||
func (s *InputService9TestShapeInputService9TestCaseOperation1Input) SetToken(v string) *InputService9TestShapeInputService9TestCaseOperation1Input {
|
||||
s.Token = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService9TestShapeInputService9TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1515,7 +1542,8 @@ func newInputService10ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice10protocoltest",
|
||||
ServiceName: "InputService10ProtocolTest",
|
||||
ServiceID: "InputService10ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1548,7 +1576,7 @@ const opInputService10TestCaseOperation1 = "OperationName"
|
||||
// InputService10TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService10TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1567,20 +1595,19 @@ const opInputService10TestCaseOperation1 = "OperationName"
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(input *InputService10TestShapeInputService10TestCaseOperation2Input) (req *request.Request, output *InputService10TestShapeInputService10TestCaseOperation1Output) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(input *InputService10TestShapeInputService10TestCaseOperation1Input) (req *request.Request, output *InputService10TestShapeInputService10TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService10TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService10TestShapeInputService10TestCaseOperation2Input{}
|
||||
input = &InputService10TestShapeInputService10TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService10TestShapeInputService10TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1592,7 +1619,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(inp
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService10TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *InputService10TestShapeInputService10TestCaseOperation2Input) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *InputService10TestShapeInputService10TestCaseOperation1Input) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService10TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
@@ -1606,7 +1633,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *Inp
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1WithContext(ctx aws.Context, input *InputService10TestShapeInputService10TestCaseOperation2Input, opts ...request.Option) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1WithContext(ctx aws.Context, input *InputService10TestShapeInputService10TestCaseOperation1Input, opts ...request.Option) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService10TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
@@ -1618,7 +1645,7 @@ const opInputService10TestCaseOperation2 = "OperationName"
|
||||
// InputService10TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService10TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1649,8 +1676,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation2Request(inp
|
||||
|
||||
output = &InputService10TestShapeInputService10TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1683,6 +1709,26 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation2WithContext
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService10TestShapeInputService10TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"InputService10TestShapeEnumType"`
|
||||
|
||||
ListEnums []*string `type:"list"`
|
||||
}
|
||||
|
||||
// SetFooEnum sets the FooEnum field's value.
|
||||
func (s *InputService10TestShapeInputService10TestCaseOperation1Input) SetFooEnum(v string) *InputService10TestShapeInputService10TestCaseOperation1Input {
|
||||
s.FooEnum = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListEnums sets the ListEnums field's value.
|
||||
func (s *InputService10TestShapeInputService10TestCaseOperation1Input) SetListEnums(v []*string) *InputService10TestShapeInputService10TestCaseOperation1Input {
|
||||
s.ListEnums = v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService10TestShapeInputService10TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1719,6 +1765,263 @@ const (
|
||||
EnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
// InputService11ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// InputService11ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type InputService11ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the InputService11ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a InputService11ProtocolTest client from just a session.
|
||||
// svc := inputservice11protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a InputService11ProtocolTest client with additional configuration
|
||||
// svc := inputservice11protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewInputService11ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService11ProtocolTest {
|
||||
c := p.ClientConfig("inputservice11protocoltest", cfgs...)
|
||||
return newInputService11ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newInputService11ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *InputService11ProtocolTest {
|
||||
svc := &InputService11ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "InputService11ProtocolTest",
|
||||
ServiceID: "InputService11ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2014-01-01",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(ec2query.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(ec2query.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(ec2query.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(ec2query.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService11ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService11ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService11TestCaseOperation1 = "StaticOp"
|
||||
|
||||
// InputService11TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService11TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See InputService11TestCaseOperation1 for more information on using the InputService11TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the InputService11TestCaseOperation1Request method.
|
||||
// req, resp := client.InputService11TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1Request(input *InputService11TestShapeInputService11TestCaseOperation1Input) (req *request.Request, output *InputService11TestShapeInputService11TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService11TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService11TestShapeInputService11TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService11TestShapeInputService11TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Build.PushBackNamed(protocol.NewHostPrefixHandler("data-", nil))
|
||||
req.Handlers.Build.PushBackNamed(protocol.ValidateEndpointHostHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService11TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1(input *InputService11TestShapeInputService11TestCaseOperation1Input) (*InputService11TestShapeInputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation1WithContext is the same as InputService11TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See InputService11TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1WithContext(ctx aws.Context, input *InputService11TestShapeInputService11TestCaseOperation1Input, opts ...request.Option) (*InputService11TestShapeInputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opInputService11TestCaseOperation2 = "MemberRefOp"
|
||||
|
||||
// InputService11TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService11TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See InputService11TestCaseOperation2 for more information on using the InputService11TestCaseOperation2
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the InputService11TestCaseOperation2Request method.
|
||||
// req, resp := client.InputService11TestCaseOperation2Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2Request(input *InputService11TestShapeInputService11TestCaseOperation2Input) (req *request.Request, output *InputService11TestShapeInputService11TestCaseOperation2Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService11TestCaseOperation2,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService11TestShapeInputService11TestCaseOperation2Input{}
|
||||
}
|
||||
|
||||
output = &InputService11TestShapeInputService11TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Build.PushBackNamed(protocol.NewHostPrefixHandler("foo-{Name}.", input.hostLabels))
|
||||
req.Handlers.Build.PushBackNamed(protocol.ValidateEndpointHostHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation2 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService11TestCaseOperation2 for usage and error information.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2(input *InputService11TestShapeInputService11TestCaseOperation2Input) (*InputService11TestShapeInputService11TestCaseOperation2Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation2Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation2WithContext is the same as InputService11TestCaseOperation2 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See InputService11TestCaseOperation2 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2WithContext(ctx aws.Context, input *InputService11TestShapeInputService11TestCaseOperation2Input, opts ...request.Option) (*InputService11TestShapeInputService11TestCaseOperation2Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation2Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Name *string `type:"string"`
|
||||
}
|
||||
|
||||
// SetName sets the Name field's value.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation1Input) SetName(v string) *InputService11TestShapeInputService11TestCaseOperation1Input {
|
||||
s.Name = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation2Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Name is a required field
|
||||
Name *string `type:"string" required:"true"`
|
||||
}
|
||||
|
||||
// Validate inspects the fields of the type to determine if they are valid.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) Validate() error {
|
||||
invalidParams := request.ErrInvalidParams{Context: "InputService11TestShapeInputService11TestCaseOperation2Input"}
|
||||
if s.Name == nil {
|
||||
invalidParams.Add(request.NewErrParamRequired("Name"))
|
||||
}
|
||||
if s.Name != nil && len(*s.Name) < 1 {
|
||||
invalidParams.Add(request.NewErrParamMinLen("Name", 1))
|
||||
}
|
||||
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetName sets the Name field's value.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) SetName(v string) *InputService11TestShapeInputService11TestCaseOperation2Input {
|
||||
s.Name = &v
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) hostLabels() map[string]string {
|
||||
return map[string]string{
|
||||
"Name": aws.StringValue(s.Name),
|
||||
}
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation2Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
//
|
||||
// Tests begin here
|
||||
//
|
||||
@@ -1733,7 +2036,7 @@ func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1763,7 +2066,7 @@ func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedTo
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1793,7 +2096,7 @@ func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1840,7 +2143,7 @@ func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1872,7 +2175,7 @@ func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *te
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1904,7 +2207,7 @@ func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testi
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1932,7 +2235,7 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1954,13 +2257,15 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
|
||||
func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
svc := NewInputService8ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService8TestShapeInputService8TestCaseOperation1Input{
|
||||
TimeArg: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeArg: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeCustom: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeFormat: aws.Time(time.Unix(1422172800, 0)),
|
||||
}
|
||||
req, _ := svc.InputService8TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1970,7 +2275,7 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&Version=2014-01-01`, util.Trim(string(body)))
|
||||
awstesting.AssertQuery(t, `Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&TimeCustom=1422172800&TimeFormat=1422172800&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://test/", r.URL.String())
|
||||
@@ -1981,14 +2286,14 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
|
||||
func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase1(t *testing.T) {
|
||||
svc := NewInputService9ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService9TestShapeInputService9TestCaseOperation2Input{
|
||||
input := &InputService9TestShapeInputService9TestCaseOperation1Input{
|
||||
Token: aws.String("abc123"),
|
||||
}
|
||||
req, _ := svc.InputService9TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2014,7 +2319,7 @@ func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase2(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2035,7 +2340,7 @@ func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase2(t *testing.T) {
|
||||
|
||||
func TestInputService10ProtocolTestEnumCase1(t *testing.T) {
|
||||
svc := NewInputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService10TestShapeInputService10TestCaseOperation2Input{
|
||||
input := &InputService10TestShapeInputService10TestCaseOperation1Input{
|
||||
ListEnums: []*string{
|
||||
aws.String("foo"),
|
||||
aws.String(""),
|
||||
@@ -2046,7 +2351,7 @@ func TestInputService10ProtocolTestEnumCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2072,7 +2377,7 @@ func TestInputService10ProtocolTestEnumCase2(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2090,3 +2395,59 @@ func TestInputService10ProtocolTestEnumCase2(t *testing.T) {
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService11ProtocolTestEndpointHostTraitCase1(t *testing.T) {
|
||||
svc := NewInputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://service.region.amazonaws.com")})
|
||||
input := &InputService11TestShapeInputService11TestCaseOperation1Input{
|
||||
Name: aws.String("myname"),
|
||||
}
|
||||
req, _ := svc.InputService11TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert body
|
||||
if r.Body == nil {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=StaticOp&Name=myname&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://data-service.region.amazonaws.com/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService11ProtocolTestEndpointHostTraitCase2(t *testing.T) {
|
||||
svc := NewInputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://service.region.amazonaws.com")})
|
||||
input := &InputService11TestShapeInputService11TestCaseOperation2Input{
|
||||
Name: aws.String("myname"),
|
||||
}
|
||||
req, _ := svc.InputService11TestCaseOperation2Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert body
|
||||
if r.Body == nil {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=MemberRefOp&Name=myname&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://foo-myname.service.region.amazonaws.com/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
+24
-10
@@ -4,7 +4,6 @@ package ec2query
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
@@ -27,7 +26,12 @@ func Unmarshal(r *request.Request) {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err)
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed decoding EC2 Query response", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -35,7 +39,11 @@ func Unmarshal(r *request.Request) {
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the EC2 protocol.
|
||||
func UnmarshalMeta(r *request.Request) {
|
||||
// TODO implement unmarshaling of request IDs
|
||||
r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
|
||||
if r.RequestID == "" {
|
||||
// Alternative version of request id in the header
|
||||
r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id")
|
||||
}
|
||||
}
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
@@ -49,15 +57,21 @@ type xmlErrorResponse struct {
|
||||
func UnmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
resp := &xmlErrorResponse{}
|
||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err)
|
||||
} else {
|
||||
var respErr xmlErrorResponse
|
||||
err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(resp.Code, resp.Message, nil),
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal error message", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
resp.RequestID,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(respErr.Code, respErr.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
respErr.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
Generated
Vendored
+82
@@ -0,0 +1,82 @@
|
||||
// +build go1.8
|
||||
|
||||
package ec2query
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestUnmarshalError(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Request *request.Request
|
||||
Code, Msg string
|
||||
ReqID string
|
||||
Status int
|
||||
}{
|
||||
"ErrorResponse": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<Response>
|
||||
<Errors>
|
||||
<Error>
|
||||
<Code>codeAbc</Code>
|
||||
<Message>msg123</Message>
|
||||
</Error>
|
||||
</Errors>
|
||||
<RequestID>reqID123</RequestID>
|
||||
</Response>`)),
|
||||
},
|
||||
},
|
||||
Code: "codeAbc", Msg: "msg123",
|
||||
Status: 400, ReqID: "reqID123",
|
||||
},
|
||||
"unknown tag": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<Hello>
|
||||
<World>.</World>
|
||||
</Hello>`)),
|
||||
},
|
||||
},
|
||||
Code: request.ErrCodeSerialization,
|
||||
Msg: "failed to unmarshal error message",
|
||||
Status: 400,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := c.Request
|
||||
UnmarshalError(r)
|
||||
if r.Error == nil {
|
||||
t.Fatalf("expect error, got none")
|
||||
}
|
||||
|
||||
aerr := r.Error.(awserr.RequestFailure)
|
||||
if e, a := c.Code, aerr.Code(); e != a {
|
||||
t.Errorf("expect %v code, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Msg, aerr.Message(); e != a {
|
||||
t.Errorf("expect %q message, got %q", e, a)
|
||||
}
|
||||
if e, a := c.ReqID, aerr.RequestID(); e != a {
|
||||
t.Errorf("expect %v request ID, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Status, aerr.StatusCode(); e != a {
|
||||
t.Errorf("expect %v status code, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+283
-47
@@ -75,7 +75,8 @@ func newOutputService1ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice1protocoltest",
|
||||
ServiceName: "OutputService1ProtocolTest",
|
||||
ServiceID: "OutputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opOutputService1TestCaseOperation1 = "OperationName"
|
||||
// OutputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -274,7 +275,8 @@ func newOutputService2ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice2protocoltest",
|
||||
ServiceName: "OutputService2ProtocolTest",
|
||||
ServiceID: "OutputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -307,7 +309,7 @@ const opOutputService2TestCaseOperation1 = "OperationName"
|
||||
// OutputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -418,7 +420,8 @@ func newOutputService3ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice3protocoltest",
|
||||
ServiceName: "OutputService3ProtocolTest",
|
||||
ServiceID: "OutputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -451,7 +454,7 @@ const opOutputService3TestCaseOperation1 = "OperationName"
|
||||
// OutputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -561,7 +564,8 @@ func newOutputService4ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice4protocoltest",
|
||||
ServiceName: "OutputService4ProtocolTest",
|
||||
ServiceID: "OutputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -594,7 +598,7 @@ const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
// OutputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -704,7 +708,8 @@ func newOutputService5ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice5protocoltest",
|
||||
ServiceName: "OutputService5ProtocolTest",
|
||||
ServiceID: "OutputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -737,7 +742,7 @@ const opOutputService5TestCaseOperation1 = "OperationName"
|
||||
// OutputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -847,7 +852,8 @@ func newOutputService6ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice6protocoltest",
|
||||
ServiceName: "OutputService6ProtocolTest",
|
||||
ServiceID: "OutputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -880,7 +886,7 @@ const opOutputService6TestCaseOperation1 = "OperationName"
|
||||
// OutputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1002,7 +1008,8 @@ func newOutputService7ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice7protocoltest",
|
||||
ServiceName: "OutputService7ProtocolTest",
|
||||
ServiceID: "OutputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1035,7 +1042,7 @@ const opOutputService7TestCaseOperation1 = "OperationName"
|
||||
// OutputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1145,7 +1152,8 @@ func newOutputService8ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice8protocoltest",
|
||||
ServiceName: "OutputService8ProtocolTest",
|
||||
ServiceID: "OutputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1178,7 +1186,7 @@ const opOutputService8TestCaseOperation1 = "OperationName"
|
||||
// OutputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1288,7 +1296,8 @@ func newOutputService9ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice9protocoltest",
|
||||
ServiceName: "OutputService9ProtocolTest",
|
||||
ServiceID: "OutputService9ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1321,7 +1330,7 @@ const opOutputService9TestCaseOperation1 = "OperationName"
|
||||
// OutputService9TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService9TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1431,7 +1440,8 @@ func newOutputService10ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice10protocoltest",
|
||||
ServiceName: "OutputService10ProtocolTest",
|
||||
ServiceID: "OutputService10ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1464,7 +1474,7 @@ const opOutputService10TestCaseOperation1 = "OperationName"
|
||||
// OutputService10TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService10TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1534,28 +1544,216 @@ type OutputService10TestShapeOutputService10TestCaseOperation1Input struct {
|
||||
type OutputService10TestShapeOutputService10TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService10TestShapeEC2EnumType"`
|
||||
StructMember *OutputService10TestShapeTimeContainer `type:"structure"`
|
||||
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
}
|
||||
|
||||
// SetStructMember sets the StructMember field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetStructMember(v *OutputService10TestShapeTimeContainer) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.StructMember = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeArg(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeArg = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeCustom(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeFormat(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type OutputService10TestShapeTimeContainer struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Bar *time.Time `locationName:"bar" type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
|
||||
Foo *time.Time `locationName:"foo" type:"timestamp"`
|
||||
}
|
||||
|
||||
// SetBar sets the Bar field's value.
|
||||
func (s *OutputService10TestShapeTimeContainer) SetBar(v time.Time) *OutputService10TestShapeTimeContainer {
|
||||
s.Bar = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetFoo sets the Foo field's value.
|
||||
func (s *OutputService10TestShapeTimeContainer) SetFoo(v time.Time) *OutputService10TestShapeTimeContainer {
|
||||
s.Foo = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// OutputService11ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// OutputService11ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type OutputService11ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the OutputService11ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a OutputService11ProtocolTest client from just a session.
|
||||
// svc := outputservice11protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a OutputService11ProtocolTest client with additional configuration
|
||||
// svc := outputservice11protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewOutputService11ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService11ProtocolTest {
|
||||
c := p.ClientConfig("outputservice11protocoltest", cfgs...)
|
||||
return newOutputService11ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newOutputService11ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *OutputService11ProtocolTest {
|
||||
svc := &OutputService11ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "OutputService11ProtocolTest",
|
||||
ServiceID: "OutputService11ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(ec2query.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(ec2query.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(ec2query.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(ec2query.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService11ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService11ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService11TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService11TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService11TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService11TestCaseOperation1 for more information on using the OutputService11TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService11TestCaseOperation1Request method.
|
||||
// req, resp := client.OutputService11TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1Request(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (req *request.Request, output *OutputService11TestShapeOutputService11TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService11TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService11TestShapeOutputService11TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &OutputService11TestShapeOutputService11TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService11TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService11TestCaseOperation1 for usage and error information.
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (*OutputService11TestShapeOutputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService11TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService11TestCaseOperation1WithContext is the same as OutputService11TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService11TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1WithContext(ctx aws.Context, input *OutputService11TestShapeOutputService11TestCaseOperation1Input, opts ...request.Option) (*OutputService11TestShapeOutputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService11TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type OutputService11TestShapeOutputService11TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService11TestShapeOutputService11TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService11TestShapeEC2EnumType"`
|
||||
|
||||
ListEnums []*string `type:"list"`
|
||||
}
|
||||
|
||||
// SetFooEnum sets the FooEnum field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetFooEnum(v string) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetFooEnum(v string) *OutputService11TestShapeOutputService11TestCaseOperation1Output {
|
||||
s.FooEnum = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListEnums sets the ListEnums field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetListEnums(v []*string) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetListEnums(v []*string) *OutputService11TestShapeOutputService11TestCaseOperation1Output {
|
||||
s.ListEnums = v
|
||||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
// EC2EnumTypeFoo is a OutputService10TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeFoo is a OutputService11TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeFoo = "foo"
|
||||
|
||||
// EC2EnumTypeBar is a OutputService10TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeBar is a OutputService11TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
@@ -1573,8 +1771,8 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1620,8 +1818,8 @@ func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1646,8 +1844,8 @@ func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1675,8 +1873,8 @@ func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1704,8 +1902,8 @@ func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1733,8 +1931,8 @@ func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1762,8 +1960,8 @@ func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1791,8 +1989,8 @@ func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1820,8 +2018,8 @@ func TestOutputService9ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1836,18 +2034,56 @@ func TestOutputService9ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService10ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
func TestOutputService10ProtocolTestTimestampMembersCase1(t *testing.T) {
|
||||
svc := NewOutputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><StructMember><foo>2014-04-29T18:30:38Z</foo><bar>1398796238</bar></StructMember><TimeArg>2014-04-29T18:30:38Z</TimeArg><TimeCustom>Tue, 29 Apr 2014 18:30:38 GMT</TimeCustom><TimeFormat>1398796238</TimeFormat><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService10TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Bar.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Foo.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeArg.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeCustom.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeFormat.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService11ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
svc := NewOutputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
req, out := svc.OutputService11TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type decodedMessage struct {
|
||||
rawMessage
|
||||
Headers decodedHeaders `json:"headers"`
|
||||
}
|
||||
type jsonMessage struct {
|
||||
Length json.Number `json:"total_length"`
|
||||
HeadersLen json.Number `json:"headers_length"`
|
||||
PreludeCRC json.Number `json:"prelude_crc"`
|
||||
Headers decodedHeaders `json:"headers"`
|
||||
Payload []byte `json:"payload"`
|
||||
CRC json.Number `json:"message_crc"`
|
||||
}
|
||||
|
||||
func (d *decodedMessage) UnmarshalJSON(b []byte) (err error) {
|
||||
var jsonMsg jsonMessage
|
||||
if err = json.Unmarshal(b, &jsonMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Length, err = numAsUint32(jsonMsg.Length)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.HeadersLen, err = numAsUint32(jsonMsg.HeadersLen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.PreludeCRC, err = numAsUint32(jsonMsg.PreludeCRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Headers = jsonMsg.Headers
|
||||
d.Payload = jsonMsg.Payload
|
||||
d.CRC, err = numAsUint32(jsonMsg.CRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decodedMessage) MarshalJSON() ([]byte, error) {
|
||||
jsonMsg := jsonMessage{
|
||||
Length: json.Number(strconv.Itoa(int(d.Length))),
|
||||
HeadersLen: json.Number(strconv.Itoa(int(d.HeadersLen))),
|
||||
PreludeCRC: json.Number(strconv.Itoa(int(d.PreludeCRC))),
|
||||
Headers: d.Headers,
|
||||
Payload: d.Payload,
|
||||
CRC: json.Number(strconv.Itoa(int(d.CRC))),
|
||||
}
|
||||
|
||||
return json.Marshal(jsonMsg)
|
||||
}
|
||||
|
||||
func numAsUint32(n json.Number) (uint32, error) {
|
||||
v, err := n.Int64()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get int64 json number, %v", err)
|
||||
}
|
||||
|
||||
return uint32(v), nil
|
||||
}
|
||||
|
||||
func (d decodedMessage) Message() Message {
|
||||
return Message{
|
||||
Headers: Headers(d.Headers),
|
||||
Payload: d.Payload,
|
||||
}
|
||||
}
|
||||
|
||||
type decodedHeaders Headers
|
||||
|
||||
func (hs *decodedHeaders) UnmarshalJSON(b []byte) error {
|
||||
var jsonHeaders []struct {
|
||||
Name string `json:"name"`
|
||||
Type valueType `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewReader(b))
|
||||
decoder.UseNumber()
|
||||
if err := decoder.Decode(&jsonHeaders); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var headers Headers
|
||||
for _, h := range jsonHeaders {
|
||||
value, err := valueFromType(h.Type, h.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
headers.Set(h.Name, value)
|
||||
}
|
||||
(*hs) = decodedHeaders(headers)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func valueFromType(typ valueType, val interface{}) (Value, error) {
|
||||
switch typ {
|
||||
case trueValueType:
|
||||
return BoolValue(true), nil
|
||||
case falseValueType:
|
||||
return BoolValue(false), nil
|
||||
case int8ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int8Value(int8(v)), err
|
||||
case int16ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int16Value(int16(v)), err
|
||||
case int32ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int32Value(int32(v)), err
|
||||
case int64ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int64Value(v), err
|
||||
case bytesValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
return BytesValue(v), err
|
||||
case stringValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
return StringValue(string(v)), err
|
||||
case timestampValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return TimestampValue(timeFromEpochMilli(v)), err
|
||||
case uuidValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
var tv UUIDValue
|
||||
copy(tv[:], v)
|
||||
return tv, err
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type, %s, %T", typ.String(), val))
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
// Decoder provides decoding of an Event Stream messages.
|
||||
type Decoder struct {
|
||||
r io.Reader
|
||||
logger aws.Logger
|
||||
}
|
||||
|
||||
// NewDecoder initializes and returns a Decoder for decoding event
|
||||
// stream messages from the reader provided.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
return &Decoder{
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Decode attempts to decode a single message from the event stream reader.
|
||||
// Will return the event stream message, or error if Decode fails to read
|
||||
// the message from the stream.
|
||||
func (d *Decoder) Decode(payloadBuf []byte) (m Message, err error) {
|
||||
reader := d.r
|
||||
if d.logger != nil {
|
||||
debugMsgBuf := bytes.NewBuffer(nil)
|
||||
reader = io.TeeReader(reader, debugMsgBuf)
|
||||
defer func() {
|
||||
logMessageDecode(d.logger, debugMsgBuf, m, err)
|
||||
}()
|
||||
}
|
||||
|
||||
crc := crc32.New(crc32IEEETable)
|
||||
hashReader := io.TeeReader(reader, crc)
|
||||
|
||||
prelude, err := decodePrelude(hashReader, crc)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
|
||||
if prelude.HeadersLen > 0 {
|
||||
lr := io.LimitReader(hashReader, int64(prelude.HeadersLen))
|
||||
m.Headers, err = decodeHeaders(lr)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
}
|
||||
|
||||
if payloadLen := prelude.PayloadLen(); payloadLen > 0 {
|
||||
buf, err := decodePayload(payloadBuf, io.LimitReader(hashReader, int64(payloadLen)))
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
m.Payload = buf
|
||||
}
|
||||
|
||||
msgCRC := crc.Sum32()
|
||||
if err := validateCRC(reader, msgCRC); err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UseLogger specifies the Logger that that the decoder should use to log the
|
||||
// message decode to.
|
||||
func (d *Decoder) UseLogger(logger aws.Logger) {
|
||||
d.logger = logger
|
||||
}
|
||||
|
||||
func logMessageDecode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, decodeErr error) {
|
||||
w := bytes.NewBuffer(nil)
|
||||
defer func() { logger.Log(w.String()) }()
|
||||
|
||||
fmt.Fprintf(w, "Raw message:\n%s\n",
|
||||
hex.Dump(msgBuf.Bytes()))
|
||||
|
||||
if decodeErr != nil {
|
||||
fmt.Fprintf(w, "Decode error: %v\n", decodeErr)
|
||||
return
|
||||
}
|
||||
|
||||
rawMsg, err := msg.rawMessage()
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "failed to create raw message, %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
decodedMsg := decodedMessage{
|
||||
rawMessage: rawMsg,
|
||||
Headers: decodedHeaders(msg.Headers),
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "Decoded message:\n")
|
||||
encoder := json.NewEncoder(w)
|
||||
if err := encoder.Encode(decodedMsg); err != nil {
|
||||
fmt.Fprintf(w, "failed to generate decoded message, %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func decodePrelude(r io.Reader, crc hash.Hash32) (messagePrelude, error) {
|
||||
var p messagePrelude
|
||||
|
||||
var err error
|
||||
p.Length, err = decodeUint32(r)
|
||||
if err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
p.HeadersLen, err = decodeUint32(r)
|
||||
if err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
if err := p.ValidateLens(); err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
preludeCRC := crc.Sum32()
|
||||
if err := validateCRC(r, preludeCRC); err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
p.PreludeCRC = preludeCRC
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func decodePayload(buf []byte, r io.Reader) ([]byte, error) {
|
||||
w := bytes.NewBuffer(buf[0:0])
|
||||
|
||||
_, err := io.Copy(w, r)
|
||||
return w.Bytes(), err
|
||||
}
|
||||
|
||||
func decodeUint8(r io.Reader) (uint8, error) {
|
||||
type byteReader interface {
|
||||
ReadByte() (byte, error)
|
||||
}
|
||||
|
||||
if br, ok := r.(byteReader); ok {
|
||||
v, err := br.ReadByte()
|
||||
return uint8(v), err
|
||||
}
|
||||
|
||||
var b [1]byte
|
||||
_, err := io.ReadFull(r, b[:])
|
||||
return uint8(b[0]), err
|
||||
}
|
||||
func decodeUint16(r io.Reader) (uint16, error) {
|
||||
var b [2]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint16(bs), nil
|
||||
}
|
||||
func decodeUint32(r io.Reader) (uint32, error) {
|
||||
var b [4]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint32(bs), nil
|
||||
}
|
||||
func decodeUint64(r io.Reader) (uint64, error) {
|
||||
var b [8]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint64(bs), nil
|
||||
}
|
||||
|
||||
func validateCRC(r io.Reader, expect uint32) error {
|
||||
msgCRC, err := decodeUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if msgCRC != expect {
|
||||
return ChecksumError{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWriteEncodedFromDecoded(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
f, err := os.Create(filepath.Join("testdata", "encoded", "positive", c.Name))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open %q, %v", c.Name, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
encoder := NewEncoder(f)
|
||||
|
||||
msg := c.Decoded.Message()
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
t.Errorf("failed to encode %q, %v", c.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_Decode(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
decoder := NewDecoder(bytes.NewBuffer(c.Encoded))
|
||||
|
||||
msg, err := decoder.Decode(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%s, expect no decode error, got %v", c.Name, err)
|
||||
}
|
||||
|
||||
raw, err := msg.rawMessage() // rawMessage will fail if payload read CRC fails
|
||||
if err != nil {
|
||||
t.Fatalf("%s, failed to get raw decoded message %v", c.Name, err)
|
||||
}
|
||||
|
||||
if e, a := c.Decoded.Length, raw.Length; e != a {
|
||||
t.Errorf("%s, expect %v length, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.HeadersLen, raw.HeadersLen; e != a {
|
||||
t.Errorf("%s, expect %v HeadersLen, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.PreludeCRC, raw.PreludeCRC; e != a {
|
||||
t.Errorf("%s, expect %v PreludeCRC, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := Headers(c.Decoded.Headers), msg.Headers; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s, expect %v headers, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.Payload, raw.Payload; !bytes.Equal(e, a) {
|
||||
t.Errorf("%s, expect %v payload, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.CRC, raw.CRC; e != a {
|
||||
t.Errorf("%s, expect %v CRC, got %v", c.Name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_Decode_Negative(t *testing.T) {
|
||||
cases, err := readNegativeTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load negative tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
decoder := NewDecoder(bytes.NewBuffer(c.Encoded))
|
||||
|
||||
msg, err := decoder.Decode(nil)
|
||||
if err == nil {
|
||||
rawMsg, rawMsgErr := msg.rawMessage()
|
||||
t.Fatalf("%s, expect error, got none, %s,\n%s\n%#v, %v\n", c.Name,
|
||||
c.Err, hex.Dump(c.Encoded), rawMsg, rawMsgErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testEncodedMsg = []byte{0, 0, 0, 61, 0, 0, 0, 32, 7, 253, 131, 150, 12, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 7, 0, 16, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115, 111, 110, 123, 39, 102, 111, 111, 39, 58, 39, 98, 97, 114, 39, 125, 141, 156, 8, 177}
|
||||
|
||||
func TestDecoder_DecodeMultipleMessages(t *testing.T) {
|
||||
const (
|
||||
expectMsgCount = 10
|
||||
expectPayloadLen = 13
|
||||
)
|
||||
|
||||
r := bytes.NewBuffer(nil)
|
||||
for i := 0; i < expectMsgCount; i++ {
|
||||
r.Write(testEncodedMsg)
|
||||
}
|
||||
|
||||
decoder := NewDecoder(r)
|
||||
|
||||
var err error
|
||||
var msg Message
|
||||
var count int
|
||||
for {
|
||||
msg, err = decoder.Decode(nil)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
count++
|
||||
|
||||
if e, a := expectPayloadLen, len(msg.Payload); e != a {
|
||||
t.Errorf("expect %v payload len, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := []byte(`{'foo':'bar'}`), msg.Payload; !bytes.Equal(e, a) {
|
||||
t.Errorf("expect %v payload, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
type causer interface {
|
||||
Cause() error
|
||||
}
|
||||
if err != nil && count != expectMsgCount {
|
||||
t.Fatalf("expect, no error, got %v", err)
|
||||
}
|
||||
|
||||
if e, a := expectMsgCount, count; e != a {
|
||||
t.Errorf("expect %v messages read, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecode(b *testing.B) {
|
||||
r := bytes.NewReader(testEncodedMsg)
|
||||
decoder := NewDecoder(r)
|
||||
payloadBuf := make([]byte, 0, 5*1024)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
msg, err := decoder.Decode(payloadBuf)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
// Release the payload buffer
|
||||
payloadBuf = msg.Payload[0:0]
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecode_NoPayloadBuf(b *testing.B) {
|
||||
r := bytes.NewReader(testEncodedMsg)
|
||||
decoder := NewDecoder(r)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := decoder.Decode(nil)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Encoder provides EventStream message encoding.
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
|
||||
headersBuf *bytes.Buffer
|
||||
}
|
||||
|
||||
// NewEncoder initializes and returns an Encoder to encode Event Stream
|
||||
// messages to an io.Writer.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
w: w,
|
||||
headersBuf: bytes.NewBuffer(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// Encode encodes a single EventStream message to the io.Writer the Encoder
|
||||
// was created with. An error is returned if writing the message fails.
|
||||
func (e *Encoder) Encode(msg Message) error {
|
||||
e.headersBuf.Reset()
|
||||
|
||||
err := encodeHeaders(e.headersBuf, msg.Headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
crc := crc32.New(crc32IEEETable)
|
||||
hashWriter := io.MultiWriter(e.w, crc)
|
||||
|
||||
headersLen := uint32(e.headersBuf.Len())
|
||||
payloadLen := uint32(len(msg.Payload))
|
||||
|
||||
if err := encodePrelude(hashWriter, crc, headersLen, payloadLen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if headersLen > 0 {
|
||||
if _, err := io.Copy(hashWriter, e.headersBuf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if payloadLen > 0 {
|
||||
if _, err := hashWriter.Write(msg.Payload); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
msgCRC := crc.Sum32()
|
||||
return binary.Write(e.w, binary.BigEndian, msgCRC)
|
||||
}
|
||||
|
||||
func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32) error {
|
||||
p := messagePrelude{
|
||||
Length: minMsgLen + headersLen + payloadLen,
|
||||
HeadersLen: headersLen,
|
||||
}
|
||||
if err := p.ValidateLens(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
p.Length,
|
||||
p.HeadersLen,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.PreludeCRC = crc.Sum32()
|
||||
err = binary.Write(w, binary.BigEndian, p.PreludeCRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeHeaders(w io.Writer, headers Headers) error {
|
||||
for _, h := range headers {
|
||||
hn := headerName{
|
||||
Len: uint8(len(h.Name)),
|
||||
}
|
||||
copy(hn.Name[:hn.Len], h.Name)
|
||||
if err := hn.encode(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := h.Value.encode(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func binaryWriteFields(w io.Writer, order binary.ByteOrder, vs ...interface{}) error {
|
||||
for _, v := range vs {
|
||||
if err := binary.Write(w, order, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEncoder_Encode(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var w bytes.Buffer
|
||||
encoder := NewEncoder(&w)
|
||||
|
||||
err = encoder.Encode(c.Decoded.Message())
|
||||
if err != nil {
|
||||
t.Fatalf("%s, failed to encode message, %v", c.Name, err)
|
||||
}
|
||||
|
||||
if e, a := c.Encoded, w.Bytes(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s, expect:\n%v\nactual:\n%v\n", c.Name,
|
||||
hex.Dump(e), hex.Dump(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
var w bytes.Buffer
|
||||
encoder := NewEncoder(&w)
|
||||
msg := Message{
|
||||
Headers: Headers{
|
||||
{Name: "event-id", Value: Int16Value(123)},
|
||||
},
|
||||
Payload: []byte(`{"abc":123}`),
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := encoder.Encode(msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package eventstream
|
||||
|
||||
import "fmt"
|
||||
|
||||
// LengthError provides the error for items being larger than a maximum length.
|
||||
type LengthError struct {
|
||||
Part string
|
||||
Want int
|
||||
Have int
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (e LengthError) Error() string {
|
||||
return fmt.Sprintf("%s length invalid, %d/%d, %v",
|
||||
e.Part, e.Want, e.Have, e.Value)
|
||||
}
|
||||
|
||||
// ChecksumError provides the error for message checksum invalidation errors.
|
||||
type ChecksumError struct{}
|
||||
|
||||
func (e ChecksumError) Error() string {
|
||||
return "message checksum mismatch"
|
||||
}
|
||||
Generated
Vendored
+196
@@ -0,0 +1,196 @@
|
||||
package eventstreamapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
)
|
||||
|
||||
// Unmarshaler provides the interface for unmarshaling a EventStream
|
||||
// message into a SDK type.
|
||||
type Unmarshaler interface {
|
||||
UnmarshalEvent(protocol.PayloadUnmarshaler, eventstream.Message) error
|
||||
}
|
||||
|
||||
// EventStream headers with specific meaning to async API functionality.
|
||||
const (
|
||||
MessageTypeHeader = `:message-type` // Identifies type of message.
|
||||
EventMessageType = `event`
|
||||
ErrorMessageType = `error`
|
||||
ExceptionMessageType = `exception`
|
||||
|
||||
// Message Events
|
||||
EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats".
|
||||
|
||||
// Message Error
|
||||
ErrorCodeHeader = `:error-code`
|
||||
ErrorMessageHeader = `:error-message`
|
||||
|
||||
// Message Exception
|
||||
ExceptionTypeHeader = `:exception-type`
|
||||
)
|
||||
|
||||
// EventReader provides reading from the EventStream of an reader.
|
||||
type EventReader struct {
|
||||
reader io.ReadCloser
|
||||
decoder *eventstream.Decoder
|
||||
|
||||
unmarshalerForEventType func(string) (Unmarshaler, error)
|
||||
payloadUnmarshaler protocol.PayloadUnmarshaler
|
||||
|
||||
payloadBuf []byte
|
||||
}
|
||||
|
||||
// NewEventReader returns a EventReader built from the reader and unmarshaler
|
||||
// provided. Use ReadStream method to start reading from the EventStream.
|
||||
func NewEventReader(
|
||||
reader io.ReadCloser,
|
||||
payloadUnmarshaler protocol.PayloadUnmarshaler,
|
||||
unmarshalerForEventType func(string) (Unmarshaler, error),
|
||||
) *EventReader {
|
||||
return &EventReader{
|
||||
reader: reader,
|
||||
decoder: eventstream.NewDecoder(reader),
|
||||
payloadUnmarshaler: payloadUnmarshaler,
|
||||
unmarshalerForEventType: unmarshalerForEventType,
|
||||
payloadBuf: make([]byte, 10*1024),
|
||||
}
|
||||
}
|
||||
|
||||
// UseLogger instructs the EventReader to use the logger and log level
|
||||
// specified.
|
||||
func (r *EventReader) UseLogger(logger aws.Logger, logLevel aws.LogLevelType) {
|
||||
if logger != nil && logLevel.Matches(aws.LogDebugWithEventStreamBody) {
|
||||
r.decoder.UseLogger(logger)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadEvent attempts to read a message from the EventStream and return the
|
||||
// unmarshaled event value that the message is for.
|
||||
//
|
||||
// For EventStream API errors check if the returned error satisfies the
|
||||
// awserr.Error interface to get the error's Code and Message components.
|
||||
//
|
||||
// EventUnmarshalers called with EventStream messages must take copies of the
|
||||
// message's Payload. The payload will is reused between events read.
|
||||
func (r *EventReader) ReadEvent() (event interface{}, err error) {
|
||||
msg, err := r.decoder.Decode(r.payloadBuf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
// Reclaim payload buffer for next message read.
|
||||
r.payloadBuf = msg.Payload[0:0]
|
||||
}()
|
||||
|
||||
typ, err := GetHeaderString(msg, MessageTypeHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case EventMessageType:
|
||||
return r.unmarshalEventMessage(msg)
|
||||
case ExceptionMessageType:
|
||||
err = r.unmarshalEventException(msg)
|
||||
return nil, err
|
||||
case ErrorMessageType:
|
||||
return nil, r.unmarshalErrorMessage(msg)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown eventstream message type, %v", typ)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalEventMessage(
|
||||
msg eventstream.Message,
|
||||
) (event interface{}, err error) {
|
||||
eventType, err := GetHeaderString(msg, EventTypeHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ev, err := r.unmarshalerForEventType(eventType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ev, nil
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalEventException(
|
||||
msg eventstream.Message,
|
||||
) (err error) {
|
||||
eventType, err := GetHeaderString(msg, ExceptionTypeHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ev, err := r.unmarshalerForEventType(eventType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ok bool
|
||||
err, ok = ev.(error)
|
||||
if !ok {
|
||||
err = messageError{
|
||||
code: "SerializationError",
|
||||
msg: fmt.Sprintf(
|
||||
"event stream exception %s mapped to non-error %T, %v",
|
||||
eventType, ev, ev,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalErrorMessage(msg eventstream.Message) (err error) {
|
||||
var msgErr messageError
|
||||
|
||||
msgErr.code, err = GetHeaderString(msg, ErrorCodeHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgErr.msg, err = GetHeaderString(msg, ErrorMessageHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return msgErr
|
||||
}
|
||||
|
||||
// Close closes the EventReader's EventStream reader.
|
||||
func (r *EventReader) Close() error {
|
||||
return r.reader.Close()
|
||||
}
|
||||
|
||||
// GetHeaderString returns the value of the header as a string. If the header
|
||||
// is not set or the value is not a string an error will be returned.
|
||||
func GetHeaderString(msg eventstream.Message, headerName string) (string, error) {
|
||||
headerVal := msg.Headers.Get(headerName)
|
||||
if headerVal == nil {
|
||||
return "", fmt.Errorf("error header %s not present", headerName)
|
||||
}
|
||||
|
||||
v, ok := headerVal.Get().(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("error header value is not a string, %T", headerVal)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
Generated
Vendored
+253
@@ -0,0 +1,253 @@
|
||||
package eventstreamapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
var eventMessageTypeHeader = eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(EventMessageType),
|
||||
}
|
||||
|
||||
func TestEventReader(t *testing.T) {
|
||||
stream := createStream(
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventABC"),
|
||||
},
|
||||
},
|
||||
},
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventEFG"),
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
|
||||
if event == nil {
|
||||
t.Fatalf("expect event got none")
|
||||
}
|
||||
|
||||
event, err = eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error for unknown event, got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %T, %v", event, event)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventReader_Error(t *testing.T) {
|
||||
stream := createStream(
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(ErrorMessageType),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ErrorCodeHeader,
|
||||
Value: eventstream.StringValue("errorCode"),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ErrorMessageHeader,
|
||||
Value: eventstream.StringValue("error message occur"),
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %v", event)
|
||||
}
|
||||
|
||||
if e, a := "errorCode: error message occur", err.Error(); e != a {
|
||||
t.Errorf("expect %v error, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventReader_Exception(t *testing.T) {
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(ExceptionMessageType),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ExceptionTypeHeader,
|
||||
Value: eventstream.StringValue("exception"),
|
||||
},
|
||||
},
|
||||
Payload: []byte(`{"message":"exception message"}`),
|
||||
},
|
||||
}
|
||||
stream := createStream(eventMsgs...)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %v", event)
|
||||
}
|
||||
|
||||
et := err.(*exceptionType)
|
||||
if e, a := string(eventMsgs[0].Payload), string(et.Payload); e != a {
|
||||
t.Errorf("expect %v payload, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEventReader(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
msg := eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventABC"),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
stream := bytes.NewReader(buf.Bytes())
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(ioutil.NopCloser(stream),
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
stream.Seek(0, 0)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
if event == nil {
|
||||
b.Fatalf("expect event got none")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalerForEventType(eventType string) (Unmarshaler, error) {
|
||||
switch eventType {
|
||||
case "eventABC":
|
||||
return &eventABC{}, nil
|
||||
case "exception":
|
||||
return &exceptionType{}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown event type, %v", eventType)
|
||||
}
|
||||
}
|
||||
|
||||
type eventABC struct {
|
||||
_ struct{}
|
||||
|
||||
HeaderField string
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (e *eventABC) UnmarshalEvent(
|
||||
unmarshaler protocol.PayloadUnmarshaler,
|
||||
msg eventstream.Message,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createStream(msgs ...eventstream.Message) io.ReadCloser {
|
||||
w := bytes.NewBuffer(nil)
|
||||
|
||||
encoder := eventstream.NewEncoder(w)
|
||||
|
||||
for _, msg := range msgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
panic("createStream failed, " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return ioutil.NopCloser(w)
|
||||
}
|
||||
|
||||
type exceptionType struct {
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (e exceptionType) Error() string {
|
||||
return fmt.Sprintf("exception error message")
|
||||
}
|
||||
|
||||
func (e *exceptionType) UnmarshalEvent(
|
||||
unmarshaler protocol.PayloadUnmarshaler,
|
||||
msg eventstream.Message,
|
||||
) error {
|
||||
e.Payload = msg.Payload
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
package eventstreamapi
|
||||
|
||||
import "fmt"
|
||||
|
||||
type messageError struct {
|
||||
code string
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e messageError) Code() string {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e messageError) Message() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func (e messageError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.code, e.msg)
|
||||
}
|
||||
|
||||
func (e messageError) OrigErr() error {
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// +build !go1.10
|
||||
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
)
|
||||
|
||||
// /x/net/http2 is only available for the latest two versions of Go. Any Go
|
||||
// version older than that cannot use the utility to configure the http2
|
||||
// server.
|
||||
func setupServer(server *httptest.Server, useH2 bool) *http.Client {
|
||||
server.Start()
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
// +build go1.10
|
||||
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
// /x/net/http2 is only available for the latest two versions of Go. Any Go
|
||||
// version older than that cannot use the utility to configure the http2
|
||||
// server.
|
||||
func setupServer(server *httptest.Server, useH2 bool) *http.Client {
|
||||
server.Config.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
clientTrans := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
|
||||
if useH2 {
|
||||
http2.ConfigureServer(server.Config, nil)
|
||||
http2.ConfigureTransport(clientTrans)
|
||||
server.Config.TLSConfig.NextProtos = []string{http2.NextProtoTLS}
|
||||
clientTrans.TLSClientConfig.NextProtos = []string{http2.NextProtoTLS}
|
||||
}
|
||||
server.TLS = server.Config.TLSConfig
|
||||
|
||||
server.StartTLS()
|
||||
|
||||
return &http.Client{
|
||||
Transport: clientTrans,
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
|
||||
)
|
||||
|
||||
// ServeEventStream provides serving EventStream messages from a HTTP server to
|
||||
// the client. The events are sent sequentially to the client without delay.
|
||||
type ServeEventStream struct {
|
||||
T *testing.T
|
||||
Events []eventstream.Message
|
||||
}
|
||||
|
||||
func (s ServeEventStream) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
encoder := eventstream.NewEncoder(flushWriter{w})
|
||||
|
||||
for _, event := range s.Events {
|
||||
encoder.Encode(event)
|
||||
}
|
||||
}
|
||||
|
||||
// SetupEventStreamSession creates a HTTP server SDK session for communicating
|
||||
// with that server to be used for EventStream APIs. If HTTP/2 is enabled the
|
||||
// server/client will only attempt to use HTTP/2.
|
||||
func SetupEventStreamSession(
|
||||
t *testing.T, handler http.Handler, h2 bool,
|
||||
) (sess *session.Session, cleanupFn func(), err error) {
|
||||
server := httptest.NewUnstartedServer(handler)
|
||||
|
||||
client := setupServer(server, h2)
|
||||
|
||||
cleanupFn = func() {
|
||||
server.Close()
|
||||
}
|
||||
|
||||
sess, err = session.NewSession(unit.Session.Config, &aws.Config{
|
||||
Endpoint: &server.URL,
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
HTTPClient: client,
|
||||
// LogLevel: aws.LogLevel(aws.LogDebugWithEventStreamBody),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sess, cleanupFn, nil
|
||||
}
|
||||
|
||||
type flushWriter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (fw flushWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = fw.w.Write(p)
|
||||
if f, ok := fw.w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalEventPayload marshals a SDK API shape into its associated wire
|
||||
// protocol payload.
|
||||
func MarshalEventPayload(
|
||||
payloadMarshaler protocol.PayloadMarshaler,
|
||||
v interface{},
|
||||
) []byte {
|
||||
var w bytes.Buffer
|
||||
err := payloadMarshaler.MarshalPayload(&w, v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to marshal event %T, %v", v, v))
|
||||
}
|
||||
|
||||
return w.Bytes()
|
||||
}
|
||||
|
||||
// EventMessageTypeHeader is an event message type header for specifying an
|
||||
// event is an message type.
|
||||
var EventMessageTypeHeader = eventstream.Header{
|
||||
Name: eventstreamapi.MessageTypeHeader,
|
||||
Value: eventstream.StringValue(eventstreamapi.EventMessageType),
|
||||
}
|
||||
|
||||
// EventExceptionTypeHeader is an event exception type header for specifying an
|
||||
// event is an exeption type.
|
||||
var EventExceptionTypeHeader = eventstream.Header{
|
||||
Name: eventstreamapi.MessageTypeHeader,
|
||||
Value: eventstream.StringValue(eventstreamapi.ExceptionMessageType),
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Headers are a collection of EventStream header values.
|
||||
type Headers []Header
|
||||
|
||||
// Header is a single EventStream Key Value header pair.
|
||||
type Header struct {
|
||||
Name string
|
||||
Value Value
|
||||
}
|
||||
|
||||
// Set associates the name with a value. If the header name already exists in
|
||||
// the Headers the value will be replaced with the new one.
|
||||
func (hs *Headers) Set(name string, value Value) {
|
||||
var i int
|
||||
for ; i < len(*hs); i++ {
|
||||
if (*hs)[i].Name == name {
|
||||
(*hs)[i].Value = value
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
*hs = append(*hs, Header{
|
||||
Name: name, Value: value,
|
||||
})
|
||||
}
|
||||
|
||||
// Get returns the Value associated with the header. Nil is returned if the
|
||||
// value does not exist.
|
||||
func (hs Headers) Get(name string) Value {
|
||||
for i := 0; i < len(hs); i++ {
|
||||
if h := hs[i]; h.Name == name {
|
||||
return h.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Del deletes the value in the Headers if it exists.
|
||||
func (hs *Headers) Del(name string) {
|
||||
for i := 0; i < len(*hs); i++ {
|
||||
if (*hs)[i].Name == name {
|
||||
copy((*hs)[i:], (*hs)[i+1:])
|
||||
(*hs) = (*hs)[:len(*hs)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeHeaders(r io.Reader) (Headers, error) {
|
||||
hs := Headers{}
|
||||
|
||||
for {
|
||||
name, err := decodeHeaderName(r)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
// EOF while getting header name means no more headers
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value, err := decodeHeaderValue(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hs.Set(name, value)
|
||||
}
|
||||
|
||||
return hs, nil
|
||||
}
|
||||
|
||||
func decodeHeaderName(r io.Reader) (string, error) {
|
||||
var n headerName
|
||||
|
||||
var err error
|
||||
n.Len, err = decodeUint8(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
name := n.Name[:n.Len]
|
||||
if _, err := io.ReadFull(r, name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(name), nil
|
||||
}
|
||||
|
||||
func decodeHeaderValue(r io.Reader) (Value, error) {
|
||||
var raw rawValue
|
||||
|
||||
typ, err := decodeUint8(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw.Type = valueType(typ)
|
||||
|
||||
var v Value
|
||||
|
||||
switch raw.Type {
|
||||
case trueValueType:
|
||||
v = BoolValue(true)
|
||||
case falseValueType:
|
||||
v = BoolValue(false)
|
||||
case int8ValueType:
|
||||
var tv Int8Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int16ValueType:
|
||||
var tv Int16Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int32ValueType:
|
||||
var tv Int32Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int64ValueType:
|
||||
var tv Int64Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case bytesValueType:
|
||||
var tv BytesValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case stringValueType:
|
||||
var tv StringValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case timestampValueType:
|
||||
var tv TimestampValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case uuidValueType:
|
||||
var tv UUIDValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown value type %d", raw.Type))
|
||||
}
|
||||
|
||||
// Error could be EOF, let caller deal with it
|
||||
return v, err
|
||||
}
|
||||
|
||||
const maxHeaderNameLen = 255
|
||||
|
||||
type headerName struct {
|
||||
Len uint8
|
||||
Name [maxHeaderNameLen]byte
|
||||
}
|
||||
|
||||
func (v headerName) encode(w io.Writer) error {
|
||||
if err := binary.Write(w, binary.BigEndian, v.Len); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := w.Write(v.Name[:v.Len])
|
||||
return err
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHeaders_Set(t *testing.T) {
|
||||
expect := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
var actual Headers
|
||||
actual.Set("ABC", Int32Value(123))
|
||||
actual.Set("ABC", StringValue("123")) // replace case
|
||||
actual.Set("EFG", TimestampValue(time.Time{}))
|
||||
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v headers, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders_Get(t *testing.T) {
|
||||
headers := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
Name string
|
||||
Value Value
|
||||
}{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
{Name: "NotFound"},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
actual := headers.Get(c.Name)
|
||||
if e, a := c.Value, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v value, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders_Del(t *testing.T) {
|
||||
headers := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
{Name: "HIJ", Value: StringValue("123")},
|
||||
{Name: "KML", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
expectAfterDel := Headers{
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
headers.Del("HIJ")
|
||||
headers.Del("ABC")
|
||||
headers.Del("KML")
|
||||
|
||||
if e, a := expectAfterDel, headers; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v headers, got %v", e, a)
|
||||
}
|
||||
}
|
||||
+501
@@ -0,0 +1,501 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const maxHeaderValueLen = 1<<15 - 1 // 2^15-1 or 32KB - 1
|
||||
|
||||
// valueType is the EventStream header value type.
|
||||
type valueType uint8
|
||||
|
||||
// Header value types
|
||||
const (
|
||||
trueValueType valueType = iota
|
||||
falseValueType
|
||||
int8ValueType // Byte
|
||||
int16ValueType // Short
|
||||
int32ValueType // Integer
|
||||
int64ValueType // Long
|
||||
bytesValueType
|
||||
stringValueType
|
||||
timestampValueType
|
||||
uuidValueType
|
||||
)
|
||||
|
||||
func (t valueType) String() string {
|
||||
switch t {
|
||||
case trueValueType:
|
||||
return "bool"
|
||||
case falseValueType:
|
||||
return "bool"
|
||||
case int8ValueType:
|
||||
return "int8"
|
||||
case int16ValueType:
|
||||
return "int16"
|
||||
case int32ValueType:
|
||||
return "int32"
|
||||
case int64ValueType:
|
||||
return "int64"
|
||||
case bytesValueType:
|
||||
return "byte_array"
|
||||
case stringValueType:
|
||||
return "string"
|
||||
case timestampValueType:
|
||||
return "timestamp"
|
||||
case uuidValueType:
|
||||
return "uuid"
|
||||
default:
|
||||
return fmt.Sprintf("unknown value type %d", uint8(t))
|
||||
}
|
||||
}
|
||||
|
||||
type rawValue struct {
|
||||
Type valueType
|
||||
Len uint16 // Only set for variable length slices
|
||||
Value []byte // byte representation of value, BigEndian encoding.
|
||||
}
|
||||
|
||||
func (r rawValue) encodeScalar(w io.Writer, v interface{}) error {
|
||||
return binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
v,
|
||||
)
|
||||
}
|
||||
|
||||
func (r rawValue) encodeFixedSlice(w io.Writer, v []byte) error {
|
||||
binary.Write(w, binary.BigEndian, r.Type)
|
||||
|
||||
_, err := w.Write(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r rawValue) encodeBytes(w io.Writer, v []byte) error {
|
||||
if len(v) > maxHeaderValueLen {
|
||||
return LengthError{
|
||||
Part: "header value",
|
||||
Want: maxHeaderValueLen, Have: len(v),
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
r.Len = uint16(len(v))
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
r.Len,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r rawValue) encodeString(w io.Writer, v string) error {
|
||||
if len(v) > maxHeaderValueLen {
|
||||
return LengthError{
|
||||
Part: "header value",
|
||||
Want: maxHeaderValueLen, Have: len(v),
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
r.Len = uint16(len(v))
|
||||
|
||||
type stringWriter interface {
|
||||
WriteString(string) (int, error)
|
||||
}
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
r.Len,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sw, ok := w.(stringWriter); ok {
|
||||
_, err = sw.WriteString(v)
|
||||
} else {
|
||||
_, err = w.Write([]byte(v))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func decodeFixedBytesValue(r io.Reader, buf []byte) error {
|
||||
_, err := io.ReadFull(r, buf)
|
||||
return err
|
||||
}
|
||||
|
||||
func decodeBytesValue(r io.Reader) ([]byte, error) {
|
||||
var raw rawValue
|
||||
var err error
|
||||
raw.Len, err = decodeUint16(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, raw.Len)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func decodeStringValue(r io.Reader) (string, error) {
|
||||
v, err := decodeBytesValue(r)
|
||||
return string(v), err
|
||||
}
|
||||
|
||||
// Value represents the abstract header value.
|
||||
type Value interface {
|
||||
Get() interface{}
|
||||
String() string
|
||||
valueType() valueType
|
||||
encode(io.Writer) error
|
||||
}
|
||||
|
||||
// An BoolValue provides eventstream encoding, and representation
|
||||
// of a Go bool value.
|
||||
type BoolValue bool
|
||||
|
||||
// Get returns the underlying type
|
||||
func (v BoolValue) Get() interface{} {
|
||||
return bool(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (v BoolValue) valueType() valueType {
|
||||
if v {
|
||||
return trueValueType
|
||||
}
|
||||
return falseValueType
|
||||
}
|
||||
|
||||
func (v BoolValue) String() string {
|
||||
return strconv.FormatBool(bool(v))
|
||||
}
|
||||
|
||||
// encode encodes the BoolValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v BoolValue) encode(w io.Writer) error {
|
||||
return binary.Write(w, binary.BigEndian, v.valueType())
|
||||
}
|
||||
|
||||
// An Int8Value provides eventstream encoding, and representation of a Go
|
||||
// int8 value.
|
||||
type Int8Value int8
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int8Value) Get() interface{} {
|
||||
return int8(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int8Value) valueType() valueType {
|
||||
return int8ValueType
|
||||
}
|
||||
|
||||
func (v Int8Value) String() string {
|
||||
return fmt.Sprintf("0x%02x", int8(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int8Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int8Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int8Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint8(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int8Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int16Value provides eventstream encoding, and representation of a Go
|
||||
// int16 value.
|
||||
type Int16Value int16
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int16Value) Get() interface{} {
|
||||
return int16(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int16Value) valueType() valueType {
|
||||
return int16ValueType
|
||||
}
|
||||
|
||||
func (v Int16Value) String() string {
|
||||
return fmt.Sprintf("0x%04x", int16(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int16Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int16Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int16Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint16(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int16Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int32Value provides eventstream encoding, and representation of a Go
|
||||
// int32 value.
|
||||
type Int32Value int32
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int32Value) Get() interface{} {
|
||||
return int32(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int32Value) valueType() valueType {
|
||||
return int32ValueType
|
||||
}
|
||||
|
||||
func (v Int32Value) String() string {
|
||||
return fmt.Sprintf("0x%08x", int32(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int32Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int32Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int32Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int32Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int64Value provides eventstream encoding, and representation of a Go
|
||||
// int64 value.
|
||||
type Int64Value int64
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int64Value) Get() interface{} {
|
||||
return int64(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int64Value) valueType() valueType {
|
||||
return int64ValueType
|
||||
}
|
||||
|
||||
func (v Int64Value) String() string {
|
||||
return fmt.Sprintf("0x%016x", int64(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int64Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int64Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int64Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint64(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int64Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An BytesValue provides eventstream encoding, and representation of a Go
|
||||
// byte slice.
|
||||
type BytesValue []byte
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v BytesValue) Get() interface{} {
|
||||
return []byte(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (BytesValue) valueType() valueType {
|
||||
return bytesValueType
|
||||
}
|
||||
|
||||
func (v BytesValue) String() string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(v))
|
||||
}
|
||||
|
||||
// encode encodes the BytesValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v BytesValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeBytes(w, []byte(v))
|
||||
}
|
||||
|
||||
func (v *BytesValue) decode(r io.Reader) error {
|
||||
buf, err := decodeBytesValue(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = BytesValue(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An StringValue provides eventstream encoding, and representation of a Go
|
||||
// string.
|
||||
type StringValue string
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v StringValue) Get() interface{} {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (StringValue) valueType() valueType {
|
||||
return stringValueType
|
||||
}
|
||||
|
||||
func (v StringValue) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// encode encodes the StringValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v StringValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeString(w, string(v))
|
||||
}
|
||||
|
||||
func (v *StringValue) decode(r io.Reader) error {
|
||||
s, err := decodeStringValue(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = StringValue(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An TimestampValue provides eventstream encoding, and representation of a Go
|
||||
// timestamp.
|
||||
type TimestampValue time.Time
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v TimestampValue) Get() interface{} {
|
||||
return time.Time(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (TimestampValue) valueType() valueType {
|
||||
return timestampValueType
|
||||
}
|
||||
|
||||
func (v TimestampValue) epochMilli() int64 {
|
||||
nano := time.Time(v).UnixNano()
|
||||
msec := nano / int64(time.Millisecond)
|
||||
return msec
|
||||
}
|
||||
|
||||
func (v TimestampValue) String() string {
|
||||
msec := v.epochMilli()
|
||||
return strconv.FormatInt(msec, 10)
|
||||
}
|
||||
|
||||
// encode encodes the TimestampValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v TimestampValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
msec := v.epochMilli()
|
||||
return raw.encodeScalar(w, msec)
|
||||
}
|
||||
|
||||
func (v *TimestampValue) decode(r io.Reader) error {
|
||||
n, err := decodeUint64(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = TimestampValue(timeFromEpochMilli(int64(n)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func timeFromEpochMilli(t int64) time.Time {
|
||||
secs := t / 1e3
|
||||
msec := t % 1e3
|
||||
return time.Unix(secs, msec*int64(time.Millisecond)).UTC()
|
||||
}
|
||||
|
||||
// An UUIDValue provides eventstream encoding, and representation of a UUID
|
||||
// value.
|
||||
type UUIDValue [16]byte
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v UUIDValue) Get() interface{} {
|
||||
return v[:]
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (UUIDValue) valueType() valueType {
|
||||
return uuidValueType
|
||||
}
|
||||
|
||||
func (v UUIDValue) String() string {
|
||||
return fmt.Sprintf(`%X-%X-%X-%X-%X`, v[0:4], v[4:6], v[6:8], v[8:10], v[10:])
|
||||
}
|
||||
|
||||
// encode encodes the UUIDValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v UUIDValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeFixedSlice(w, v[:])
|
||||
}
|
||||
|
||||
func (v *UUIDValue) decode(r io.Reader) error {
|
||||
tv := (*v)[:]
|
||||
return decodeFixedBytesValue(r, tv)
|
||||
}
|
||||
Generated
Vendored
+203
@@ -0,0 +1,203 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func binWrite(v interface{}) []byte {
|
||||
var w bytes.Buffer
|
||||
binary.Write(&w, binary.BigEndian, v)
|
||||
return w.Bytes()
|
||||
}
|
||||
|
||||
var testValueEncodingCases = []struct {
|
||||
Val Value
|
||||
Expect []byte
|
||||
Decode func(io.Reader) (Value, error)
|
||||
}{
|
||||
{
|
||||
BoolValue(true),
|
||||
[]byte{byte(trueValueType)},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
BoolValue(false),
|
||||
[]byte{byte(falseValueType)},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
Int8Value(0x0f),
|
||||
[]byte{byte(int8ValueType), 0x0f},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int8Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int16Value(0x0f),
|
||||
append([]byte{byte(int16ValueType)}, binWrite(int16(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int16Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int32Value(0x0f),
|
||||
append([]byte{byte(int32ValueType)}, binWrite(int32(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int32Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int64Value(0x0f),
|
||||
append([]byte{byte(int64ValueType)}, binWrite(int64(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int64Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
BytesValue([]byte{0, 1, 2, 3}),
|
||||
[]byte{byte(bytesValueType), 0x00, 0x04, 0, 1, 2, 3},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v BytesValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
StringValue("abc123"),
|
||||
append([]byte{byte(stringValueType), 0, 6}, []byte("abc123")...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v StringValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
TimestampValue(
|
||||
time.Date(2014, 04, 04, 0, 1, 0, 0, time.FixedZone("PDT", -7)),
|
||||
),
|
||||
append([]byte{byte(timestampValueType)}, binWrite(int64(1396569667000))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v TimestampValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
UUIDValue(
|
||||
[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf},
|
||||
),
|
||||
[]byte{byte(uuidValueType), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v UUIDValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestValue_MarshalValue(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
var w bytes.Buffer
|
||||
|
||||
if err := c.Val.encode(&w); err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
if e, a := c.Expect, w.Bytes(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeader_DecodeValues(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
r := bytes.NewBuffer(c.Expect)
|
||||
v, err := decodeHeaderValue(r)
|
||||
if err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
switch tv := v.(type) {
|
||||
case TimestampValue:
|
||||
exp := time.Time(c.Val.(TimestampValue))
|
||||
if e, a := exp, time.Time(tv); !e.Equal(a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
default:
|
||||
if e, a := c.Val, v; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue_Decode(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
if c.Decode == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := bytes.NewBuffer(c.Expect)
|
||||
r.ReadByte() // strip off Type field
|
||||
|
||||
v, err := c.Decode(r)
|
||||
if err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
switch tv := v.(type) {
|
||||
case TimestampValue:
|
||||
exp := time.Time(c.Val.(TimestampValue))
|
||||
if e, a := exp, time.Time(tv); !e.Equal(a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
default:
|
||||
if e, a := c.Val, v; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue_String(t *testing.T) {
|
||||
cases := []struct {
|
||||
Val Value
|
||||
Expect string
|
||||
}{
|
||||
{BoolValue(true), "true"},
|
||||
{BoolValue(false), "false"},
|
||||
{Int8Value(0x0f), "0x0f"},
|
||||
{Int16Value(0x0f), "0x000f"},
|
||||
{Int32Value(0x0f), "0x0000000f"},
|
||||
{Int64Value(0x0f), "0x000000000000000f"},
|
||||
{BytesValue([]byte{0, 1, 2, 3}), "AAECAw=="},
|
||||
{StringValue("abc123"), "abc123"},
|
||||
{TimestampValue(
|
||||
time.Date(2014, 04, 04, 0, 1, 0, 0, time.FixedZone("PDT", -7)),
|
||||
),
|
||||
"1396569667000",
|
||||
},
|
||||
{UUIDValue([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}),
|
||||
"00010203-0405-0607-0809-0A0B0C0D0E0F",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
if e, a := c.Expect, c.Val.String(); e != a {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
const preludeLen = 8
|
||||
const preludeCRCLen = 4
|
||||
const msgCRCLen = 4
|
||||
const minMsgLen = preludeLen + preludeCRCLen + msgCRCLen
|
||||
const maxPayloadLen = 1024 * 1024 * 16 // 16MB
|
||||
const maxHeadersLen = 1024 * 128 // 128KB
|
||||
const maxMsgLen = minMsgLen + maxHeadersLen + maxPayloadLen
|
||||
|
||||
var crc32IEEETable = crc32.MakeTable(crc32.IEEE)
|
||||
|
||||
// A Message provides the eventstream message representation.
|
||||
type Message struct {
|
||||
Headers Headers
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (m *Message) rawMessage() (rawMessage, error) {
|
||||
var raw rawMessage
|
||||
|
||||
if len(m.Headers) > 0 {
|
||||
var headers bytes.Buffer
|
||||
if err := encodeHeaders(&headers, m.Headers); err != nil {
|
||||
return rawMessage{}, err
|
||||
}
|
||||
raw.Headers = headers.Bytes()
|
||||
raw.HeadersLen = uint32(len(raw.Headers))
|
||||
}
|
||||
|
||||
raw.Length = raw.HeadersLen + uint32(len(m.Payload)) + minMsgLen
|
||||
|
||||
hash := crc32.New(crc32IEEETable)
|
||||
binaryWriteFields(hash, binary.BigEndian, raw.Length, raw.HeadersLen)
|
||||
raw.PreludeCRC = hash.Sum32()
|
||||
|
||||
binaryWriteFields(hash, binary.BigEndian, raw.PreludeCRC)
|
||||
|
||||
if raw.HeadersLen > 0 {
|
||||
hash.Write(raw.Headers)
|
||||
}
|
||||
|
||||
// Read payload bytes and update hash for it as well.
|
||||
if len(m.Payload) > 0 {
|
||||
raw.Payload = m.Payload
|
||||
hash.Write(raw.Payload)
|
||||
}
|
||||
|
||||
raw.CRC = hash.Sum32()
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
type messagePrelude struct {
|
||||
Length uint32
|
||||
HeadersLen uint32
|
||||
PreludeCRC uint32
|
||||
}
|
||||
|
||||
func (p messagePrelude) PayloadLen() uint32 {
|
||||
return p.Length - p.HeadersLen - minMsgLen
|
||||
}
|
||||
|
||||
func (p messagePrelude) ValidateLens() error {
|
||||
if p.Length == 0 || p.Length > maxMsgLen {
|
||||
return LengthError{
|
||||
Part: "message prelude",
|
||||
Want: maxMsgLen,
|
||||
Have: int(p.Length),
|
||||
}
|
||||
}
|
||||
if p.HeadersLen > maxHeadersLen {
|
||||
return LengthError{
|
||||
Part: "message headers",
|
||||
Want: maxHeadersLen,
|
||||
Have: int(p.HeadersLen),
|
||||
}
|
||||
}
|
||||
if payloadLen := p.PayloadLen(); payloadLen > maxPayloadLen {
|
||||
return LengthError{
|
||||
Part: "message payload",
|
||||
Want: maxPayloadLen,
|
||||
Have: int(payloadLen),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type rawMessage struct {
|
||||
messagePrelude
|
||||
|
||||
Headers []byte
|
||||
Payload []byte
|
||||
|
||||
CRC uint32
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
Name string
|
||||
Encoded []byte
|
||||
Decoded decodedMessage
|
||||
}
|
||||
|
||||
type testErrorCase struct {
|
||||
Name string
|
||||
Encoded []byte
|
||||
Err string
|
||||
}
|
||||
|
||||
type rawTestCase struct {
|
||||
Name string
|
||||
Encoded, Decoded []byte
|
||||
}
|
||||
|
||||
func readRawTestCases(root, class string) (map[string]rawTestCase, error) {
|
||||
encoded, err := readTests(filepath.Join(root, "encoded", class))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded, err := readTests(filepath.Join(root, "decoded", class))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(encoded) == 0 {
|
||||
return nil, fmt.Errorf("expect encoded cases, found none")
|
||||
}
|
||||
|
||||
if len(encoded) != len(decoded) {
|
||||
return nil, fmt.Errorf("encoded and decoded sets different")
|
||||
}
|
||||
|
||||
rawCases := map[string]rawTestCase{}
|
||||
for name, encData := range encoded {
|
||||
decData, ok := decoded[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("encoded %q case not found in decoded set", name)
|
||||
}
|
||||
|
||||
rawCases[name] = rawTestCase{
|
||||
Name: name,
|
||||
Encoded: encData,
|
||||
Decoded: decData,
|
||||
}
|
||||
}
|
||||
|
||||
return rawCases, nil
|
||||
}
|
||||
|
||||
func readNegativeTests(root string) ([]testErrorCase, error) {
|
||||
rawCases, err := readRawTestCases(root, "negative")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cases := make([]testErrorCase, 0, len(rawCases))
|
||||
for name, rawCase := range rawCases {
|
||||
cases = append(cases, testErrorCase{
|
||||
Name: name,
|
||||
Encoded: rawCase.Encoded,
|
||||
Err: string(rawCase.Decoded),
|
||||
})
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func readPositiveTests(root string) ([]testCase, error) {
|
||||
rawCases, err := readRawTestCases(root, "positive")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cases := make([]testCase, 0, len(rawCases))
|
||||
for name, rawCase := range rawCases {
|
||||
|
||||
var dec decodedMessage
|
||||
if err := json.Unmarshal(rawCase.Decoded, &dec); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode %q, %v", name, err)
|
||||
}
|
||||
|
||||
cases = append(cases, testCase{
|
||||
Name: name,
|
||||
Encoded: rawCase.Encoded,
|
||||
Decoded: dec,
|
||||
})
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func readTests(root string) (map[string][]byte, error) {
|
||||
items, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read test suite %q dirs, %v", root, err)
|
||||
}
|
||||
|
||||
cases := map[string][]byte{}
|
||||
for _, item := range items {
|
||||
if item.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
filename := filepath.Join(root, item.Name())
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read test_data file %q, %v", filename, err)
|
||||
}
|
||||
|
||||
cases[item.Name()] = data
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func compareLines(t *testing.T, a, b []byte) bool {
|
||||
as := bufio.NewScanner(bytes.NewBuffer(a))
|
||||
bs := bufio.NewScanner(bytes.NewBuffer(b))
|
||||
|
||||
var failed bool
|
||||
for {
|
||||
if ab, bb := as.Scan(), bs.Scan(); ab != bb {
|
||||
t.Errorf("expect a & b to have same number of lines")
|
||||
return false
|
||||
} else if !ab {
|
||||
break
|
||||
}
|
||||
|
||||
if v1, v2 := as.Text(), bs.Text(); v1 != v2 {
|
||||
t.Errorf("expect %q to be %q", v1, v2)
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
return !failed
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Prelude checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Message checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Prelude checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Message checksum mismatch
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"total_length": 204,
|
||||
"headers_length": 175,
|
||||
"prelude_crc": 263087306,
|
||||
"headers": [ {
|
||||
"name": "event-type",
|
||||
"type": 4,
|
||||
"value": 40972
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"type": 7,
|
||||
"value": "YXBwbGljYXRpb24vanNvbg=="
|
||||
},
|
||||
{
|
||||
"name": "bool false",
|
||||
"type": 1,
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "bool true",
|
||||
"type": 0,
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"name": "byte",
|
||||
"type": 2,
|
||||
"value": -49
|
||||
},
|
||||
{
|
||||
"name": "byte buf",
|
||||
"type": 6,
|
||||
"value": "SSdtIGEgbGl0dGxlIHRlYXBvdCE="
|
||||
},
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": 8,
|
||||
"value": 8675309
|
||||
},
|
||||
{
|
||||
"name": "int16",
|
||||
"type": 3,
|
||||
"value": 42
|
||||
},
|
||||
{
|
||||
"name": "int64",
|
||||
"type": 5,
|
||||
"value": 42424242
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"type": 9,
|
||||
"value": "AQIDBAUGBwgJCgsMDQ4PEA=="
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1415188212
|
||||
}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"total_length": 16,
|
||||
"headers_length": 0,
|
||||
"prelude_crc": 96618731,
|
||||
"headers": [ ],
|
||||
"payload": "",
|
||||
"message_crc": 2107164927
|
||||
}
|
||||
vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/testdata/decoded/positive/int32_header
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"total_length": 45,
|
||||
"headers_length": 16,
|
||||
"prelude_crc": 1103373496,
|
||||
"headers": [ {
|
||||
"name": "event-type",
|
||||
"type": 4,
|
||||
"value": 40972
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": 921993376
|
||||
}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"total_length": 29,
|
||||
"headers_length": 0,
|
||||
"prelude_crc": -44921766,
|
||||
"headers": [ ],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1016776394
|
||||
}
|
||||
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"total_length": 61,
|
||||
"headers_length": 32,
|
||||
"prelude_crc": 134054806,
|
||||
"headers": [ {
|
||||
"name": "content-type",
|
||||
"type": 7,
|
||||
"value": "YXBwbGljYXRpb24vanNvbg=="
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1919153999
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user