Skip to content

Commit

Permalink
fix(parser): Unmarshalling of resources with polymorphic properties (…
Browse files Browse the repository at this point in the history
…like S3 events) now works (awslabs#188)
  • Loading branch information
Graham Jenson authored and PaulMaddox committed Mar 19, 2019
1 parent 8b332a4 commit 8eff90a
Show file tree
Hide file tree
Showing 21 changed files with 46 additions and 1,555 deletions.
Expand Up @@ -7,9 +7,9 @@ import "github.com/awslabs/goformation/cloudformation/policies"
type AWSServerlessFunction_DynamoDBEvent struct {

// BatchSize AWS CloudFormation Property
// Required: true
// Required: false
// See: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#dynamodb
BatchSize int `json:"BatchSize"`
BatchSize int `json:"BatchSize,omitempty"`

// StartingPosition AWS CloudFormation Property
// Required: true
Expand Down
5 changes: 2 additions & 3 deletions cloudformation/resources/awsserverlessapi_definitionuri.go
Expand Up @@ -4,8 +4,6 @@ import (
"sort"

"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessApi_DefinitionUri is a helper struct that can hold either a String or S3Location value
Expand Down Expand Up @@ -55,8 +53,9 @@ func (r *AWSServerlessApi_DefinitionUri) UnmarshalJSON(b []byte) error {
r.String = &val

case map[string]interface{}:
val = val // This ensures val is used to stop an error

mapstructure.Decode(val, &r.S3Location)
json.Unmarshal(b, &r.S3Location)

case []interface{}:

Expand Down
5 changes: 2 additions & 3 deletions cloudformation/resources/awsserverlessapplication_location.go
Expand Up @@ -4,8 +4,6 @@ import (
"sort"

"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessApplication_Location is a helper struct that can hold either a String or ApplicationLocation value
Expand Down Expand Up @@ -55,8 +53,9 @@ func (r *AWSServerlessApplication_Location) UnmarshalJSON(b []byte) error {
r.String = &val

case map[string]interface{}:
val = val // This ensures val is used to stop an error

mapstructure.Decode(val, &r.ApplicationLocation)
json.Unmarshal(b, &r.ApplicationLocation)

case []interface{}:

Expand Down
5 changes: 2 additions & 3 deletions cloudformation/resources/awsserverlessfunction_codeuri.go
Expand Up @@ -4,8 +4,6 @@ import (
"sort"

"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessFunction_CodeUri is a helper struct that can hold either a String or S3Location value
Expand Down Expand Up @@ -55,8 +53,9 @@ func (r *AWSServerlessFunction_CodeUri) UnmarshalJSON(b []byte) error {
r.String = &val

case map[string]interface{}:
val = val // This ensures val is used to stop an error

mapstructure.Decode(val, &r.S3Location)
json.Unmarshal(b, &r.S3Location)

case []interface{}:

Expand Down
5 changes: 2 additions & 3 deletions cloudformation/resources/awsserverlessfunction_events.go
Expand Up @@ -2,8 +2,6 @@ package resources

import (
"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessFunction_Events is a helper struct that can hold either a String or String value
Expand Down Expand Up @@ -49,10 +47,11 @@ func (r *AWSServerlessFunction_Events) UnmarshalJSON(b []byte) error {
r.StringArray = &val

case map[string]interface{}:
val = val // This ensures val is used to stop an error

case []interface{}:

mapstructure.Decode(val, &r.StringArray)
json.Unmarshal(b, &r.StringArray)

}

Expand Down
9 changes: 4 additions & 5 deletions cloudformation/resources/awsserverlessfunction_policies.go
Expand Up @@ -4,8 +4,6 @@ import (
"sort"

"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessFunction_Policies is a helper struct that can hold either a String, String, IAMPolicyDocument, or IAMPolicyDocument value
Expand Down Expand Up @@ -70,14 +68,15 @@ func (r *AWSServerlessFunction_Policies) UnmarshalJSON(b []byte) error {
r.StringArray = &val

case map[string]interface{}:
val = val // This ensures val is used to stop an error

mapstructure.Decode(val, &r.IAMPolicyDocument)
json.Unmarshal(b, &r.IAMPolicyDocument)

case []interface{}:

mapstructure.Decode(val, &r.StringArray)
json.Unmarshal(b, &r.StringArray)

mapstructure.Decode(val, &r.IAMPolicyDocumentArray)
json.Unmarshal(b, &r.IAMPolicyDocumentArray)

}

Expand Down
23 changes: 11 additions & 12 deletions cloudformation/resources/awsserverlessfunction_properties.go
Expand Up @@ -4,8 +4,6 @@ import (
"sort"

"encoding/json"

"github.com/mitchellh/mapstructure"
)

// AWSServerlessFunction_Properties is a helper struct that can hold either a S3Event, SNSEvent, SQSEvent, KinesisEvent, DynamoDBEvent, ApiEvent, ScheduleEvent, CloudWatchEventEvent, IoTRuleEvent, or AlexaSkillEvent value
Expand Down Expand Up @@ -91,26 +89,27 @@ func (r *AWSServerlessFunction_Properties) UnmarshalJSON(b []byte) error {
switch val := typecheck.(type) {

case map[string]interface{}:
val = val // This ensures val is used to stop an error

mapstructure.Decode(val, &r.S3Event)
json.Unmarshal(b, &r.S3Event)

mapstructure.Decode(val, &r.SNSEvent)
json.Unmarshal(b, &r.SNSEvent)

mapstructure.Decode(val, &r.SQSEvent)
json.Unmarshal(b, &r.SQSEvent)

mapstructure.Decode(val, &r.KinesisEvent)
json.Unmarshal(b, &r.KinesisEvent)

mapstructure.Decode(val, &r.DynamoDBEvent)
json.Unmarshal(b, &r.DynamoDBEvent)

mapstructure.Decode(val, &r.ApiEvent)
json.Unmarshal(b, &r.ApiEvent)

mapstructure.Decode(val, &r.ScheduleEvent)
json.Unmarshal(b, &r.ScheduleEvent)

mapstructure.Decode(val, &r.CloudWatchEventEvent)
json.Unmarshal(b, &r.CloudWatchEventEvent)

mapstructure.Decode(val, &r.IoTRuleEvent)
json.Unmarshal(b, &r.IoTRuleEvent)

mapstructure.Decode(val, &r.AlexaSkillEvent)
json.Unmarshal(b, &r.AlexaSkillEvent)

case []interface{}:

Expand Down
16 changes: 16 additions & 0 deletions generate/property_test.go
Expand Up @@ -68,6 +68,22 @@ var _ = Describe("Goformation Code Generator", func() {

})

Context("properly marshals and unmarshals polymorphic values", func() {

property := []byte(`{"Properties":{"Bucket":"asd","Events":"LATEST"},"Type":"S3"}`)

result := &resources.AWSServerlessFunction_EventSource{}
err := json.Unmarshal(property, result)
output, err2 := json.Marshal(result)

It("should marshal and unmarhal to same value", func() {
Expect(err).To(BeNil())
Expect(err2).To(BeNil())
Expect(output).To(Equal(property))
})

})

Context("properly Marshals best value", func() {
expected := []byte(`{"BatchSize":10,"Stream":"arn"}`)

Expand Down
2 changes: 1 addition & 1 deletion generate/sam-2016-10-31.json
Expand Up @@ -506,7 +506,7 @@
},
"BatchSize": {
"Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#dynamodb",
"Required": true,
"Required": false,
"PrimitiveType": "Integer",
"UpdateType": "Immutable"
}
Expand Down
10 changes: 4 additions & 6 deletions generate/templates/polymorphic-property.template
Expand Up @@ -5,9 +5,6 @@ import (
"sort"
{{end}}
"encoding/json"
{{ if (or .Property.Types .Property.ItemTypes .Property.PrimitiveItemTypes)}}
"github.com/mitchellh/mapstructure"
{{end}}
)

// {{.Name}} is a helper struct that can hold either a {{.TypesJoined}} value
Expand Down Expand Up @@ -88,16 +85,17 @@ func (r *{{.Name}}) UnmarshalJSON(b []byte) error {
{{end}}

case map[string]interface{}:
val = val // This ensures val is used to stop an error
{{range $type := $.Property.Types}}
mapstructure.Decode(val, &r.{{$type}})
json.Unmarshal(b, &r.{{$type}})
{{end}}

case []interface{}:
{{range $type := $.Property.PrimitiveItemTypes}}
mapstructure.Decode(val, &r.{{$type}}Array)
json.Unmarshal(b, &r.{{$type}}Array)
{{end}}
{{range $type := $.Property.ItemTypes}}
mapstructure.Decode(val, &r.{{$type}}Array)
json.Unmarshal(b, &r.{{$type}}Array)
{{end}}

}
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Expand Up @@ -9,8 +9,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mitchellh/mapstructure v1.1.0 h1:PoCJ/Ct9du6caE+91v8ov4CLjO4XEBgkPk/dF1v43eo=
github.com/mitchellh/mapstructure v1.1.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/onsi/ginkgo v1.5.0 h1:uZr+v/TFDdYkdA+j02sPO1kA5owrfjBGCJAogfIyThE=
Expand Down
1 change: 0 additions & 1 deletion schema/sam.go
Expand Up @@ -40274,7 +40274,6 @@ var SamSchema = `{
}
},
"required": [
"BatchSize",
"StartingPosition",
"Stream"
],
Expand Down
1 change: 0 additions & 1 deletion schema/sam.schema.json
Expand Up @@ -40271,7 +40271,6 @@
}
},
"required": [
"BatchSize",
"StartingPosition",
"Stream"
],
Expand Down
8 changes: 0 additions & 8 deletions vendor/github.com/mitchellh/mapstructure/.travis.yml

This file was deleted.

21 changes: 0 additions & 21 deletions vendor/github.com/mitchellh/mapstructure/CHANGELOG.md

This file was deleted.

21 changes: 0 additions & 21 deletions vendor/github.com/mitchellh/mapstructure/LICENSE

This file was deleted.

46 changes: 0 additions & 46 deletions vendor/github.com/mitchellh/mapstructure/README.md

This file was deleted.

0 comments on commit 8eff90a

Please sign in to comment.