From 7d82244d54d4178b9a0f5688c39d1050b0ff3cb4 Mon Sep 17 00:00:00 2001 From: Anton Mokhovikov Date: Mon, 29 Mar 2021 13:57:22 -0700 Subject: [PATCH] Adding conditionallyCreateOnlyProperties to metaschema (#121) --- .../cloudformation/resource/ResourceTypeSchema.java | 10 ++++++++++ .../schema/provider.definition.schema.v1.json | 4 ++++ .../resource/ResourceTypeSchemaTest.java | 11 +++++++++++ src/test/resources/test-schema.json | 6 ++++++ 4 files changed, 31 insertions(+) diff --git a/src/main/java/software/amazon/cloudformation/resource/ResourceTypeSchema.java b/src/main/java/software/amazon/cloudformation/resource/ResourceTypeSchema.java index 594c772..c7c7d27 100644 --- a/src/main/java/software/amazon/cloudformation/resource/ResourceTypeSchema.java +++ b/src/main/java/software/amazon/cloudformation/resource/ResourceTypeSchema.java @@ -52,6 +52,7 @@ public class ResourceTypeSchema { private final String replacementStrategy; private final boolean taggable; private final List createOnlyProperties = new ArrayList<>(); + private final List conditionalCreateOnlyProperties = new ArrayList<>(); private final List deprecatedProperties = new ArrayList<>(); private final List primaryIdentifier = new ArrayList<>(); private final List> additionalIdentifiers = new ArrayList<>(); @@ -96,6 +97,11 @@ public ResourceTypeSchema(Schema schema) { : true; this.unprocessedProperties.remove("taggable"); + this.unprocessedProperties.computeIfPresent("conditionalCreateOnlyProperties", (k, v) -> { + ((ArrayList) v).forEach(p -> this.conditionalCreateOnlyProperties.add(new JSONPointer(p.toString()))); + return null; + }); + this.unprocessedProperties.computeIfPresent("createOnlyProperties", (k, v) -> { ((ArrayList) v).forEach(p -> this.createOnlyProperties.add(new JSONPointer(p.toString()))); return null; @@ -159,6 +165,10 @@ public String getDescription() { return schema.getDescription(); } + public List getConditionalCreateOnlyPropertiesAsStrings() throws ValidationException { + return this.conditionalCreateOnlyProperties.stream().map(JSONPointer::toString).collect(Collectors.toList()); + } + public List getCreateOnlyPropertiesAsStrings() throws ValidationException { return this.createOnlyProperties.stream().map(JSONPointer::toString).collect(Collectors.toList()); } diff --git a/src/main/resources/schema/provider.definition.schema.v1.json b/src/main/resources/schema/provider.definition.schema.v1.json index c5de5a4..52b2734 100644 --- a/src/main/resources/schema/provider.definition.schema.v1.json +++ b/src/main/resources/schema/provider.definition.schema.v1.json @@ -387,6 +387,10 @@ "description": "A list of JSON pointers to properties (typically sensitive) that are able to be specified by the customer but unable to be returned in a Read request", "$ref": "#/definitions/jsonPointerArray" }, + "conditionalCreateOnlyProperties": { + "description": "A list of JSON pointers for properties that can only be updated under certain conditions. For example, you can upgrade the engine version of an RDS DBInstance but you cannot downgrade it. When updating this property for a resource in a CloudFormation stack, the resource will be replaced if it cannot be updated.", + "$ref": "#/definitions/jsonPointerArray" + }, "createOnlyProperties": { "description": "A list of JSON pointers to properties that are only able to be specified by the customer when creating a resource. Conversely, any property *not* in this list can be applied to an Update request.", "$ref": "#/definitions/jsonPointerArray" diff --git a/src/test/java/software/amazon/cloudformation/resource/ResourceTypeSchemaTest.java b/src/test/java/software/amazon/cloudformation/resource/ResourceTypeSchemaTest.java index 7bba480..002493d 100644 --- a/src/test/java/software/amazon/cloudformation/resource/ResourceTypeSchemaTest.java +++ b/src/test/java/software/amazon/cloudformation/resource/ResourceTypeSchemaTest.java @@ -51,6 +51,16 @@ public void getProperties() { assertThat(schema.getUnprocessedProperties()).isEmpty(); } + @Test + public void getConditionalCreateOnlyProperties() { + JSONObject o = loadJSON(TEST_SCHEMA_PATH); + final ResourceTypeSchema schema = ResourceTypeSchema.load(o); + + List result = schema.getConditionalCreateOnlyPropertiesAsStrings(); + + assertThat(result).containsExactly("/properties/propertyF"); + } + @Test public void getCreateOnlyProperties() { JSONObject o = loadJSON(TEST_SCHEMA_PATH); @@ -171,6 +181,7 @@ public void minimalSchema_hasNoSemantics() { assertThat(schema.getTypeName()).isEqualTo("AWS::Test::TestModel"); assertThat(schema.getUnprocessedProperties()).isEmpty(); assertThat(schema.getCreateOnlyPropertiesAsStrings()).isEmpty(); + assertThat(schema.getConditionalCreateOnlyPropertiesAsStrings()).isEmpty(); assertThat(schema.getDeprecatedPropertiesAsStrings()).isEmpty(); assertThat(schema.getPrimaryIdentifierAsStrings()).containsExactly("/properties/PropertyA"); assertThat(schema.getAdditionalIdentifiersAsStrings()).isEmpty(); diff --git a/src/test/resources/test-schema.json b/src/test/resources/test-schema.json index 6d0b2cc..fe0a828 100644 --- a/src/test/resources/test-schema.json +++ b/src/test/resources/test-schema.json @@ -28,6 +28,9 @@ "type": "string" } } + }, + "propertyF": { + "type": "string" } }, "propertyTransform": { @@ -37,6 +40,9 @@ "required": [ "propertyB" ], + "conditionalCreateOnlyProperties": [ + "/properties/propertyF" + ], "createOnlyProperties": [ "/properties/propertyA", "/properties/propertyD"