Skip to content

Commit

Permalink
Clarify various aspects of xmlNamespace traits
Browse files Browse the repository at this point in the history
* The xmlNamespace trait can only be applied to simple types, list,
  map, set, structure, union, member, and service shapes. We previously
  allowed "*", but that includes resource and operation shapes where
  the trait isn't actually used.
* aws.protocols#awsQuery and aws.protocols#ec2Query protocol traits
  both now require that an xmlNamespace is set on the top-level
  service shape they are applied to so that the namespace is
  guaranteed to be known.
* Added various examples for how the xmlNamespace trait interacts
  with flattened lists and maps.
* Add a protocol test suite named "restXmlWithNamespace" to test that
  implementations add an xmlns to restXml services when necessary,
  closing #616
  • Loading branch information
mtdowling committed Nov 28, 2020
1 parent 705efff commit 930ac23
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 8 deletions.
4 changes: 3 additions & 1 deletion docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ Summary
OR in a ``x-form-url-encoded`` body and responses in XML documents. This
protocol is an Amazon EC2-specific extension of the ``awsQuery`` protocol.
Trait selector
``service``
``service [trait|xmlNamespace]``

*Service shapes with the xmlNamespace trait*
Value type
Annotation trait.

Expand Down
4 changes: 3 additions & 1 deletion docs/source/1.0/spec/aws/aws-query-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Summary
Adds support for an HTTP protocol that sends requests in the query
string and responses in XML documents.
Trait selector
``service``
``service [trait|xmlNamespace]``

*Service shapes with the xmlNamespace trait*
Value type
Annotation trait.
See
Expand Down
4 changes: 3 additions & 1 deletion docs/source/1.0/spec/core/xml-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,9 @@ The XML serialization is:
Summary
Adds an `XML namespace`_ to an XML element.
Trait selector
``*``
``:is(service, member, simpleType, collection, map, structure, union)``

*Service, simple types, list, map, set, structure, or union*
Value type
``structure``
Conflicts with
Expand Down
1 change: 1 addition & 0 deletions smithy-aws-protocol-tests/model/awsQuery/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ service AwsQuery {
XmlMapsXmlName,
FlattenedXmlMap,
FlattenedXmlMapWithXmlName,
FlattenedXmlMapWithXmlNamespace,
XmlEmptyMaps,

// Output XML list tests
Expand Down
28 changes: 28 additions & 0 deletions smithy-aws-protocol-tests/model/awsQuery/xml-lists.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ apply XmlLists @httpResponseTests([
<flattenedList>bye</flattenedList>
<customName>yep</customName>
<customName>nope</customName>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">a</flattenedListWithMemberNamespace>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">b</flattenedListWithMemberNamespace>
<flattenedListWithNamespace>a</flattenedListWithNamespace>
<flattenedListWithNamespace>b</flattenedListWithNamespace>
<myStructureList>
<item>
<value>1</value>
Expand Down Expand Up @@ -107,6 +111,8 @@ apply XmlLists @httpResponseTests([
renamedListMembers: ["foo", "bar"],
flattenedList: ["hi", "bye"],
flattenedList2: ["yep", "nope"],
flattenedListWithMemberNamespace: ["a", "b"],
flattenedListWithNamespace: ["a", "b"],
structureList: [
{
a: "1",
Expand Down Expand Up @@ -180,6 +186,17 @@ structure XmlListsOutput {
// serializing flattened lists in structures.
flattenedList2: RenamedListMembers,

// The XML namespace of the flattened list's member is used, and
// list's XML namespace is disregarded.
@xmlFlattened
flattenedListWithMemberNamespace: ListWithMemberNamespace,

// Again, the XML namespace of the flattened list is ignored.
// The namespace of the member is used, which is empty, so
// no xmlns attribute appears on the serialized XML.
@xmlFlattened
flattenedListWithNamespace: ListWithNamespace,

@xmlName("myStructureList")
structureList: StructureList
}
Expand All @@ -201,3 +218,14 @@ structure StructureListMember {
@xmlName("other")
b: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithMemberNamespace {
@xmlNamespace(uri: "https://xml-member.example.com")
member: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithNamespace {
member: String,
}
54 changes: 54 additions & 0 deletions smithy-aws-protocol-tests/model/awsQuery/xml-maps.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,57 @@ map FlattenedXmlMapWithXmlNameOutputMap {
@xmlName("V")
value: String,
}

/// Flattened maps with @xmlNamespace and @xmlName
operation FlattenedXmlMapWithXmlNamespace {
output: FlattenedXmlMapWithXmlNamespaceOutput
}

apply FlattenedXmlMapWithXmlNamespace @httpResponseTests([
{
id: "QueryQueryFlattenedXmlMapWithXmlNamespace",
documentation: "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members",
protocol: awsQuery,
code: 200,
body: """
<FlattenedXmlMapWithXmlNamespaceResponse xmlns="https://example.com/">
<FlattenedXmlMapWithXmlNamespaceResult>
<KVP xmlns="https://the-member.example.com">
<K xmlns="https://the-key.example.com">a</K>
<V xmlns="https://the-value.example.com">A</V>
</KVP>
<KVP xmlns="https://the-member.example.com">
<K xmlns="https://the-key.example.com">b</K>
<V xmlns="https://the-value.example.com">B</V>
</KVP>
</FlattenedXmlMapWithXmlNamespaceResult>
</FlattenedXmlMapWithXmlNamespaceResponse>""",
bodyMediaType: "application/xml",
headers: {
"Content-Type": "text/xml"
},
params: {
myMap: {
a: "A",
b: "B",
}
}
}
])

structure FlattenedXmlMapWithXmlNamespaceOutput {
@xmlFlattened
@xmlName("KVP")
@xmlNamespace(uri: "https://the-member.example.com")
myMap: FlattenedXmlMapWithXmlNamespaceOutputMap,
}

map FlattenedXmlMapWithXmlNamespaceOutputMap {
@xmlName("K")
@xmlNamespace(uri: "https://the-key.example.com")
key: String,

@xmlName("V")
@xmlNamespace(uri: "https://the-value.example.com")
value: String,
}
31 changes: 30 additions & 1 deletion smithy-aws-protocol-tests/model/ec2Query/xml-lists.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use smithy.test#httpResponseTests
/// 4. XML lists with @xmlName on its members
/// 5. Flattened XML lists.
/// 6. Flattened XML lists with @xmlName.
/// 7. Lists of structures.
/// 7. Flattened XML lists with @xmlNamespace.
/// 8. Lists of structures.
operation XmlLists {
output: XmlListsOutput
}
Expand Down Expand Up @@ -78,6 +79,10 @@ apply XmlLists @httpResponseTests([
<flattenedList>bye</flattenedList>
<customName>yep</customName>
<customName>nope</customName>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">a</flattenedListWithMemberNamespace>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">b</flattenedListWithMemberNamespace>
<flattenedListWithNamespace>a</flattenedListWithNamespace>
<flattenedListWithNamespace>b</flattenedListWithNamespace>
<myStructureList>
<item>
<value>1</value>
Expand Down Expand Up @@ -106,6 +111,8 @@ apply XmlLists @httpResponseTests([
renamedListMembers: ["foo", "bar"],
flattenedList: ["hi", "bye"],
flattenedList2: ["yep", "nope"],
flattenedListWithMemberNamespace: ["a", "b"],
flattenedListWithNamespace: ["a", "b"],
structureList: [
{
a: "1",
Expand Down Expand Up @@ -177,6 +184,17 @@ structure XmlListsOutput {
// serializing flattened lists in structures.
flattenedList2: RenamedListMembers,

// The XML namespace of the flattened list's member is used, and
// list's XML namespace is disregarded.
@xmlFlattened
flattenedListWithMemberNamespace: ListWithMemberNamespace,

// Again, the XML namespace of the flattened list is ignored.
// The namespace of the member is used, which is empty, so
// no xmlns attribute appears on the serialized XML.
@xmlFlattened
flattenedListWithNamespace: ListWithNamespace,

@xmlName("myStructureList")
structureList: StructureList
}
Expand All @@ -198,3 +216,14 @@ structure StructureListMember {
@xmlName("other")
b: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithMemberNamespace {
@xmlNamespace(uri: "https://xml-member.example.com")
member: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithNamespace {
member: String,
}
31 changes: 30 additions & 1 deletion smithy-aws-protocol-tests/model/restXml/document-lists.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use smithy.test#httpResponseTests
/// 4. XML lists with @xmlName on its members
/// 5. Flattened XML lists.
/// 6. Flattened XML lists with @xmlName.
/// 7. Lists of structures.
/// 7. Flattened XML lists with @xmlNamespace.
/// 8. Lists of structures.
@idempotent
@http(uri: "/XmlLists", method: "PUT")
operation XmlLists {
Expand Down Expand Up @@ -176,6 +177,10 @@ apply XmlLists @httpResponseTests([
<flattenedList>bye</flattenedList>
<customName>yep</customName>
<customName>nope</customName>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">a</flattenedListWithMemberNamespace>
<flattenedListWithMemberNamespace xmlns="https://xml-member.example.com">b</flattenedListWithMemberNamespace>
<flattenedListWithNamespace>a</flattenedListWithNamespace>
<flattenedListWithNamespace>b</flattenedListWithNamespace>
<myStructureList>
<item>
<value>1</value>
Expand Down Expand Up @@ -203,6 +208,8 @@ apply XmlLists @httpResponseTests([
renamedListMembers: ["foo", "bar"],
flattenedList: ["hi", "bye"],
flattenedList2: ["yep", "nope"],
flattenedListWithMemberNamespace: ["a", "b"],
flattenedListWithNamespace: ["a", "b"],
structureList: [
{
a: "1",
Expand Down Expand Up @@ -300,6 +307,17 @@ structure XmlListsInputOutput {
// serializing flattened lists in structures.
flattenedList2: RenamedListMembers,

// The XML namespace of the flattened list's member is used, and
// list's XML namespace is disregarded.
@xmlFlattened
flattenedListWithMemberNamespace: ListWithMemberNamespace,

// Again, the XML namespace of the flattened list is ignored.
// The namespace of the member is used, which is empty, so
// no xmlns attribute appears on the serialized XML.
@xmlFlattened
flattenedListWithNamespace: ListWithNamespace,

@xmlName("myStructureList")
structureList: StructureList
}
Expand All @@ -321,3 +339,14 @@ structure StructureListMember {
@xmlName("other")
b: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithMemberNamespace {
@xmlNamespace(uri: "https://xml-member.example.com")
member: String,
}

@xmlNamespace(uri: "https://xml-list.example.com")
list ListWithNamespace {
member: String,
}
53 changes: 53 additions & 0 deletions smithy-aws-protocol-tests/model/restXml/document-maps.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,56 @@ map FlattenedXmlMapWithXmlNameInputOutputMap {
@xmlName("V")
value: String,
}

/// Flattened maps with @xmlNamespace and @xmlName
@http(uri: "/FlattenedXmlMapWithXmlNamespace", method: "POST")
operation FlattenedXmlMapWithXmlNamespace {
output: FlattenedXmlMapWithXmlNamespaceOutput
}

apply FlattenedXmlMapWithXmlNamespace @httpResponseTests([
{
id: "RestXmlFlattenedXmlMapWithXmlNamespace",
documentation: "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members",
protocol: restXml,
code: 200,
body: """
<FlattenedXmlMapWithXmlNamespaceOutput>
<KVP xmlns="https://the-member.example.com">
<K xmlns="https://the-key.example.com">a</K>
<V xmlns="https://the-value.example.com">A</V>
</KVP>
<KVP xmlns="https://the-member.example.com">
<K xmlns="https://the-key.example.com">b</K>
<V xmlns="https://the-value.example.com">B</V>
</KVP>
</FlattenedXmlMapWithXmlNamespaceOutput>""",
bodyMediaType: "application/xml",
headers: {
"Content-Type": "application/xml"
},
params: {
myMap: {
a: "A",
b: "B",
}
}
}
])

structure FlattenedXmlMapWithXmlNamespaceOutput {
@xmlFlattened
@xmlName("KVP")
@xmlNamespace(uri: "https://the-member.example.com")
myMap: FlattenedXmlMapWithXmlNamespaceOutputMap,
}

map FlattenedXmlMapWithXmlNamespaceOutputMap {
@xmlName("K")
@xmlNamespace(uri: "https://the-key.example.com")
key: String,

@xmlName("V")
@xmlNamespace(uri: "https://the-value.example.com")
value: String,
}
1 change: 1 addition & 0 deletions smithy-aws-protocol-tests/model/restXml/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ service RestXml {
XmlMapsXmlName,
FlattenedXmlMap,
FlattenedXmlMapWithXmlName,
FlattenedXmlMapWithXmlNamespace,

// @xmlAttribute tests
XmlAttributes,
Expand Down
Loading

0 comments on commit 930ac23

Please sign in to comment.