The "passthroughBehavior" property of the x-amzn-apigateway-integration
option was incorrectly cased as "passThroughBehavior" when added via
the `@cors` trait, when an integration trait was not present.
A couple test cases for CORS were using the incorrect casing, which
have been fixed.
* Add support for missing authorizer members
This commit adds support for the `authorizerPayloadFormatVersion` and
`enableSimpleResponses` members in `apiGateway#authorizers`.
These members are used to properly define authorizers for HTTP APIs.
We previously added the `nullable: true` property to some object
properties if they had the box trait. However, we never should have
done that, it has no effect, and it resulted in us adding code to
handle difference between OpenAPI versions around how we handled
whether null is an acceptable value. We don't need any of it. We
actually don't want null sent on the wire and the optionality of a
member is already controlled by the `required` and `default`
properties in OpenAPI.
* Cleanup after rebasing against main
* Update OpenAPI converter to be deterministic
* Fix the flattenMixins model transform to not use the removeShapes
transform when removing mixins. This causes issues when a mixin is
already flattened out of a shape.
* Fixed a naming issue for setting enum shape members.
* Don't try to flatten mixins in a shape if it has none.
* Clean up method for finding a required mixin member so it doesn't
build intermediate member shapes.
* Add test to ensure forward references are ordered.
* Mark a few public APIs as internal in the OpenAPI converters because
I think we'll refactor them heavily in the near future.
This commit updates Smithy IDL v2 to support custom default values
rather than only default zero values.
We didn't previously support custom default values because we wanted to
be able to change default values if ever needed, we wanted to avoid
information disclosure of unreleased internal members, and we wanted
clients to be able to fill in a default zero value if a required member
is missing on the wire (implying that the member transitioned from
required to default).
While default zero values are a big simplification for clients, they do
come with awkward tradeoffs. For example, the zero value of an enum was
`""` (or it could have been the first enum in the shape definition but
that's problematic due to model filtering, and it requires a lot of
up-front planning from service teams). We also observed that there are
likely 1,000+ members already used in AWS that have default values that
are only captured through documentation. If we could actually model
defaults, it would be easier to catch changes to default values in
automated diff tools and discuss them in API reviews.
To address these concerns and support custom default values, we
recommend the following:
* clients implement presence tracking and only serialize default values if
the member is explicitly set to the default value. This allows services
to change defaults if ever necessary.
* servers always serialize default values unless the member is marked with
the `@internal` trait. This makes it explicit as to what the server
thinks the default value is while still preventing unintended
information disclosure of unreleased features.
* To avoid downtime and account for misconfigured servers that do not
serialize required or default members, clients attempt to populate the
member with a default zero value.
More details and specifics can be found in
defaults-and-model-evolution.md.
Enum changes:
* Given the addition of syntax sugar for assigning values to
defaulted structure members, this commit also allows syntactic sugar for
assigning values to enum and intEnum shapes without the use of the
`@enumValue` trait.
* Now that there is no default zero value for enums, the `@enumDefault`
trait has been removed.
When we create the JSON schema for open-api we were setting the format
int32/int64 if the shape type is integer or long regardless of which
type we were mapping to. This is not correct if we do not also map the
type to the custom OpenAPI's integer type, as controlled by the
useIntegerType configuration setting, which if not set will map the
type to "number" instead which cannot use these formats according to
the specification. To fix the issue we need to only emit the format
when we also map the type to "integer".
This commit updates traits to use the originally provided node value in
a model file so that the value is persisted as-is when calling toNode on
a trait. This prevents needing to duplicate the work of creating the
trait and helps expose issues like typos in traits because invalid
properties can be detected when validating traits against the model.
The tradeoff of this change is that if a trait does any kind of
normalization of values or setting of defaults or if a trait has logic
around omitting empty lists, false, etc, then traits may need to
override equals and hashCode since relying on toNode equality would
render two traits inequal. That generally is fine, but it may be a
problem if a model transformation is performed and you need to compare
two models, you need to merge two models that migth contain duplicate
shapes as a result of a transform, etc.
This commit introduces the `smithy.api#Unit` type that that is used for
operations with no meaningful input or output, and for tagged union
members with no meaningful value. Operations will now, by default,
target `smithy.api#Union` if they do not define input or output.
This commit also introduces the `@input` and `@output` traits that are
used to specialize structures as for use only as the input or output of
a single operation. The `@input` trait provides structures with more
relaxed backward compatibility constraints so that, for example, when
things like the `@default` value trait are added, it is considered a
backward compatible change to remove the `@required` trait from the
member of a structure marked with the `@input` trait.
New methods were added to smithy-model to account for the fact that
operations always now have input and output shapes. The existing methods
that return Optional shape IDs and structures remain but are marked as
deprecated. Any usage of these deprecated methods were updated
throughout the monorepo to use the newly introduced methods (this
accounts for a lot of the churn).
If an operation defines no input or output, a WARNING is emitted. If an
operation defines input or output other than `smithy.api#Unit` and the
targeted shapes aren't marked with `@input` or `@output` a validation
event is emitted. This also accounts for a lot of churn in test cases
(either to add suppressions or to add input and output). Due to the
suppressed events, Smithy's errorfiles test runner was updated to no
longer require that SUPPRESSED validation events are explicitly listed
in errorfiles (they can be but don't have to be).
Along with updating every operation to define input and output shapes,
this change also removes many JSON AST examples. These examples were
unnecessary and a liability for the team to maintain. The appropriate
place to document how the IDL and JSON AST interact is in the
specification language around the IDL and JSON AST, not spread across
the entire specification. Alternatively, I could have edited each
impacted AST example, but I worried that I would add mistakes and they
are not validated against the IDL examples.
When creating JSONSchema from a Smithy model, any two conflicting shapes with
the same unqualified name would cause the process to fail, when in most cases
the conflict is only important if it occurs between two shapes connected to
the service in question.
CloudFormation resource schema generation must consider additional shapes
via @cfnResource's additionalSchemas property. This property is read by
the CFN index and subsequently discarded, so I simply disabled the more
narrowly-scoped conflict detection for CFN specifically. This can be removed
once shapes can be connected directly to a service.
Rework the 'httpChecksum' trait
Moves the httpChecksum trait to the aws.protocols namespace and updates the trait
to follow a new design that constrains the trait for client safety and forwards compatibility.
Co-authored-by: skotambkar <kotambkarshantanu@gmail.com>
This updates the lists of headers needed for sigv4 and for the
restJson1 protocol in the openapi conversion. It also ensures
that those headers are added to cors configurations for apig.
CloudFormation variables can be parameter names, resource logical IDs
or resource attributes.
* Parameter names: can be alphanumeric or pseudo-parameters, which can
be prefixed with "AWS::"
* Resource logical IDs: can be alphanumeric.
* Resource attributes: specified as resourceLogicalId.attributeName,
where attributeName is also alphanumeric.
This adds support for non-numeric float values in jsonschema and
openapi. It is disabled by default because it makes the type
signature awful, and enabling it by default would be a backwards
incompatible change.
OpenAPI supports a format called "double" on the "number" type to indicate
that a number is a double precision floating point number. Timestamps
that use epoch-seconds have been updated to use this format so that
stricter JSON Schema validators don't error when they encounter
decimals. "double" is only added as a format when performing OpenAPI
conversions and are not added by default when performing JSON Schema
conversions.
The support for adding CORS REST API headers is now in its own mapper
class to better distinguish between the AddIntegrations mapper that is
applied to every type of API Gateway service, and our support for CORS
in REST APIs which is different than CORS in HTTP APIs.
This commit ensures that Access-Control-Expose-Headers is correctly
populated based on all of the headers used in an operation, including
any headers that might be added manually during the OpenAPI conversion
independent of a Smithy shape.
I added a new ApiGatewayMapper method called postProcessOperation to
allow transformations to better control when they are applied, in
particular, transforms sometimes need to occur on an operation after the
things that the operation contains have been transformed. This was not
previously possible even with the ordering semantics that already exist.
This change was necessary in order to ensure that the correct CORs
headers are added to operations based on all of the transforms applied
to the operation, and it makes it easier to separate CORS headers from
modeled headers when constructing Access-Control-Expose-Headers.
This updates the OpenAPI conversion to set an operation's
`requestBody` as required if the operation has an `httpPayload`
member and that member is required or if the operation has no
`httpPayload` member but does have a required member bound to the
document.
There are valid use cases on an `@aws.apigateway#authorizors` entry
for setting the `customAuthType` property without setting its `type`
property. This enables that use case while still not defaulting the
client extension to "custom" if the `type` is not set.
This commit adds support for enabling API Gateway's API key usage
plans. An httpApiKeyAuth based authorizer on an operation will now
be directly set on every operation in the OpenAPI document, even if
it's the same as the service level authorizer.
This commit also updates the strategy for not setting a default
"x-amazon-apigateway-authtype" extension to an absence of the "type"
setting on the definition in the authorizers trait.
Allow the setting of an empty customAuthType to indicate that the
x-amazon-apigateway-authtype extension should not be set to "custom".
This is done to handle the current defaulting behavior instead of
adding a flag. This is necessary to enable API Gateway's built-in
API key validation.
Unfortunately, Kotlin isn't well-supported in VS Code, and we're looking
at adding VS plugins to Smithy in the future. We've also found that the
majority of Gradle plugins only provide Groovy examples, making it
harder to write out build scripts due to a lack of Kotlin examples. With
IDE plugins and a quicker compile/test feedback loop, the loss in type
safety realized by Kotlin isn't as bad as I thought it would be.
This commit deprecates the old access pattern used to create a
KnowledgeIndex (`model.getKnowledge(X.class)`) in favor of using a new
convention: `X.of(model)`. KnowledgeIndex implementations are now
expected to provide a public static method named `of` that accepts a
`Model` and returns an instance of the class. The instance should be
created by calling `model.getKnowledge(Class<T>, Function<Model, T>)`
which will ensure the index is cached in the given model.
This change is the first step towards seeing if we can get full GraalVM
native image support. It also makes using a KnowledgeIndex more
ergonomic IMO, and remove reflection, which is generally a good thing.
The deprecated method will eventually be removed in a subsequent
release.
Currently, when converting the Smithy model to API Gateway for HTTP APIs, it fails because it doesn't configure the `payloadFormatVersion`. This change adds the payload format version to the IntegrationTrait.
The payload format version specifies the format of the data that API Gateway sends to an integration, and how API Gateway interprets the response. If you create an integration for HTTP APIs programmatically, you **must** specify a payloadFormatVersion. The supported values are 1.0 and 2.0.
This fixes a bug where any `SourceException`s rasied after the model
assembler began validation would result in validation getting
skipped. This was due to the fact that the assembler calls `onEnd`
in its visitor before validation AND whenever it catches that
class of exception. `onEnd` will cache its result, so you can't simply
call `onError` and guarantee it will be in the output.
The `$version` control statement can now be set to only a major version
(e.g., "1") to indicate that an implementation must support a version >= 1
and < 2. `$version` can now be set to `major.minor` (e.g., "1.1") to
indicate that an implementation must support a version >= 1.1 and < 2.