Skip to content

Commit

Permalink
Add versioning for API Gateway defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
srchase committed Aug 15, 2023
1 parent 15586bd commit bb120e3
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 75 deletions.
34 changes: 34 additions & 0 deletions docs/source-2.0/guides/converting-to-openapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,40 @@ dependency on ``software.amazon.smithy:smithy-aws-apigateway-openapi``.
Amazon API Gateway configuration settings
=========================================

apiGatewayDefaults (``string``)
Sets recommended default configuration settings and allows for those defaults
to be disabled.

This setting can be set to one of the following:

* ``2023-08-11`` Set the defaults described below.
* ``DISABLED`` Disables setting defaults.

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"]``

.. important::

This setting should be set explicitly to one of the allowed values.
If omitted, it will default to ``2023-08-11``.

.. code-block:: json
:caption: smithy-build.json
{
"version": "1.0",
"plugins": {
"openapi": {
"service": "example.weather#Weather",
"apiGatewayDefaults": "2023-08-11"
}
}
}
apiGatewayType (``string``)
Defines the type of API Gateway to define in the generated OpenAPI model.
This setting influences which API Gateway specific plugins apply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ApiGatewayDefaults DEFAULT_VERSION = ApiGatewayDefaults.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.getApiGatewayDefaults() == null) {
LOGGER.warning(String.format("`apiGatewayDefault` configuration not set for opeanapi plugin. Assuming %s.",
DEFAULT_VERSION));
config.setApiGatewayDefaults(DEFAULT_VERSION);
}
config.getApiGatewayDefaults().setDefaults(openApiConfig);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public enum ApiType {
private ApiType apiGatewayType = ApiType.REST;
private boolean disableCloudFormationSubstitution;
private Set<String> additionalAllowedCorsHeaders = Collections.emptySet();
private ApiGatewayDefaults apiGatewayDefaults;

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

public ApiGatewayDefaults getApiGatewayDefaults() {
return this.apiGatewayDefaults;
}

public void setApiGatewayDefaults(ApiGatewayDefaults apiGatewayDefaults) {
this.apiGatewayDefaults = apiGatewayDefaults;
}
}
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 ApiGatewayDefaults {
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;

ApiGatewayDefaults(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;
Expand All @@ -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.setApiGatewayDefaults(ApiGatewayDefaults.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.setApiGatewayDefaults(ApiGatewayDefaults.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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"BAR"
]
},
"FooBaz": {
"type": "object"
},
"HasDefaultRequestContent": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -69,6 +72,12 @@
},
"baz": {
"$ref": "#/components/schemas/DefaultEnum"
},
"withAlphaOnlyRef": {
"$ref": "#/components/schemas/FooBaz"
},
"anInt": {
"type": "integer"
}
}
}
Expand Down

This file was deleted.

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

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

structure Foo_Baz {}
Loading

0 comments on commit bb120e3

Please sign in to comment.