Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add document validation and fix their HTTP binding #474

Merged
merged 1 commit into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Trait selector
Value type
Annotation trait.

.. important::

This protocol does not support :ref:`inline document types <document-type>`.

.. tabs::

.. code-tab:: smithy
Expand Down
4 changes: 4 additions & 0 deletions docs/source/1.0/spec/aws/aws-query-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ See
}
}

.. important::

This protocol does not support :ref:`inline document types <document-type>`.

*TODO: Add specifications, protocol examples, etc.*
4 changes: 4 additions & 0 deletions docs/source/1.0/spec/aws/aws-restxml-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ that affect serialization:
* - :ref:`timestampFormat <timestampFormat-trait>`
- Defines a custom timestamp serialization format.

.. important::

This protocol does not support :ref:`inline document types <document-type>`.


------------
Content-Type
Expand Down
18 changes: 10 additions & 8 deletions docs/source/1.0/spec/core/http-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,7 @@ Serialization rules:
as a separate HTTP header either by concatenating the values with a comma on a
single line or by serializing each header value on its own line.
* boolean values are serialized as ``true`` or ``false``.
* blob values are base-64 encoded.
* string values with a :ref:`mediaType-trait` of "application/json" or that
end in "+json" are base-64 encoded.
* string values with a :ref:`mediaType-trait` are base64 encoded.
* timestamp values are serialized using the ``http-date``
format as defined in the ``IMF-fixdate`` production of
:rfc:`7231#section-7.1.1.1`.
Expand Down Expand Up @@ -688,9 +686,11 @@ Trait selector
.. code-block:: none

structure > member
:test(> map > member[id|member=value] > :test(simpleType, collection > member > simpleType))
:test(> map > member[id|member=value] > :test(
boolean, number, string, timestamp,
collection > member > :test(boolean, number, string, timestamp)))

*Structure member that targets a map of simple types or a map of lists/sets of simple types*
*Structure member that targets a map of specific simple types or a map of lists/sets of specific simple types*
Value type
``string`` value that defines the prefix to prepend to each header field
name stored in the targeted map member. For example, given a prefix value
Expand Down Expand Up @@ -762,9 +762,11 @@ Summary
Trait selector
.. code-block:: none

structure > :test(member > :test(simpleType, collection > member > simpleType))
structure > member
:test(> simpleType:not(document),
> collection > member > simpleType:not(document)))

*Structure members that target simple types or lists/sets of simple types*
*Structure members that target non-document simple types or collections of non-document simple types*
Value type
``string`` value defining the name of the query string parameter. The
query string value MUST NOT be empty. This trait is ignored when
Expand All @@ -786,7 +788,7 @@ Serialization rules:
* Multiple members of a structure MUST NOT case-sensitively target the same
query string parameter.
* boolean values are serialized as ``true`` or ``false``.
* blob values are base-64 encoded when serialized in the query string.
* blob values are base64 encoded when serialized in the query string.
* timestamp values are serialized as an :rfc:`3339`
``date-time`` string (e.g., ``1990-12-31T23:59:60Z``).
* :ref:`list` members are serialized by adding multiple query string parameters
Expand Down
12 changes: 10 additions & 2 deletions docs/source/1.0/spec/core/protocol-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Value type
in order to successfully use the protocol. Each shape MUST exist
and MUST be a trait. Code generators SHOULD ensure that they
support each listed trait.
* - noInlineDocumentSupport
- ``boolean``
- If set to ``true``, indicates that this protocol does not support
:ref:`document <document-type>` shapes. A service that uses such
a protocol MUST NOT contain any document shapes in their service
closure.

Smithy is protocol agnostic, which means it focuses on the interfaces and
abstractions that are provided to end-users rather than how the data is sent
Expand Down Expand Up @@ -275,5 +281,7 @@ Smithy defines the following built-in timestamp formats:
a timestamp differs from the default protocol format. Using this trait too
liberally can cause other tooling to improperly interpret the timestamp.

See :ref:`timestamp-serialization-format` for information on how to
determine the serialization format of a timestamp.
.. seealso::

Refer to :ref:`timestamp-serialization-format` for information on how to
determine the serialization format of a timestamp.
62 changes: 62 additions & 0 deletions smithy-aws-protocol-tests/model/awsJson1_1/documents.smithy
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This file defines test cases that serialize inline documents.

$version: "1.0"

namespace aws.protocoltests.json

use aws.protocols#awsJson1_1
use smithy.test#httpRequestTests
use smithy.test#httpResponseTests

/// This example serializes an inline document as part of the payload.
operation PutAndGetInlineDocuments {
input: PutAndGetInlineDocumentsInputOutput,
output: PutAndGetInlineDocumentsInputOutput
}

structure PutAndGetInlineDocumentsInputOutput {
inlineDocument: Document
}

document Document

apply PutAndGetInlineDocuments @httpRequestTests([
{
id: "PutAndGetInlineDocumentsInput",
documentation: "Serializes inline documents in a JSON request.",
protocol: awsJson1_1,
method: "POST",
uri: "/",
body: """
{
"inlineDocument": {"foo": "bar"}
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
inlineDocument: {
foo: "bar"
}
}
}
])

apply PutAndGetInlineDocuments @httpResponseTests([
{
id: "PutAndGetInlineDocumentsInput",
documentation: "Serializes inline documents in a JSON response.",
protocol: awsJson1_1,
code: 200,
body: """
{
"inlineDocument": {"foo": "bar"}
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
inlineDocument: {
foo: "bar"
}
}
}
])
1 change: 1 addition & 0 deletions smithy-aws-protocol-tests/model/awsJson1_1/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ service JsonProtocol {
EmptyOperation,
KitchenSinkOperation,
OperationWithOptionalInputOutput,
PutAndGetInlineDocuments
],
}

Expand Down
128 changes: 128 additions & 0 deletions smithy-aws-protocol-tests/model/restJson1/documents.smithy
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// This file defines test cases that serialize inline documents.

$version: "1.0"

namespace aws.protocoltests.restjson

use aws.protocols#restJson1
use smithy.test#httpRequestTests
use smithy.test#httpResponseTests

// Define some shapes shared throughout these test cases.
document Document

/// This example serializes an inline document as part of the payload.
@idempotent
@http(uri: "/InlineDocument", method: "PUT")
operation InlineDocument {
input: InlineDocumentInputOutput,
output: InlineDocumentInputOutput
}

structure InlineDocumentInputOutput {
stringValue: String,
documentValue: Document,
}

apply InlineDocument @httpRequestTests([
{
id: "InlineDocumentInput",
documentation: "Serializes inline documents as part of the JSON request payload with no escaping.",
protocol: restJson1,
method: "PUT",
uri: "/InlineDocument",
body: """
{
"stringValue": "string",
"documentValue": {
"foo": "bar"
}
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
stringValue: "string",
documentValue: {
foo: "bar"
}
}
}
])

apply InlineDocument @httpResponseTests([
{
id: "InlineDocumentOutput",
documentation: "Serializes inline documents as part of the JSON response payload with no escaping.",
protocol: restJson1,
code: 200,
body: """
{
"stringValue": "string",
"documentValue": {
"foo": "bar"
}
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
stringValue: "string",
documentValue: {
foo: "bar"
}
}
}
])

/// This example serializes an inline document as the entire HTTP payload.
@idempotent
@http(uri: "/InlineDocumentAsPayload", method: "PUT")
operation InlineDocumentAsPayload {
input: InlineDocumentAsPayloadInputOutput,
output: InlineDocumentAsPayloadInputOutput
}

structure InlineDocumentAsPayloadInputOutput {
@httpPayload
documentValue: Document,
}

apply InlineDocumentAsPayload @httpRequestTests([
{
id: "InlineDocumentAsPayloadInput",
documentation: "Serializes an inline document as the target of the httpPayload trait.",
protocol: restJson1,
method: "PUT",
uri: "/InlineDocumentAsPayload",
body: """
{
"foo": "bar"
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
documentValue: {
foo: "bar"
}
}
}
])

apply InlineDocumentAsPayload @httpResponseTests([
{
id: "InlineDocumentAsPayloadInputOutput",
documentation: "Serializes an inline document as the target of the httpPayload trait.",
protocol: restJson1,
code: 200,
body: """
{
"foo": "bar"
}""",
bodyMediaType: "application/json",
headers: {"Content-Type": "application/json"},
params: {
documentValue: {
foo: "bar"
}
}
}
])
4 changes: 4 additions & 0 deletions smithy-aws-protocol-tests/model/restJson1/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,9 @@ service RestJson {
JsonLists,
JsonMaps,
JsonBlobs,

// Documents
InlineDocument,
InlineDocumentAsPayload,
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"selector": "service"
},
"smithy.api#protocolDefinition": {
"noInlineDocumentSupport": true,
"traits": [
"smithy.api#httpError",
"smithy.api#httpHeader",
Expand Down Expand Up @@ -124,6 +125,7 @@
"selector": "service"
},
"smithy.api#protocolDefinition": {
"noInlineDocumentSupport": true,
"traits": [
"smithy.api#xmlAttribute",
"smithy.api#xmlFlattened",
Expand All @@ -142,6 +144,7 @@
"selector": "service"
},
"smithy.api#protocolDefinition": {
"noInlineDocumentSupport": true,
"traits": [
"aws.protocols#ec2QueryName",
"smithy.api#xmlAttribute",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ERROR] smithy.example#InvalidExample: This service uses the `aws.protocols#awsQuery` protocol which does not support inline document types, but the following document types were found in the closure of the service: [smithy.example#InlineDocument | NoInlineDocumentSupport
[SUPPRESSED] smithy.example#InvalidExample: This shape applies a trait that is deprecated: aws.protocols#awsQuery | DeprecatedTrait
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// awsQuery does not support inline documents. Because an inline document is
// used in the closure of InvalidExample, this model creates a DANGER event.

namespace smithy.example

use aws.protocols#awsQuery

@awsQuery
@suppress(["DeprecatedTrait"]) // ignore the fact that the awsQuery trait is deprecated
service InvalidExample {
version: "2020-06-15",
operations: [Operation1]
}

operation Operation1 {
input: Operation1Input,
}

structure Operation1Input {
foo: InlineDocument,
}

document InlineDocument
Loading