From 87a591fa582d6b4abefbcd1b46cd037dfc5ffdc3 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Wed, 8 Nov 2017 17:57:06 -0800 Subject: [PATCH] private/protocol/restjson:Define querystirng and body JSONValue marshaling Fix #1636 --- models/protocol_tests/generate.go | 3 +- models/protocol_tests/input/rest-json.json | 68 ++++- models/protocol_tests/output/rest-json.json | 63 ++-- private/model/api/param_filler.go | 14 + private/protocol/json/jsonutil/build.go | 21 +- private/protocol/json/jsonutil/unmarshal.go | 15 +- private/protocol/jsonvalue.go | 67 +++++ private/protocol/rest/build.go | 21 +- private/protocol/rest/unmarshal.go | 14 +- private/protocol/restjson/build_test.go | 203 +++++++++++-- private/protocol/restjson/unmarshal_test.go | 304 +++++++++----------- 11 files changed, 538 insertions(+), 255 deletions(-) create mode 100644 private/protocol/jsonvalue.go diff --git a/models/protocol_tests/generate.go b/models/protocol_tests/generate.go index 4f9e103fa97..7fd48bed9e8 100644 --- a/models/protocol_tests/generate.go +++ b/models/protocol_tests/generate.go @@ -459,7 +459,7 @@ func GenerateAssertions(out interface{}, shape *api.Shape, prefix string) string code += GenerateAssertions(v, s, prefix+"[\""+k+"\"]") } } else if shape.Type == "jsonvalue" { - code += fmt.Sprintf("reflect.DeepEqual(%s, map[string]interface{}%s)", prefix, walkMap(out.(map[string]interface{}))) + code += fmt.Sprintf("reflect.DeepEqual(%s, map[string]interface{}%s)\n", prefix, walkMap(out.(map[string]interface{}))) } else { for _, k := range keys { v := t[k] @@ -517,6 +517,7 @@ func getType(t string) uint { } func main() { + fmt.Println("Generating test suite", os.Args[1:]) out := generateTestSuite(os.Args[1]) if len(os.Args) == 3 { f, err := os.Create(os.Args[2]) diff --git a/models/protocol_tests/input/rest-json.json b/models/protocol_tests/input/rest-json.json index fe7933c24ef..73f960370f9 100644 --- a/models/protocol_tests/input/rest-json.json +++ b/models/protocol_tests/input/rest-json.json @@ -1310,17 +1310,46 @@ "shapes": { "InputShape": { "type": "structure", + "payload": "Body", "members": { - "Attr": { + "HeaderField": { "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" + "jsonvalue": true, + "location": "header", + "locationName": "X-Amz-Foo" + }, + "QueryField": { + "shape": "StringType", + "jsonvalue": true, + "location": "querystring", + "locationName": "Bar" + }, + "Body": { + "shape": "BodyStructure" } } }, "StringType": { "type": "string" + }, + "ListType": { + "type": "list", + "member": { + "shape": "StringType", + "jsonvalue": true + } + }, + "BodyStructure": { + "type": "structure", + "members": { + "BodyField": { + "shape": "StringType", + "jsonvalue": true + }, + "BodyListField": { + "shape": "ListType" + } + } } }, "cases": [ @@ -1335,12 +1364,16 @@ "name": "OperationName" }, "params": { - "Attr": {"Foo":"Bar"} + "HeaderField": {"Foo":"Bar"}, + "QueryField": {"Foo":"Bar"}, + "Body": { + "BodyField": {"Foo":"Bar"} + } }, "serialized": { - "uri": "/", + "uri": "/?Bar=%7B%22Foo%22%3A%22Bar%22%7D", "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" + "body": "{\"BodyField\":\"{\\\"Foo\\\":\\\"Bar\\\"}\"}" } }, { @@ -1353,6 +1386,27 @@ }, "name": "OperationName" }, + "params": { + "Body": { + "BodyListField": [{"Foo":"Bar"}] + } + }, + "serialized": { + "uri": "/", + "headers": {}, + "body": "{\"BodyListField\":[\"{\\\"Foo\\\":\\\"Bar\\\"}\"]}" + } + }, + { + "given": { + "input": { + "shape": "InputShape" + }, + "http": { + "method": "POST" + }, + "name": "OperationName" + }, "params": { }, "serialized": { diff --git a/models/protocol_tests/output/rest-json.json b/models/protocol_tests/output/rest-json.json index 9217fe3dd3d..dc51fe10917 100644 --- a/models/protocol_tests/output/rest-json.json +++ b/models/protocol_tests/output/rest-json.json @@ -447,26 +447,6 @@ } ] }, - { - "description": "Ignores undefined output", - "metadata": { - "protocol": "rest-json" - }, - "shapes": {}, - "cases": [ - { - "given": { - "name": "OperationName" - }, - "result": {}, - "response": { - "status_code": 200, - "headers": {}, - "body": "OK" - } - } - ] - }, { "description": "Supports header maps", "metadata": { @@ -634,16 +614,30 @@ "OutputShape": { "type": "structure", "members": { - "Attr": { + "HeaderField": { "shape": "StringType", - "jsonvalue": true, - "location": "header", - "locationName": "X-Amz-Foo" + "jsonvalue": true, + "location": "header", + "locationName": "X-Amz-Foo" + }, + "BodyField":{ + "shape": "StringType", + "jsonvalue": true + }, + "BodyListField": { + "shape": "ListType" } } }, "StringType": { "type": "string" + }, + "ListType": { + "type": "list", + "member": { + "shape": "StringType", + "jsonvalue": true + } } }, "cases": [ @@ -655,12 +649,29 @@ "name": "OperationName" }, "result": { - "Attr": {"Foo":"Bar"} + "HeaderField": {"Foo":"Bar"}, + "BodyField": {"Foo":"Bar"} }, "response": { "status_code": 200, "headers": {"X-Amz-Foo": "eyJGb28iOiJCYXIifQ=="}, - "body": "" + "body": "{\"BodyField\":\"{\\\"Foo\\\":\\\"Bar\\\"}\"}" + } + }, + { + "given": { + "output": { + "shape": "OutputShape" + }, + "name": "OperationName" + }, + "result": { + "BodyListField": [{"Foo":"Bar"}] + }, + "response": { + "status_code": 200, + "headers": {}, + "body": "{\"BodyListField\":[\"{\\\"Foo\\\":\\\"Bar\\\"}\"]}" } } ] diff --git a/private/model/api/param_filler.go b/private/model/api/param_filler.go index eb3edb9d2a5..f4fde6700a3 100644 --- a/private/model/api/param_filler.go +++ b/private/model/api/param_filler.go @@ -4,6 +4,7 @@ package api import ( "fmt" + "encoding/json" "reflect" "strings" @@ -79,6 +80,19 @@ func (f paramFiller) paramsStructAny(value interface{}, shape *Shape) string { if v.IsValid() { return fmt.Sprintf("aws.Time(time.Unix(%d, 0))", int(v.Float())) } + case "jsonvalue": + v, err := json.Marshal(value) + if err != nil { + panic("failed to marshal JSONValue, "+err.Error()) + } + const tmpl = `func() aws.JSONValue { + var m aws.JSONValue + if err := json.Unmarshal([]byte(%q), &m); err != nil { + panic("failed to unmarshal JSONValue, "+err.Error()) + } + return m + }()` + return fmt.Sprintf(tmpl, string(v)) default: panic("Unhandled type " + shape.Type) } diff --git a/private/protocol/json/jsonutil/build.go b/private/protocol/json/jsonutil/build.go index 6efe43d5f39..ec765ba257e 100644 --- a/private/protocol/json/jsonutil/build.go +++ b/private/protocol/json/jsonutil/build.go @@ -12,6 +12,7 @@ import ( "strconv" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/private/protocol" ) @@ -49,7 +50,10 @@ func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) err t = "list" } case reflect.Map: - t = "map" + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } } } @@ -210,14 +214,11 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro } buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) default: - switch value.Type() { - case timeType: - converted := v.Interface().(*time.Time) - + switch converted := value.Interface().(type) { + case time.Time: buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10)) - case byteSliceType: + case []byte: if !value.IsNil() { - converted := value.Interface().([]byte) buf.WriteByte('"') if len(converted) < 1024 { // for small buffers, using Encode directly is much faster. @@ -233,6 +234,12 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro } buf.WriteByte('"') } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) default: return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) } diff --git a/private/protocol/json/jsonutil/unmarshal.go b/private/protocol/json/jsonutil/unmarshal.go index fea53561366..037e1e7be78 100644 --- a/private/protocol/json/jsonutil/unmarshal.go +++ b/private/protocol/json/jsonutil/unmarshal.go @@ -8,6 +8,9 @@ import ( "io/ioutil" "reflect" "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/protocol" ) // UnmarshalJSON reads a stream and unmarshals the results in object v. @@ -50,7 +53,10 @@ func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) t = "list" } case reflect.Map: - t = "map" + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } } } @@ -183,6 +189,13 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa return err } value.Set(reflect.ValueOf(b)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) default: return errf() } diff --git a/private/protocol/jsonvalue.go b/private/protocol/jsonvalue.go new file mode 100644 index 00000000000..84022484077 --- /dev/null +++ b/private/protocol/jsonvalue.go @@ -0,0 +1,67 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go/aws" +) + +type EscapeMode int + +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + return string(b), nil +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + fmt.Println("JSONVAlue decode", u, v, err) + b = []byte(u) + default: + b = []byte(v) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/private/protocol/rest/build.go b/private/protocol/rest/build.go index 71618356493..90bcbf8903c 100644 --- a/private/protocol/rest/build.go +++ b/private/protocol/rest/build.go @@ -4,7 +4,6 @@ package rest import ( "bytes" "encoding/base64" - "encoding/json" "fmt" "io" "net/http" @@ -18,6 +17,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" ) // RFC822 returns an RFC822 formatted timestamp for AWS protocols @@ -252,13 +252,12 @@ func EscapePath(path string, encodeSep bool) string { return buf.String() } -func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { v = reflect.Indirect(v) if !v.IsValid() { return "", errValueNotSet } - var str string switch value := v.Interface().(type) { case string: str = value @@ -273,17 +272,19 @@ func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { case time.Time: str = value.UTC().Format(RFC822) case aws.JSONValue: - b, err := json.Marshal(value) - if err != nil { - return "", err + if len(value) == 0 { + return "", errValueNotSet } + var escaping protocol.EscapeMode if tag.Get("location") == "header" { - str = base64.StdEncoding.EncodeToString(b) - } else { - str = string(b) + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) } default: - err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) return "", err } return str, nil diff --git a/private/protocol/rest/unmarshal.go b/private/protocol/rest/unmarshal.go index 7a779ee2260..092e061d167 100644 --- a/private/protocol/rest/unmarshal.go +++ b/private/protocol/rest/unmarshal.go @@ -3,7 +3,6 @@ package rest import ( "bytes" "encoding/base64" - "encoding/json" "fmt" "io" "io/ioutil" @@ -16,6 +15,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" ) // UnmarshalHandler is a named request handler for unmarshaling rest protocol requests @@ -204,17 +204,11 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro } v.Set(reflect.ValueOf(&t)) case aws.JSONValue: - b := []byte(header) - var err error + var escaping protocol.EscapeMode if tag.Get("location") == "header" { - b, err = base64.StdEncoding.DecodeString(header) - if err != nil { - return err - } + escaping = protocol.Base64Escape } - - m := aws.JSONValue{} - err = json.Unmarshal(b, &m) + m, err := protocol.DecodeJSONValue(header, escaping) if err != nil { return err } diff --git a/private/protocol/restjson/build_test.go b/private/protocol/restjson/build_test.go index ac4e4d18e6f..100b6ded943 100644 --- a/private/protocol/restjson/build_test.go +++ b/private/protocol/restjson/build_test.go @@ -4101,7 +4101,7 @@ const opInputService21TestCaseOperation1 = "OperationName" // if err == nil { // resp is now filled // fmt.Println(resp) // } -func (c *InputService21ProtocolTest) InputService21TestCaseOperation1Request(input *InputService21TestShapeInputService21TestCaseOperation2Input) (req *request.Request, output *InputService21TestShapeInputService21TestCaseOperation1Output) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation1Request(input *InputService21TestShapeInputService21TestCaseOperation3Input) (req *request.Request, output *InputService21TestShapeInputService21TestCaseOperation1Output) { op := &request.Operation{ Name: opInputService21TestCaseOperation1, HTTPMethod: "POST", @@ -4109,7 +4109,7 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation1Request(inp } if input == nil { - input = &InputService21TestShapeInputService21TestCaseOperation2Input{} + input = &InputService21TestShapeInputService21TestCaseOperation3Input{} } output = &InputService21TestShapeInputService21TestCaseOperation1Output{} @@ -4127,7 +4127,7 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation1Request(inp // // See the AWS API reference guide for 's // API operation InputService21TestCaseOperation1 for usage and error information. -func (c *InputService21ProtocolTest) InputService21TestCaseOperation1(input *InputService21TestShapeInputService21TestCaseOperation2Input) (*InputService21TestShapeInputService21TestCaseOperation1Output, error) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation1(input *InputService21TestShapeInputService21TestCaseOperation3Input) (*InputService21TestShapeInputService21TestCaseOperation1Output, error) { req, out := c.InputService21TestCaseOperation1Request(input) return out, req.Send() } @@ -4141,7 +4141,7 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation1(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 *InputService21ProtocolTest) InputService21TestCaseOperation1WithContext(ctx aws.Context, input *InputService21TestShapeInputService21TestCaseOperation2Input, opts ...request.Option) (*InputService21TestShapeInputService21TestCaseOperation1Output, error) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation1WithContext(ctx aws.Context, input *InputService21TestShapeInputService21TestCaseOperation3Input, opts ...request.Option) (*InputService21TestShapeInputService21TestCaseOperation1Output, error) { req, out := c.InputService21TestCaseOperation1Request(input) req.SetContext(ctx) req.ApplyOptions(opts...) @@ -4172,7 +4172,7 @@ const opInputService21TestCaseOperation2 = "OperationName" // if err == nil { // resp is now filled // fmt.Println(resp) // } -func (c *InputService21ProtocolTest) InputService21TestCaseOperation2Request(input *InputService21TestShapeInputService21TestCaseOperation2Input) (req *request.Request, output *InputService21TestShapeInputService21TestCaseOperation2Output) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation2Request(input *InputService21TestShapeInputService21TestCaseOperation3Input) (req *request.Request, output *InputService21TestShapeInputService21TestCaseOperation2Output) { op := &request.Operation{ Name: opInputService21TestCaseOperation2, HTTPMethod: "POST", @@ -4180,7 +4180,7 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation2Request(inp } if input == nil { - input = &InputService21TestShapeInputService21TestCaseOperation2Input{} + input = &InputService21TestShapeInputService21TestCaseOperation3Input{} } output = &InputService21TestShapeInputService21TestCaseOperation2Output{} @@ -4198,7 +4198,7 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation2Request(inp // // See the AWS API reference guide for 's // API operation InputService21TestCaseOperation2 for usage and error information. -func (c *InputService21ProtocolTest) InputService21TestCaseOperation2(input *InputService21TestShapeInputService21TestCaseOperation2Input) (*InputService21TestShapeInputService21TestCaseOperation2Output, error) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation2(input *InputService21TestShapeInputService21TestCaseOperation3Input) (*InputService21TestShapeInputService21TestCaseOperation2Output, error) { req, out := c.InputService21TestCaseOperation2Request(input) return out, req.Send() } @@ -4212,30 +4212,141 @@ func (c *InputService21ProtocolTest) InputService21TestCaseOperation2(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 *InputService21ProtocolTest) InputService21TestCaseOperation2WithContext(ctx aws.Context, input *InputService21TestShapeInputService21TestCaseOperation2Input, opts ...request.Option) (*InputService21TestShapeInputService21TestCaseOperation2Output, error) { +func (c *InputService21ProtocolTest) InputService21TestCaseOperation2WithContext(ctx aws.Context, input *InputService21TestShapeInputService21TestCaseOperation3Input, opts ...request.Option) (*InputService21TestShapeInputService21TestCaseOperation2Output, error) { req, out := c.InputService21TestCaseOperation2Request(input) req.SetContext(ctx) req.ApplyOptions(opts...) return out, req.Send() } +const opInputService21TestCaseOperation3 = "OperationName" + +// InputService21TestCaseOperation3Request generates a "aws/request.Request" representing the +// client's request for the InputService21TestCaseOperation3 operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// 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 InputService21TestCaseOperation3 for more information on using the InputService21TestCaseOperation3 +// 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 InputService21TestCaseOperation3Request method. +// req, resp := client.InputService21TestCaseOperation3Request(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +func (c *InputService21ProtocolTest) InputService21TestCaseOperation3Request(input *InputService21TestShapeInputService21TestCaseOperation3Input) (req *request.Request, output *InputService21TestShapeInputService21TestCaseOperation3Output) { + op := &request.Operation{ + Name: opInputService21TestCaseOperation3, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &InputService21TestShapeInputService21TestCaseOperation3Input{} + } + + output = &InputService21TestShapeInputService21TestCaseOperation3Output{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(restjson.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + return +} + +// InputService21TestCaseOperation3 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 InputService21TestCaseOperation3 for usage and error information. +func (c *InputService21ProtocolTest) InputService21TestCaseOperation3(input *InputService21TestShapeInputService21TestCaseOperation3Input) (*InputService21TestShapeInputService21TestCaseOperation3Output, error) { + req, out := c.InputService21TestCaseOperation3Request(input) + return out, req.Send() +} + +// InputService21TestCaseOperation3WithContext is the same as InputService21TestCaseOperation3 with the addition of +// the ability to pass a context and additional request options. +// +// See InputService21TestCaseOperation3 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 *InputService21ProtocolTest) InputService21TestCaseOperation3WithContext(ctx aws.Context, input *InputService21TestShapeInputService21TestCaseOperation3Input, opts ...request.Option) (*InputService21TestShapeInputService21TestCaseOperation3Output, error) { + req, out := c.InputService21TestCaseOperation3Request(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +type InputService21TestShapeBodyStructure struct { + _ struct{} `type:"structure"` + + BodyField aws.JSONValue `type:"jsonvalue"` + + BodyListField []aws.JSONValue `type:"list"` +} + +// SetBodyField sets the BodyField field's value. +func (s *InputService21TestShapeBodyStructure) SetBodyField(v aws.JSONValue) *InputService21TestShapeBodyStructure { + s.BodyField = v + return s +} + +// SetBodyListField sets the BodyListField field's value. +func (s *InputService21TestShapeBodyStructure) SetBodyListField(v []aws.JSONValue) *InputService21TestShapeBodyStructure { + s.BodyListField = v + return s +} + type InputService21TestShapeInputService21TestCaseOperation1Output struct { _ struct{} `type:"structure"` } -type InputService21TestShapeInputService21TestCaseOperation2Input struct { +type InputService21TestShapeInputService21TestCaseOperation2Output struct { _ struct{} `type:"structure"` +} + +type InputService21TestShapeInputService21TestCaseOperation3Input struct { + _ struct{} `type:"structure" payload:"Body"` + + Body *InputService21TestShapeBodyStructure `type:"structure"` + + HeaderField aws.JSONValue `location:"header" locationName:"X-Amz-Foo" type:"jsonvalue"` + + QueryField aws.JSONValue `location:"querystring" locationName:"Bar" type:"jsonvalue"` +} - Attr aws.JSONValue `location:"header" locationName:"X-Amz-Foo" type:"jsonvalue"` +// SetBody sets the Body field's value. +func (s *InputService21TestShapeInputService21TestCaseOperation3Input) SetBody(v *InputService21TestShapeBodyStructure) *InputService21TestShapeInputService21TestCaseOperation3Input { + s.Body = v + return s } -// SetAttr sets the Attr field's value. -func (s *InputService21TestShapeInputService21TestCaseOperation2Input) SetAttr(v aws.JSONValue) *InputService21TestShapeInputService21TestCaseOperation2Input { - s.Attr = v +// SetHeaderField sets the HeaderField field's value. +func (s *InputService21TestShapeInputService21TestCaseOperation3Input) SetHeaderField(v aws.JSONValue) *InputService21TestShapeInputService21TestCaseOperation3Input { + s.HeaderField = v return s } -type InputService21TestShapeInputService21TestCaseOperation2Output struct { +// SetQueryField sets the QueryField field's value. +func (s *InputService21TestShapeInputService21TestCaseOperation3Input) SetQueryField(v aws.JSONValue) *InputService21TestShapeInputService21TestCaseOperation3Input { + s.QueryField = v + return s +} + +type InputService21TestShapeInputService21TestCaseOperation3Output struct { _ struct{} `type:"structure"` } @@ -5099,8 +5210,19 @@ func TestInputService20ProtocolTestIdempotencyTokenAutoFillCase2(t *testing.T) { func TestInputService21ProtocolTestJSONValueTraitCase1(t *testing.T) { svc := NewInputService21ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) - input := &InputService21TestShapeInputService21TestCaseOperation2Input{} - input.Attr = aws.JSONValue{"Foo": "Bar"} + input := &InputService21TestShapeInputService21TestCaseOperation3Input{ + Body: &InputService21TestShapeBodyStructure{ + BodyField: func() aws.JSONValue { + var m aws.JSONValue + if err := json.Unmarshal([]byte("{\"Foo\":\"Bar\"}"), &m); err != nil { + panic("failed to unmarshal JSONValue, " + err.Error()) + } + return m + }(), + }, + } + input.HeaderField = aws.JSONValue{"Foo": "Bar"} + input.QueryField = aws.JSONValue{"Foo": "Bar"} req, _ := svc.InputService21TestCaseOperation1Request(input) r := req.HTTPRequest @@ -5110,8 +5232,15 @@ func TestInputService21ProtocolTestJSONValueTraitCase1(t *testing.T) { 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.AssertJSON(t, `{"BodyField":"{\"Foo\":\"Bar\"}"}`, util.Trim(string(body))) + // assert URL - awstesting.AssertURL(t, "https://test/", r.URL.String()) + awstesting.AssertURL(t, "https://test/?Bar=%7B%22Foo%22%3A%22Bar%22%7D", r.URL.String()) // assert headers if e, a := "eyJGb28iOiJCYXIifQ==", r.Header.Get("X-Amz-Foo"); e != a { @@ -5122,7 +5251,19 @@ func TestInputService21ProtocolTestJSONValueTraitCase1(t *testing.T) { func TestInputService21ProtocolTestJSONValueTraitCase2(t *testing.T) { svc := NewInputService21ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) - input := &InputService21TestShapeInputService21TestCaseOperation2Input{} + input := &InputService21TestShapeInputService21TestCaseOperation3Input{ + Body: &InputService21TestShapeBodyStructure{ + BodyListField: []aws.JSONValue{ + func() aws.JSONValue { + var m aws.JSONValue + if err := json.Unmarshal([]byte("{\"Foo\":\"Bar\"}"), &m); err != nil { + panic("failed to unmarshal JSONValue, " + err.Error()) + } + return m + }(), + }, + }, + } req, _ := svc.InputService21TestCaseOperation2Request(input) r := req.HTTPRequest @@ -5132,6 +5273,32 @@ func TestInputService21ProtocolTestJSONValueTraitCase2(t *testing.T) { 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.AssertJSON(t, `{"BodyListField":["{\"Foo\":\"Bar\"}"]}`, util.Trim(string(body))) + + // assert URL + awstesting.AssertURL(t, "https://test/", r.URL.String()) + + // assert headers + +} + +func TestInputService21ProtocolTestJSONValueTraitCase3(t *testing.T) { + svc := NewInputService21ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) + input := &InputService21TestShapeInputService21TestCaseOperation3Input{} + req, _ := svc.InputService21TestCaseOperation3Request(input) + r := req.HTTPRequest + + // build request + restjson.Build(req) + if req.Error != nil { + t.Errorf("expect no error, got %v", req.Error) + } + // assert URL awstesting.AssertURL(t, "https://test/", r.URL.String()) diff --git a/private/protocol/restjson/unmarshal_test.go b/private/protocol/restjson/unmarshal_test.go index 38fccb911f1..1255ec87d7e 100644 --- a/private/protocol/restjson/unmarshal_test.go +++ b/private/protocol/restjson/unmarshal_test.go @@ -1417,8 +1417,6 @@ func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1Request(inp output = &OutputService9TestShapeOutputService9TestCaseOperation1Output{} req = c.newRequest(op, input, output) - req.Handlers.Unmarshal.Remove(restjson.UnmarshalHandler) - req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) return } @@ -1457,6 +1455,22 @@ type OutputService9TestShapeOutputService9TestCaseOperation1Input struct { type OutputService9TestShapeOutputService9TestCaseOperation1Output struct { _ struct{} `type:"structure"` + + AllHeaders map[string]*string `location:"headers" type:"map"` + + PrefixedHeaders map[string]*string `location:"headers" locationName:"X-" type:"map"` +} + +// SetAllHeaders sets the AllHeaders field's value. +func (s *OutputService9TestShapeOutputService9TestCaseOperation1Output) SetAllHeaders(v map[string]*string) *OutputService9TestShapeOutputService9TestCaseOperation1Output { + s.AllHeaders = v + return s +} + +// SetPrefixedHeaders sets the PrefixedHeaders field's value. +func (s *OutputService9TestShapeOutputService9TestCaseOperation1Output) SetPrefixedHeaders(v map[string]*string) *OutputService9TestShapeOutputService9TestCaseOperation1Output { + s.PrefixedHeaders = v + return s } // OutputService10ProtocolTest provides the API operation methods for making requests to @@ -1586,27 +1600,39 @@ func (c *OutputService10ProtocolTest) OutputService10TestCaseOperation1WithConte return out, req.Send() } +type OutputService10TestShapeBodyStructure struct { + _ struct{} `type:"structure"` + + Foo *string `type:"string"` +} + +// SetFoo sets the Foo field's value. +func (s *OutputService10TestShapeBodyStructure) SetFoo(v string) *OutputService10TestShapeBodyStructure { + s.Foo = &v + return s +} + type OutputService10TestShapeOutputService10TestCaseOperation1Input struct { _ struct{} `type:"structure"` } type OutputService10TestShapeOutputService10TestCaseOperation1Output struct { - _ struct{} `type:"structure"` + _ struct{} `type:"structure" payload:"Data"` - AllHeaders map[string]*string `location:"headers" type:"map"` + Data *OutputService10TestShapeBodyStructure `type:"structure"` - PrefixedHeaders map[string]*string `location:"headers" locationName:"X-" type:"map"` + Header *string `location:"header" locationName:"X-Foo" type:"string"` } -// SetAllHeaders sets the AllHeaders field's value. -func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetAllHeaders(v map[string]*string) *OutputService10TestShapeOutputService10TestCaseOperation1Output { - s.AllHeaders = v +// SetData sets the Data field's value. +func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetData(v *OutputService10TestShapeBodyStructure) *OutputService10TestShapeOutputService10TestCaseOperation1Output { + s.Data = v return s } -// SetPrefixedHeaders sets the PrefixedHeaders field's value. -func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetPrefixedHeaders(v map[string]*string) *OutputService10TestShapeOutputService10TestCaseOperation1Output { - s.PrefixedHeaders = v +// SetHeader sets the Header field's value. +func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetHeader(v string) *OutputService10TestShapeOutputService10TestCaseOperation1Output { + s.Header = &v return s } @@ -1737,39 +1763,19 @@ func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1WithConte return out, req.Send() } -type OutputService11TestShapeBodyStructure struct { - _ struct{} `type:"structure"` - - Foo *string `type:"string"` -} - -// SetFoo sets the Foo field's value. -func (s *OutputService11TestShapeBodyStructure) SetFoo(v string) *OutputService11TestShapeBodyStructure { - s.Foo = &v - return s -} - type OutputService11TestShapeOutputService11TestCaseOperation1Input struct { _ struct{} `type:"structure"` } type OutputService11TestShapeOutputService11TestCaseOperation1Output struct { - _ struct{} `type:"structure" payload:"Data"` - - Data *OutputService11TestShapeBodyStructure `type:"structure"` - - Header *string `location:"header" locationName:"X-Foo" type:"string"` -} + _ struct{} `type:"structure" payload:"Stream"` -// SetData sets the Data field's value. -func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetData(v *OutputService11TestShapeBodyStructure) *OutputService11TestShapeOutputService11TestCaseOperation1Output { - s.Data = v - return s + Stream []byte `type:"blob"` } -// SetHeader sets the Header field's value. -func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetHeader(v string) *OutputService11TestShapeOutputService11TestCaseOperation1Output { - s.Header = &v +// SetStream sets the Stream field's value. +func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetStream(v []byte) *OutputService11TestShapeOutputService11TestCaseOperation1Output { + s.Stream = v return s } @@ -1856,7 +1862,7 @@ const opOutputService12TestCaseOperation1 = "OperationName" // if err == nil { // resp is now filled // fmt.Println(resp) // } -func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (req *request.Request, output *OutputService12TestShapeOutputService12TestCaseOperation1Output) { +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (req *request.Request, output *OutputService12TestShapeOutputService12TestCaseOperation2Output) { op := &request.Operation{ Name: opOutputService12TestCaseOperation1, HTTPPath: "/", @@ -1866,7 +1872,7 @@ func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(i input = &OutputService12TestShapeOutputService12TestCaseOperation1Input{} } - output = &OutputService12TestShapeOutputService12TestCaseOperation1Output{} + output = &OutputService12TestShapeOutputService12TestCaseOperation2Output{} req = c.newRequest(op, input, output) return } @@ -1879,7 +1885,7 @@ func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(i // // See the AWS API reference guide for 's // API operation OutputService12TestCaseOperation1 for usage and error information. -func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (*OutputService12TestShapeOutputService12TestCaseOperation1Output, error) { +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (*OutputService12TestShapeOutputService12TestCaseOperation2Output, error) { req, out := c.OutputService12TestCaseOperation1Request(input) return out, req.Send() } @@ -1893,169 +1899,114 @@ func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1(input *O // 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 *OutputService12ProtocolTest) OutputService12TestCaseOperation1WithContext(ctx aws.Context, input *OutputService12TestShapeOutputService12TestCaseOperation1Input, opts ...request.Option) (*OutputService12TestShapeOutputService12TestCaseOperation1Output, error) { +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1WithContext(ctx aws.Context, input *OutputService12TestShapeOutputService12TestCaseOperation1Input, opts ...request.Option) (*OutputService12TestShapeOutputService12TestCaseOperation2Output, error) { req, out := c.OutputService12TestCaseOperation1Request(input) req.SetContext(ctx) req.ApplyOptions(opts...) return out, req.Send() } -type OutputService12TestShapeOutputService12TestCaseOperation1Input struct { - _ struct{} `type:"structure"` -} - -type OutputService12TestShapeOutputService12TestCaseOperation1Output struct { - _ struct{} `type:"structure" payload:"Stream"` - - Stream []byte `type:"blob"` -} - -// SetStream sets the Stream field's value. -func (s *OutputService12TestShapeOutputService12TestCaseOperation1Output) SetStream(v []byte) *OutputService12TestShapeOutputService12TestCaseOperation1Output { - s.Stream = v - return s -} - -// OutputService13ProtocolTest provides the API operation methods for making requests to -// . See this package's package overview docs -// for details on the service. -// -// OutputService13ProtocolTest methods are safe to use concurrently. It is not safe to -// modify mutate any of the struct's properties though. -type OutputService13ProtocolTest struct { - *client.Client -} - -// New creates a new instance of the OutputService13ProtocolTest 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 OutputService13ProtocolTest client from just a session. -// svc := outputservice13protocoltest.New(mySession) -// -// // Create a OutputService13ProtocolTest client with additional configuration -// svc := outputservice13protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2")) -func NewOutputService13ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService13ProtocolTest { - c := p.ClientConfig("outputservice13protocoltest", cfgs...) - return newOutputService13ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) -} - -// newClient creates, initializes and returns a new service client instance. -func newOutputService13ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *OutputService13ProtocolTest { - svc := &OutputService13ProtocolTest{ - Client: client.New( - cfg, - metadata.ClientInfo{ - ServiceName: "outputservice13protocoltest", - SigningName: signingName, - SigningRegion: signingRegion, - Endpoint: endpoint, - APIVersion: "", - }, - 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) - - return svc -} - -// newRequest creates a new request for a OutputService13ProtocolTest operation and runs any -// custom request initialization. -func (c *OutputService13ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { - req := c.NewRequest(op, params, data) - - return req -} - -const opOutputService13TestCaseOperation1 = "OperationName" +const opOutputService12TestCaseOperation2 = "OperationName" -// OutputService13TestCaseOperation1Request generates a "aws/request.Request" representing the -// client's request for the OutputService13TestCaseOperation1 operation. The "output" return +// OutputService12TestCaseOperation2Request generates a "aws/request.Request" representing the +// client's request for the OutputService12TestCaseOperation2 operation. The "output" return // value will be populated with the request's response once the request complets // successfuly. // // 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 OutputService13TestCaseOperation1 for more information on using the OutputService13TestCaseOperation1 +// See OutputService12TestCaseOperation2 for more information on using the OutputService12TestCaseOperation2 // 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 OutputService13TestCaseOperation1Request method. -// req, resp := client.OutputService13TestCaseOperation1Request(params) +// // Example sending a request using the OutputService12TestCaseOperation2Request method. +// req, resp := client.OutputService12TestCaseOperation2Request(params) // // err := req.Send() // if err == nil { // resp is now filled // fmt.Println(resp) // } -func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1Request(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (req *request.Request, output *OutputService13TestShapeOutputService13TestCaseOperation1Output) { +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation2Request(input *OutputService12TestShapeOutputService12TestCaseOperation2Input) (req *request.Request, output *OutputService12TestShapeOutputService12TestCaseOperation2Output) { op := &request.Operation{ - Name: opOutputService13TestCaseOperation1, + Name: opOutputService12TestCaseOperation2, HTTPPath: "/", } if input == nil { - input = &OutputService13TestShapeOutputService13TestCaseOperation1Input{} + input = &OutputService12TestShapeOutputService12TestCaseOperation2Input{} } - output = &OutputService13TestShapeOutputService13TestCaseOperation1Output{} + output = &OutputService12TestShapeOutputService12TestCaseOperation2Output{} req = c.newRequest(op, input, output) return } -// OutputService13TestCaseOperation1 API operation for . +// OutputService12TestCaseOperation2 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 OutputService13TestCaseOperation1 for usage and error information. -func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (*OutputService13TestShapeOutputService13TestCaseOperation1Output, error) { - req, out := c.OutputService13TestCaseOperation1Request(input) +// API operation OutputService12TestCaseOperation2 for usage and error information. +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation2(input *OutputService12TestShapeOutputService12TestCaseOperation2Input) (*OutputService12TestShapeOutputService12TestCaseOperation2Output, error) { + req, out := c.OutputService12TestCaseOperation2Request(input) return out, req.Send() } -// OutputService13TestCaseOperation1WithContext is the same as OutputService13TestCaseOperation1 with the addition of +// OutputService12TestCaseOperation2WithContext is the same as OutputService12TestCaseOperation2 with the addition of // the ability to pass a context and additional request options. // -// See OutputService13TestCaseOperation1 for details on how to use this API operation. +// See OutputService12TestCaseOperation2 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 *OutputService13ProtocolTest) OutputService13TestCaseOperation1WithContext(ctx aws.Context, input *OutputService13TestShapeOutputService13TestCaseOperation1Input, opts ...request.Option) (*OutputService13TestShapeOutputService13TestCaseOperation1Output, error) { - req, out := c.OutputService13TestCaseOperation1Request(input) +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation2WithContext(ctx aws.Context, input *OutputService12TestShapeOutputService12TestCaseOperation2Input, opts ...request.Option) (*OutputService12TestShapeOutputService12TestCaseOperation2Output, error) { + req, out := c.OutputService12TestCaseOperation2Request(input) req.SetContext(ctx) req.ApplyOptions(opts...) return out, req.Send() } -type OutputService13TestShapeOutputService13TestCaseOperation1Input struct { +type OutputService12TestShapeOutputService12TestCaseOperation1Input struct { + _ struct{} `type:"structure"` +} + +type OutputService12TestShapeOutputService12TestCaseOperation2Input struct { _ struct{} `type:"structure"` } -type OutputService13TestShapeOutputService13TestCaseOperation1Output struct { +type OutputService12TestShapeOutputService12TestCaseOperation2Output struct { _ struct{} `type:"structure"` - Attr aws.JSONValue `location:"header" locationName:"X-Amz-Foo" type:"jsonvalue"` + BodyField aws.JSONValue `type:"jsonvalue"` + + BodyListField []aws.JSONValue `type:"list"` + + HeaderField aws.JSONValue `location:"header" locationName:"X-Amz-Foo" type:"jsonvalue"` +} + +// SetBodyField sets the BodyField field's value. +func (s *OutputService12TestShapeOutputService12TestCaseOperation2Output) SetBodyField(v aws.JSONValue) *OutputService12TestShapeOutputService12TestCaseOperation2Output { + s.BodyField = v + return s } -// SetAttr sets the Attr field's value. -func (s *OutputService13TestShapeOutputService13TestCaseOperation1Output) SetAttr(v aws.JSONValue) *OutputService13TestShapeOutputService13TestCaseOperation1Output { - s.Attr = v +// SetBodyListField sets the BodyListField field's value. +func (s *OutputService12TestShapeOutputService12TestCaseOperation2Output) SetBodyListField(v []aws.JSONValue) *OutputService12TestShapeOutputService12TestCaseOperation2Output { + s.BodyListField = v + return s +} + +// SetHeaderField sets the HeaderField field's value. +func (s *OutputService12TestShapeOutputService12TestCaseOperation2Output) SetHeaderField(v aws.JSONValue) *OutputService12TestShapeOutputService12TestCaseOperation2Output { + s.HeaderField = v return s } @@ -2324,34 +2275,11 @@ func TestOutputService8ProtocolTestIgnoresExtraDataCase1(t *testing.T) { } -func TestOutputService9ProtocolTestIgnoresUndefinedOutputCase1(t *testing.T) { +func TestOutputService9ProtocolTestSupportsHeaderMapsCase1(t *testing.T) { svc := NewOutputService9ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) - buf := bytes.NewReader([]byte("OK")) - req, out := svc.OutputService9TestCaseOperation1Request(nil) - req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} - - // set headers - - // unmarshal response - restjson.UnmarshalMeta(req) - restjson.Unmarshal(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") - } - -} - -func TestOutputService10ProtocolTestSupportsHeaderMapsCase1(t *testing.T) { - svc := NewOutputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) - buf := bytes.NewReader([]byte("{}")) - req, out := svc.OutputService10TestCaseOperation1Request(nil) + req, out := svc.OutputService9TestCaseOperation1Request(nil) req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} // set headers @@ -2388,11 +2316,11 @@ func TestOutputService10ProtocolTestSupportsHeaderMapsCase1(t *testing.T) { } -func TestOutputService11ProtocolTestJSONPayloadCase1(t *testing.T) { - svc := NewOutputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) +func TestOutputService10ProtocolTestJSONPayloadCase1(t *testing.T) { + svc := NewOutputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) buf := bytes.NewReader([]byte("{\"Foo\": \"abc\"}")) - req, out := svc.OutputService11TestCaseOperation1Request(nil) + req, out := svc.OutputService10TestCaseOperation1Request(nil) req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} // set headers @@ -2418,11 +2346,11 @@ func TestOutputService11ProtocolTestJSONPayloadCase1(t *testing.T) { } -func TestOutputService12ProtocolTestStreamingPayloadCase1(t *testing.T) { - svc := NewOutputService12ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) +func TestOutputService11ProtocolTestStreamingPayloadCase1(t *testing.T) { + svc := NewOutputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) buf := bytes.NewReader([]byte("abc")) - req, out := svc.OutputService12TestCaseOperation1Request(nil) + req, out := svc.OutputService11TestCaseOperation1Request(nil) req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} // set headers @@ -2444,11 +2372,11 @@ func TestOutputService12ProtocolTestStreamingPayloadCase1(t *testing.T) { } -func TestOutputService13ProtocolTestJSONValueTraitCase1(t *testing.T) { - svc := NewOutputService13ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) +func TestOutputService12ProtocolTestJSONValueTraitCase1(t *testing.T) { + svc := NewOutputService12ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) - buf := bytes.NewReader([]byte("")) - req, out := svc.OutputService13TestCaseOperation1Request(nil) + buf := bytes.NewReader([]byte("{\"BodyField\":\"{\\\"Foo\\\":\\\"Bar\\\"}\"}")) + req, out := svc.OutputService12TestCaseOperation1Request(nil) req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} // set headers @@ -2465,5 +2393,31 @@ func TestOutputService13ProtocolTestJSONValueTraitCase1(t *testing.T) { if out == nil { t.Errorf("expect not to be nil") } - reflect.DeepEqual(out.Attr, map[string]interface{}{"Foo": "Bar"}) + reflect.DeepEqual(out.BodyField, map[string]interface{}{"Foo": "Bar"}) + reflect.DeepEqual(out.HeaderField, map[string]interface{}{"Foo": "Bar"}) + +} + +func TestOutputService12ProtocolTestJSONValueTraitCase2(t *testing.T) { + svc := NewOutputService12ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")}) + + buf := bytes.NewReader([]byte("{\"BodyListField\":[\"{\\\"Foo\\\":\\\"Bar\\\"}\"]}")) + req, out := svc.OutputService12TestCaseOperation2Request(nil) + req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}} + + // set headers + + // unmarshal response + restjson.UnmarshalMeta(req) + restjson.Unmarshal(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") + } + reflect.DeepEqual(out.BodyListField[0], map[string]interface{}{"Foo": "Bar"}) + }