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 14, 2023
1 parent b8999a4 commit 94dbad0
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 75 deletions.
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 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
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
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.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;
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 94dbad0

Please sign in to comment.