Skip to content

Commit

Permalink
[BugFix] Fix for TagProperty Validation (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
ammokhov authored Oct 15, 2024
1 parent b322bba commit d46e05a
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public void validateTaggingMetadata(final boolean containUpdateHandler, final Sc
throw new ValidationException(errorMessage, "tagging", "#/tagging/tagProperty");
}

final String propertyName = this.tagProperty.toString().substring(propertiesPrefix.length());
final String propertyName = this.tagProperty.toString().substring(propertiesPrefix.length()).replaceAll("/\\*/", "/0/");

if (this.taggable && !schema.definesProperty(propertyName)) {
final String errorMessage = String.format("Invalid tagProperty value since %s not found in schema", propertyName);
throw new ValidationException(errorMessage, "tagging", "#/tagging/tagProperty");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ public boolean definesProperty(String field) {
.filter(subschema -> subschema instanceof ObjectSchema)
.findFirst().get()
: schema;

return schemaToCheck.definesProperty(field);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static software.amazon.cloudformation.resource.ValidatorTest.loadJSON;

import java.util.List;
import java.util.Map;

import org.everit.json.schema.PublicJSONPointer;
import org.json.JSONObject;
import org.json.JSONPointer;
import org.junit.jupiter.api.Test;

import software.amazon.cloudformation.resource.exceptions.ValidationException;

public class ResourceTypeSchemaTest {
private static final String TEST_SCHEMA_PATH = "/test-schema.json";
private static final String TEST_NESTED_TAGGING_SCHEMA_PATH = "/test-nested-tagging-schema.json";
private static final String TEST_SCHEMA_WITH_EMPTY_WRITE_ONLY_PATH = "/test-schema-with-empty-write-only.json";
private static final String EMPTY_SCHEMA_PATH = "/empty-schema.json";
private static final String SINGLETON_SCHEMA_PATH = "/singleton-test-schema.json";
Expand Down Expand Up @@ -68,6 +71,20 @@ public void getProperties() {
assertThat(schema.getUnprocessedProperties()).isEmpty();
}

@Test
public void getProperties2() {
JSONPointer tagProperty = new JSONPointer("/properties/NestedTagProperty/TagSpecifications/*/Tags");
JSONObject o = loadJSON(TEST_NESTED_TAGGING_SCHEMA_PATH);
final ResourceTypeSchema schema = ResourceTypeSchema.load(o);

assertThat(schema.getDescription()).isEqualTo("A test schema for unit tests.");
assertThat(schema.getSourceUrl()).isEqualTo("https://mycorp.com/my-repo.git");
assertThat(schema.getTypeName()).isEqualTo("AWS::Test::TestModel");
assertThat(schema.isTaggable()).isTrue();
assertThat(schema.getTagging().getTagProperty().toString()).isEqualTo(tagProperty.toString());
assertDoesNotThrow(() -> schema.getTagging().validateTaggingMetadata(true, schema.getSchema()));
}

@Test
public void getConditionalCreateOnlyProperties() {
JSONObject o = loadJSON(TEST_SCHEMA_PATH);
Expand Down
128 changes: 128 additions & 0 deletions src/test/resources/test-nested-tagging-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"typeName": "AWS::Test::TestModel",
"description": "A test schema for unit tests.",
"sourceUrl": "https://mycorp.com/my-repo.git",
"definitions": {
"NestedDefinition": {
"type": "object",
"additionalProperties": false,
"properties": {
"TagSpecifications": {
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/TagSpecificationDefinition"
}
}
}
},
"TagSpecificationDefinition": {
"type": "object",
"additionalProperties": false,
"properties": {
"Tags": {
"type": "array",
"uniqueItems": false,
"items": {
"$ref": "#/definitions/Tag"
}
}
}
},
"Tag": {
"type": "object",
"additionalProperties": false,
"properties": {
"Key": {
"type": "string"
},
"Value": {
"type": "string"
}
},
"required": [
"Value",
"Key"
]
}
},
"properties": {
"propertyA": {
"type": "string"
},
"propertyB": {
"type": "array",
"arrayType": "AttributeList",
"items": {
"type": "integer"
}
},
"propertyC": {
"type": "string"
},
"propertyD": {
"type": "boolean"
},
"propertyE": {
"type": "object",
"properties": {
"nestedProperty": {
"type": "string"
},
"writeOnlyArray": {
"type": "string"
}
}
},
"propertyF": {
"type": "string"
},
"NestedTagProperty": {
"$ref": "#/definitions/NestedDefinition"
}
},
"tagging": {
"taggable": true,
"tagOnCreate": true,
"tagUpdatable": false,
"cloudFormationSystemTags": true,
"tagProperty": "/properties/NestedTagProperty/TagSpecifications/*/Tags",
"permissions": [
"permission:AddTags"
]
},
"propertyTransform": {
"/properties/propertyA": "$join([$string(test), propertyA])",
"/properties/propertyB": "$count(propertyB) = 0 ? null : propertyB"
},
"required": [
"propertyB"
],
"conditionalCreateOnlyProperties": [
"/properties/propertyF"
],
"createOnlyProperties": [
"/properties/propertyA",
"/properties/propertyD"
],
"deprecatedProperties": [
"/properties/propertyC"
],
"readOnlyProperties": [
"/properties/propertyB"
],
"writeOnlyProperties": [
"/properties/propertyC",
"/properties/propertyE/nestedProperty"
],
"primaryIdentifier": [
"/properties/propertyA"
],
"additionalIdentifiers": [
[
"/properties/propertyB"
]
],
"replacementStrategy": "create_then_delete",
"additionalProperties": false
}

0 comments on commit d46e05a

Please sign in to comment.