Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add versioning for API Gateway defaults
Browse files Browse the repository at this point in the history
srchase committed Aug 14, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 15586bd commit 31cfe93
Showing 10 changed files with 254 additions and 75 deletions.
27 changes: 27 additions & 0 deletions docs/source-2.0/guides/converting-to-openapi.rst
Original file line number Diff line number Diff line change
@@ -1176,6 +1176,33 @@ dependency on ``software.amazon.smithy:smithy-aws-apigateway-openapi``.
Amazon API Gateway configuration settings
=========================================

apiGatewayDefault (``string``)
Sets recommended default configuration settings and allows for those defaults
to be disabled. If this setting is omitted, the ``2023-08-11`` version will
be used by default.

The ``2023-08-11`` version sets the following configuration settings:

* :ref:`alphanumericOnlyRefs <generate-openapi-jsonschema-setting-alphanumericOnlyRefs>`: ``true``
* :ref:`disableDefaultValues <generate-openapi-setting-disableDefaultValues>`: ``true``
* :ref:`disableIntegerFormat <generate-openapi-setting-disableIntegerFormat>`: ``true``
* :ref:`disableFeatures <generate-openapi-jsonschema-setting-disableFeatures>`: ``["default"]``

.. code-block:: json
:caption: smithy-build.json
{
"version": "1.0",
"plugins": {
"openapi": {
"service": "example.weather#Weather",
"apiGatewayDefault": "2023-08-11"
}
}
}
If the version is set to ``DISABLED``, the configuration settings will not be set.

apiGatewayType (``string``)
Defines the type of API Gateway to define in the generated OpenAPI model.
This setting influences which API Gateway specific plugins apply
Original file line number Diff line number Diff line change
@@ -16,30 +16,37 @@
package software.amazon.smithy.aws.apigateway.openapi;

import java.util.List;
import java.util.logging.Logger;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.openapi.OpenApiConfig;

/**
* Disables OpenAPI and JSON Schema features not supported by API Gateway.
* Sets default config settings for API Gateway.
*
* <p>By default, this disables OpenAPI and JSON Schema features not
* supported by API Gateway.</p>
*
* <p>API Gateway does not allow characters like "_". API Gateway
* doesn't support the "default" trait or `int32` or `int64` "format"
* values.
*/
final class AddDefaultConfigSettings implements ApiGatewayMapper {
private static final Logger LOGGER = Logger.getLogger(AddDefaultConfigSettings.class.getName());
private static final String DEFAULT_VERSION_MESSAGE = String.format("`apiGatewayDefault` configuration not set for"
+ " opeanapi plugin. Assuming %s.", ApiGatewayDefault.VERSION_2023_08_11);

@Override
public List<ApiGatewayConfig.ApiType> getApiTypes() {
return null;
}

@Override
public void updateDefaultSettings(Model model, OpenApiConfig config) {
config.setAlphanumericOnlyRefs(true);
config.getDisableFeatures().add("default");
config.setDisableDefaultValues(true);
// If the `useIntegerType` config has been set, this assures that
// `int32` and `int64` formats are not set on those integer types.
// See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html
config.setDisableIntegerFormat(true);
public void updateDefaultSettings(Model model, OpenApiConfig openApiConfig) {
ApiGatewayConfig config = openApiConfig.getExtensions(ApiGatewayConfig.class);
if (config.getApiGatewayDefault() == null) {
LOGGER.warning(DEFAULT_VERSION_MESSAGE);
config.setApiGatewayDefault(ApiGatewayDefault.VERSION_2023_08_11);
}
config.getApiGatewayDefault().setDefaults(openApiConfig);
}
}
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ public enum ApiType {
private ApiType apiGatewayType = ApiType.REST;
private boolean disableCloudFormationSubstitution;
private Set<String> additionalAllowedCorsHeaders = Collections.emptySet();
private ApiGatewayDefault apiGatewayDefault;

/**
* @return Returns true if CloudFormation substitutions are disabled.
@@ -120,4 +121,12 @@ public Set<String> getAdditionalAllowedCorsHeadersSet() {
public void setAdditionalAllowedCorsHeaders(Collection<String> additionalAllowedCorsHeaders) {
this.additionalAllowedCorsHeaders = SetUtils.caseInsensitiveCopyOf(additionalAllowedCorsHeaders);
}

public ApiGatewayDefault getApiGatewayDefault() {
return this.apiGatewayDefault;
}

public void setApiGatewayDefault(ApiGatewayDefault apiGatewayDefault) {
this.apiGatewayDefault = apiGatewayDefault;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.smithy.aws.apigateway.openapi;

import software.amazon.smithy.openapi.OpenApiConfig;
import software.amazon.smithy.utils.SetUtils;
import software.amazon.smithy.utils.SmithyUnstableApi;

public enum ApiGatewayDefault {
VERSION_2023_08_11("2023-08-11") {
@Override
public void setDefaults(OpenApiConfig config) {
config.setAlphanumericOnlyRefs(true);
config.setDisableDefaultValues(true);
config.setDisableIntegerFormat(true);
config.setDisableFeatures(SetUtils.of("default"));
}
},
DISABLED("disabled") {
@Override
public void setDefaults(OpenApiConfig config) {
}
};

private final String version;

ApiGatewayDefault(String version) {
this.version = version;
}

@Override
public String toString() {
return version;
}

@SmithyUnstableApi
public abstract void setDefaults(OpenApiConfig config);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package software.amazon.smithy.aws.apigateway.openapi;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;

import java.util.Optional;
import org.junit.jupiter.api.Test;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.NodePointer;
import software.amazon.smithy.model.node.NodeMapper;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.openapi.OpenApiConfig;
@@ -16,38 +12,66 @@

public class AddDefaultConfigSettingsTest {
@Test
public void addsDefaultConfigSettings() {
public void defaultsTo2023_08_11() {
Model model = Model.assembler()
.discoverModels(getClass().getClassLoader())
.addImport(getClass().getResource("alphanumeric-only.json"))
.addImport(getClass().getResource("default-config-settings.smithy"))
.assemble()
.unwrap();

OpenApiConfig config = new OpenApiConfig();
config.setService(ShapeId.from("example.smithy#MyService"));
config.setUseIntegerType(true);
ObjectNode result = OpenApiConverter.create()
.config(config)
.convertToNode(model);

// Ensure that Foo_Baz became FooBaz.
NodePointer pointer = NodePointer.parse("/components/schemas/FooBaz");
assertThat(pointer.getValue(result), not(Optional.empty()));
Node.assertEquals(result, Node.parse(IoUtils.readUtf8Resource(getClass(), "2023-08-11.openapi.json")));
}

@Test
public void omitsDefaultTraits() {
public void usesVersion2023_08_11() {
Model model = Model.assembler()
.discoverModels(getClass().getClassLoader())
.addImport(getClass().getResource("omits-default-trait.smithy"))
.addImport(getClass().getResource("default-config-settings.smithy"))
.assemble()
.unwrap();

OpenApiConfig config = new OpenApiConfig();
config.setService(ShapeId.from("example.smithy#MyService"));
OpenApiConfig openApiConfig = new OpenApiConfig();
openApiConfig.setService(ShapeId.from("example.smithy#MyService"));
openApiConfig.setUseIntegerType(true);

ApiGatewayConfig config = new ApiGatewayConfig();
NodeMapper mapper = new NodeMapper();
config.setApiGatewayDefault(ApiGatewayDefault.VERSION_2023_08_11);
openApiConfig.setExtensions(mapper.serialize(config).expectObjectNode());
ObjectNode result = OpenApiConverter.create()
.config(config)
.config(openApiConfig)
.convertToNode(model);

Node.assertEquals(result, Node.parse(IoUtils.readUtf8Resource(getClass(), "2023-08-11.openapi.json")));
}

@Test
public void canDisableDefaults() {
Model model = Model.assembler()
.discoverModels(getClass().getClassLoader())
.addImport(getClass().getResource("default-config-settings.smithy"))
.assemble()
.unwrap();

OpenApiConfig openApiConfig = new OpenApiConfig();
openApiConfig.setService(ShapeId.from("example.smithy#MyService"));
openApiConfig.setUseIntegerType(true);

ApiGatewayConfig config = new ApiGatewayConfig();
NodeMapper mapper = new NodeMapper();
config.setApiGatewayDefault(ApiGatewayDefault.DISABLED);
openApiConfig.setExtensions(mapper.serialize(config).expectObjectNode());
ObjectNode result = OpenApiConverter.create()
.config(openApiConfig)
.convertToNode(model);

Node.assertEquals(result, Node.parse(IoUtils.readUtf8Resource(getClass(), "omits-default-trait.openapi.json")));
Node.assertEquals(result, Node.parse(IoUtils.readUtf8Resource(getClass(), "disabled-defaults.openapi.json")));
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
package software.amazon.smithy.aws.apigateway.openapi;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;

import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.NodePointer;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.openapi.OpenApiConfig;
Original file line number Diff line number Diff line change
@@ -41,6 +41,9 @@
"BAR"
]
},
"FooBaz": {
"type": "object"
},
"HasDefaultRequestContent": {
"type": "object",
"properties": {
@@ -69,6 +72,12 @@
},
"baz": {
"$ref": "#/components/schemas/DefaultEnum"
},
"withAlphaOnlyRef": {
"$ref": "#/components/schemas/FooBaz"
},
"anInt": {
"type": "integer"
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -20,6 +20,8 @@ operation HasDefault {
foo: String = ""
bar: StringList = []
baz: DefaultEnum = "FOO"
withAlphaOnlyRef: Foo_Baz,
anInt: Long
}
}

@@ -31,3 +33,5 @@ enum DefaultEnum {
FOO
BAR
}

structure Foo_Baz {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"openapi": "3.0.2",
"info": {
"title": "MyService",
"version": "2020-07-02"
},
"paths": {
"/defaults": {
"post": {
"operationId": "HasDefault",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HasDefaultRequestContent"
}
}
}
},
"responses": {
"200": {
"description": "HasDefault 200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HasDefaultResponseContent"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"DefaultEnum": {
"type": "string",
"enum": [
"FOO",
"BAR"
]
},
"Foo_Baz": {
"type": "object"
},
"HasDefaultRequestContent": {
"type": "object",
"properties": {
"foo": {
"type": "string",
"default": ""
},
"bar": {
"type": "array",
"default": [],
"items": {
"type": "string"
}
}
}
},
"HasDefaultResponseContent": {
"type": "object",
"properties": {
"foo": {
"type": "string",
"default": ""
},
"bar": {
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"baz": {
"allOf": [
{
"$ref": "#/components/schemas/DefaultEnum"
},
{
"default": "FOO"
}
]
},
"withAlphaOnlyRef": {
"$ref": "#/components/schemas/Foo_Baz"
},
"anInt": {
"type": "integer",
"format": "int64"
}
}
}
}
}
}

0 comments on commit 31cfe93

Please sign in to comment.