Skip to content

Commit 503170a

Browse files
authored
Merge branch 'v2' into feat/validation-batch
2 parents 0dcb8b9 + b4f9ee9 commit 503170a

File tree

9 files changed

+31
-25
lines changed

9 files changed

+31
-25
lines changed

docs/utilities/validation.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ You can validate inbound and outbound events using `@Validation` annotation.
8383

8484
You can also use the `Validator#validate()` methods, if you want more control over the validation process such as handling a validation error.
8585

86-
We support JSON schema version 4, 6, 7 and 201909 (from [jmespath-jackson library](https://github.com/burtcorp/jmespath-java)).
86+
We support JSON schema version 4, 6, 7, 2019-09 and 2020-12 using the [NetworkNT JSON Schema Validator](https://github.com/networknt/json-schema-validator). ([Compatibility with JSON Schema versions](https://github.com/networknt/json-schema-validator/blob/master/doc/compatibility.md)).
87+
88+
The validator is configured to enable format assertions by default even for 2019-09 and 2020-12.
8789

8890
### Validation annotation
8991

@@ -233,7 +235,8 @@ and [function](https://jmespath.org/tutorial.html#functions) expressions, where
233235

234236

235237
## Change the schema version
236-
By default, powertools-validation is configured with [V7](https://json-schema.org/draft-07/json-schema-release-notes.html).
238+
By default, powertools-validation is configured to use [V7](https://json-schema.org/draft-07/json-schema-release-notes.html) as the default dialect if [`$schema`](https://json-schema.org/understanding-json-schema/reference/schema#schema) is not explicitly specified within the schema. If [`$schema`](https://json-schema.org/understanding-json-schema/reference/schema#schema) is explicitly specified within the schema, the validator will use the specified dialect.
239+
237240
You can use the `ValidationConfig` to change that behaviour.
238241

239242
=== "Handler with custom schema version"

powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/ValidationALBE2ET.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void test_invalidInboundSQSEvent() throws IOException {
8585
// THEN
8686
// invocation should fail inbound validation and return an error message
8787
JsonNode validJsonNode = objectMapper.readTree(invocationResult.getResult());
88-
assertThat(validJsonNode.get("errorMessage").asText()).contains("$.price: is missing but it is required");
88+
assertThat(validJsonNode.get("errorMessage").asText()).contains(": required property 'price' not found");
8989
}
9090

9191
@Test
@@ -99,6 +99,6 @@ void test_invalidOutboundSQSEvent() throws IOException {
9999
// THEN
100100
// invocation should fail outbound validation and return 400
101101
JsonNode validJsonNode = objectMapper.readTree(invocationResult.getResult());
102-
assertThat(validJsonNode.get("errorMessage").asText()).contains("$.price: must have an exclusive maximum value of 1000");
102+
assertThat(validJsonNode.get("errorMessage").asText()).contains("/price: must have an exclusive maximum value of 1000");
103103
}
104104
}

powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/ValidationApiGWE2ET.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void test_invalidInboundApiGWEvent() throws IOException {
8686
// invocation should fail inbound validation and return 400
8787
JsonNode validJsonNode = objectMapper.readTree(invocationResult.getResult());
8888
assertThat(validJsonNode.get("statusCode").asInt()).isEqualTo(400);
89-
assertThat(validJsonNode.get("body").asText()).contains("$.price: is missing but it is required");
89+
assertThat(validJsonNode.get("body").asText()).contains(": required property 'price' not found");
9090
}
9191

9292
@Test
@@ -102,6 +102,6 @@ void test_invalidOutboundApiGWEvent() throws IOException {
102102
JsonNode validJsonNode = objectMapper.readTree(invocationResult.getResult());
103103
assertThat(validJsonNode.get("statusCode").asInt()).isEqualTo(400);
104104
assertThat(validJsonNode.get("body").asText())
105-
.contains("$.price: must have an exclusive maximum value of 1000");
105+
.contains("/price: must have an exclusive maximum value of 1000");
106106
}
107107
}

powertools-validation/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<dependency>
6666
<groupId>com.networknt</groupId>
6767
<artifactId>json-schema-validator</artifactId>
68-
<version>1.0.87</version>
68+
<version>1.4.3</version>
6969
</dependency>
7070
<dependency>
7171
<groupId>com.amazonaws</groupId>

powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ public SpecVersion.VersionFlag getSchemaVersion() {
4747
}
4848

4949
/**
50-
* Set the version of the json schema specifications (default is V7)
50+
* Set the version of the json schema specifications to use if $schema is not
51+
* explicitly specified within the schema (default is V7). If $schema is
52+
* explicitly specified within the schema is explicitly specified within the
53+
* schema, the validator will use the specified dialect.
5154
*
5255
* @param version May be V4, V6, V7, V201909 or V202012
56+
* @see <a href=
57+
* "https://json-schema.org/understanding-json-schema/reference/schema#declaring-a-dialect">Declaring
58+
* a Dialect</a>
5359
*/
5460
public void setSchemaVersion(SpecVersion.VersionFlag version) {
5561
if (version != jsonSchemaVersion) {

powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java

+10-13
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@
2121
import com.fasterxml.jackson.databind.node.JsonNodeType;
2222
import com.fasterxml.jackson.databind.node.NullNode;
2323
import com.networknt.schema.JsonSchema;
24+
import com.networknt.schema.SchemaLocation;
2425
import com.networknt.schema.SchemaValidatorsConfig;
2526
import com.networknt.schema.ValidationMessage;
26-
import com.networknt.schema.uri.URITranslator;
2727
import io.burt.jmespath.Expression;
2828
import java.io.ByteArrayOutputStream;
29-
import java.io.InputStream;
3029
import java.util.Collections;
3130
import java.util.Map;
3231
import java.util.Set;
3332
import java.util.concurrent.ConcurrentHashMap;
3433
import java.util.stream.Collectors;
35-
import software.amazon.lambda.powertools.validation.internal.ValidationAspect;
3634

3735
/**
3836
* Validation utility, used to manually validate Json against Json Schema
@@ -255,27 +253,26 @@ public static JsonSchema getJsonSchema(String schema, boolean validateSchema) {
255253

256254
private static JsonSchema createJsonSchema(String schema) {
257255
JsonSchema jsonSchema;
256+
SchemaValidatorsConfig config = SchemaValidatorsConfig.builder().formatAssertionsEnabled(true)
257+
.preloadJsonSchemaRefMaxNestingDepth(10).build();
258258
if (schema.startsWith(CLASSPATH)) {
259-
String filePath = schema.substring(CLASSPATH.length());
260-
try (InputStream schemaStream = ValidationAspect.class.getResourceAsStream(filePath)) {
261-
262-
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
263-
config.addUriTranslator(URITranslator.prefix("https://json-schema.org", "resource:"));
264-
265-
jsonSchema = ValidationConfig.get().getFactory().getSchema(schemaStream, config);
259+
try {
260+
jsonSchema = ValidationConfig.get().getFactory().getSchema(SchemaLocation.of(schema), config);
266261
} catch (Exception e) {
262+
String filePath = schema.substring(CLASSPATH.length());
267263
throw new IllegalArgumentException(
268-
"'" + schema + "' is invalid, verify '" + filePath + "' is in your classpath");
264+
"'" + schema + "' is invalid, verify '" + filePath + "' is in your classpath", e);
269265
}
270266
} else {
271-
jsonSchema = ValidationConfig.get().getFactory().getSchema(schema);
267+
jsonSchema = ValidationConfig.get().getFactory().getSchema(schema, config);
272268
}
273269

274270
return jsonSchema;
275271
}
276272

277273
private static void validateSchema(String schema, JsonSchema jsonSchema) {
278-
String schemaId = ValidationConfig.get().getSchemaVersion().getId().replace("https://json-schema.org", "");
274+
String schemaId = jsonSchema.getValidationContext().getMetaSchema().getIri()
275+
.replace("https://json-schema.org", "").replace("http://json-schema.org", "");
279276
try {
280277
validate(jsonSchema.getSchemaNode(),
281278
getJsonSchema(CLASSPATH + schemaId));

powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public void testLoadSchemaV7OK() {
4848
ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V7);
4949
JsonSchema jsonSchema = getJsonSchema("classpath:/schema_v7.json", true);
5050
assertThat(jsonSchema).isNotNull();
51-
assertThat(jsonSchema.getCurrentUri()).asString().isEqualTo("http://example.com/product.json");
51+
assertThat(jsonSchema.getId()).isEqualTo("http://example.com/product.json");
5252
}
5353

5454
@Test
@@ -57,7 +57,7 @@ public void testLoadSchemaV7KO() {
5757
assertThatThrownBy(() -> getJsonSchema("classpath:/schema_v7_ko.json", true))
5858
.isInstanceOf(IllegalArgumentException.class)
5959
.hasMessage(
60-
"The schema classpath:/schema_v7_ko.json is not valid, it does not respect the specification /draft-07/schema");
60+
"The schema classpath:/schema_v7_ko.json is not valid, it does not respect the specification /draft-07/schema#");
6161
}
6262

6363
@Test

powertools-validation/src/test/resources/schema_v7.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "http://json-schema.org/draft-07/schema",
2+
"$schema": "http://json-schema.org/draft-07/schema#",
33
"$id": "http://example.com/product.json",
44
"type": "object",
55
"title": "Product schema",

powertools-validation/src/test/resources/schema_v7_ko.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "http://json-schema.org/draft-07/schema",
2+
"$schema": "http://json-schema.org/draft-07/schema#",
33
"type": "object",
44
"title": "Product schema",
55
"description": "JSON schema to validate Products",

0 commit comments

Comments
 (0)