From 8b15f85b0c3badfba7b7677c4b74522fda219f45 Mon Sep 17 00:00:00 2001 From: Pascal Krause Date: Tue, 20 Jun 2023 16:09:50 +0200 Subject: [PATCH] feat(web-validation): replace deprecated SchemaParser with new SchemaRepository Signed-off-by: Pascal Krause --- .../java/examples/ApiCodegenExamples.java | 32 +-- .../service/RouteToEBServiceHandlerTest.java | 36 ++-- .../RouteToEBServiceFuturesHandlerTest.java | 11 +- .../src/main/asciidoc/index.adoc | 19 +- .../java/examples/WebValidationExamples.java | 52 +++-- .../ext/web/validation/ValidationHandler.java | 22 ++- .../ext/web/validation/builder/Bodies.java | 31 +-- .../builder/BodyProcessorFactory.java | 6 +- .../builder/ParameterProcessorFactory.java | 6 +- .../web/validation/builder/Parameters.java | 143 +++++++++----- .../StyledParameterProcessorFactory.java | 6 +- .../builder/ValidationHandlerBuilder.java | 45 ++++- .../builder/impl/ValidationDSLUtils.java | 185 ++++++++++-------- .../impl/ValidationHandlerBuilderImpl.java | 22 +-- .../impl/body/FormBodyProcessorImpl.java | 23 ++- .../impl/body/JsonBodyProcessorImpl.java | 22 ++- .../impl/body/TextPlainBodyProcessorImpl.java | 22 ++- .../impl/parameter/ParameterProcessor.java | 17 +- .../parameter/ParameterProcessorImpl.java | 32 ++- .../validation/BaseValidationHandlerTest.java | 9 +- ...ationHandlerPredicatesIntegrationTest.java | 12 +- ...ationHandlerProcessorsIntegrationTest.java | 154 ++++++++------- .../impl/FormBodyProcessorImplTest.java | 23 ++- .../impl/JsonBodyProcessorImplTest.java | 39 ++-- .../ParameterProcessorIntegrationTest.java | 21 +- .../impl/ParameterProcessorUnitTest.java | 54 +++-- .../impl/TextPlainBodyProcessorTest.java | 17 +- .../src/test/resources/int_schema.json | 5 - 28 files changed, 639 insertions(+), 427 deletions(-) delete mode 100644 vertx-web-validation/src/test/resources/int_schema.json diff --git a/vertx-web-api-service/src/main/java/examples/ApiCodegenExamples.java b/vertx-web-api-service/src/main/java/examples/ApiCodegenExamples.java index 20ea0ccb85..616c3d307b 100644 --- a/vertx-web-api-service/src/main/java/examples/ApiCodegenExamples.java +++ b/vertx-web-api-service/src/main/java/examples/ApiCodegenExamples.java @@ -15,7 +15,7 @@ import io.vertx.ext.web.handler.HttpException; import io.vertx.ext.web.validation.ValidationHandler; import io.vertx.ext.web.validation.builder.ValidationHandlerBuilder; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; import io.vertx.serviceproxy.ServiceBinder; import static io.vertx.ext.web.validation.builder.Bodies.json; @@ -29,7 +29,8 @@ @Source public class ApiCodegenExamples { - public void mountHandler(EventBus eventBus, Router router, ValidationHandler validationHandler) { + public void mountHandler(EventBus eventBus, Router router, + ValidationHandler validationHandler) { router .get("/hello") .handler(validationHandler) @@ -39,33 +40,38 @@ public void mountHandler(EventBus eventBus, Router router, ValidationHandler val ); } - public void mountHandlerWithTimeout(EventBus eventBus, Router router, ValidationHandler validationHandler) { + public void mountHandlerWithTimeout(EventBus eventBus, Router router, + ValidationHandler validationHandler) { router .get("/hello") .handler(validationHandler) .handler( RouteToEBServiceHandler - .build(eventBus, "greeters.myapplication", "hello", new DeliveryOptions().setSendTimeout(1000)) + .build(eventBus, "greeters.myapplication", "hello", + new DeliveryOptions().setSendTimeout(1000)) ); } - public void serviceMountExample(EventBus eventBus, Router router, SchemaParser schemaParser) { + public void serviceMountExample(EventBus eventBus, Router router, + SchemaRepository repository) { router.get("/api/transactions") .handler( - ValidationHandlerBuilder.create(schemaParser) + ValidationHandlerBuilder.create(repository) .queryParameter(optionalParam("from", stringSchema())) .queryParameter(optionalParam("to", stringSchema())) .build() ).handler( - RouteToEBServiceHandler.build(eventBus, "transactions.myapplication", "getTransactionsList") + RouteToEBServiceHandler.build(eventBus, "transactions.myapplication", + "getTransactionsList") ); router.post("/api/transactions") .handler( - ValidationHandlerBuilder.create(schemaParser) + ValidationHandlerBuilder.create(repository) .body(json(objectSchema())) .build() ).handler( - RouteToEBServiceHandler.build(eventBus, "transactions.myapplication", "putTransaction") + RouteToEBServiceHandler.build(eventBus, "transactions.myapplication", + "putTransaction") ); } @@ -80,7 +86,9 @@ public void serviceMount(Vertx vertx) { .register(TransactionService.class, transactionService); } - public void implGetTransactionsListSuccess(String from, String to, ServiceRequest context, Handler> resultHandler) { + public void implGetTransactionsListSuccess(String from, String to, + ServiceRequest context, + Handler> resultHandler) { // Your business logic resultHandler.handle( Future.succeededFuture( @@ -89,7 +97,9 @@ public void implGetTransactionsListSuccess(String from, String to, ServiceReques ); } - public void implGetTransactionsListFailure(String from, String to, ServiceRequest context, Handler> resultHandler) { + public void implGetTransactionsListFailure(String from, String to, + ServiceRequest context, + Handler> resultHandler) { // Return a failed result resultHandler.handle( Future.failedFuture( diff --git a/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/RouteToEBServiceHandlerTest.java b/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/RouteToEBServiceHandlerTest.java index 4023101e2f..4199fdc2bd 100644 --- a/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/RouteToEBServiceHandlerTest.java +++ b/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/RouteToEBServiceHandlerTest.java @@ -24,8 +24,18 @@ import static io.vertx.ext.web.validation.builder.Bodies.json; import static io.vertx.ext.web.validation.builder.Parameters.param; -import static io.vertx.ext.web.validation.testutils.TestRequest.*; -import static io.vertx.json.schema.draft7.dsl.Schemas.*; +import static io.vertx.ext.web.validation.testutils.TestRequest.bodyResponse; +import static io.vertx.ext.web.validation.testutils.TestRequest.emptyResponse; +import static io.vertx.ext.web.validation.testutils.TestRequest.jsonBodyResponse; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusCode; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusMessage; +import static io.vertx.ext.web.validation.testutils.TestRequest.testRequest; +import static io.vertx.json.schema.draft7.dsl.Schemas.anyOf; +import static io.vertx.json.schema.draft7.dsl.Schemas.arraySchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.intSchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.objectSchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.ref; +import static io.vertx.json.schema.draft7.dsl.Schemas.stringSchema; /** * @author Francesco Guardiani @slinkydeveloper @@ -52,7 +62,7 @@ public void serviceProxyTypedTest(Vertx vertx, VertxTestContext testContext) { .post("/testE/:id") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser) + ValidationHandler.builder(schemaRepo) .pathParameter(param("id", intSchema())) .body(json(objectSchema().property("value", intSchema()))) .build() @@ -64,7 +74,7 @@ public void serviceProxyTypedTest(Vertx vertx, VertxTestContext testContext) { .post("/testF/:id") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser) + ValidationHandler.builder(schemaRepo) .pathParameter(param("id", intSchema())) .body(json( anyOf( @@ -106,7 +116,7 @@ public void serviceProxyDataObjectTest(Vertx vertx, VertxTestContext testContext .post("/test") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser) + ValidationHandler.builder(schemaRepo) .body(json(ref(JsonPointer.fromURI(URI.create("filter.json"))))) .build() ).handler( @@ -135,7 +145,7 @@ public void emptyOperationResultTest(Vertx vertx, VertxTestContext testContext) router .get("/test") .handler( - ValidationHandler.builder(parser).build() + ValidationHandler.builder(schemaRepo).build() ).handler( RouteToEBServiceHandler.build(vertx.eventBus(), "someAddress", "testEmptyServiceResponse") ); @@ -157,7 +167,7 @@ public void authorizedUserTest(Vertx vertx, VertxTestContext testContext) { router .get("/test") .handler( - ValidationHandler.builder(parser).build() + ValidationHandler.builder(schemaRepo).build() ).handler(rc -> { rc.setUser(User.fromName("slinkydeveloper")); // Put user mock into context rc.next(); @@ -183,7 +193,7 @@ public void extraPayloadTest(Vertx vertx, VertxTestContext testContext) { router .get("/test") .handler( - ValidationHandler.builder(parser).build() + ValidationHandler.builder(schemaRepo).build() ).handler( RouteToEBServiceHandler .build(vertx.eventBus(), "someAddress", "extraPayload") @@ -210,7 +220,7 @@ public void serviceProxyManualFailureTest(Vertx vertx, VertxTestContext testCont .post("/testFailure") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser) + ValidationHandler.builder(schemaRepo) .body(json( objectSchema() .requiredProperty("hello", stringSchema()) @@ -227,7 +237,7 @@ public void serviceProxyManualFailureTest(Vertx vertx, VertxTestContext testCont .post("/testException") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser) + ValidationHandler.builder(schemaRepo) .body(json( objectSchema() .requiredProperty("hello", stringSchema()) @@ -262,14 +272,14 @@ public void binaryDataTest(Vertx vertx, VertxTestContext testContext) { .get("/test") .handler(BodyHandler.create()) .handler( - ValidationHandler.builder(parser).build() + ValidationHandler.builder(schemaRepo).build() ).handler( RouteToEBServiceHandler.build(vertx.eventBus(), "someAddress", "binaryTest") ); testRequest(client, HttpMethod.GET, "/test") .expect(statusCode(200), statusMessage("OK")) - .expect(bodyResponse(Buffer.buffer(new byte[] {(byte) 0xb0}), "application/octet-stream")) + .expect(bodyResponse(Buffer.buffer(new byte[]{(byte) 0xb0}), "application/octet-stream")) .send(testContext, checkpoint); } @@ -284,7 +294,7 @@ public void authorizationPropagationTest(Vertx vertx, VertxTestContext testConte router .get("/test") .handler( - ValidationHandler.builder(parser).build() + ValidationHandler.builder(schemaRepo).build() ).handler(rc -> { // patch the request to include authorization header rc.request().headers().add(HttpHeaders.AUTHORIZATION, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); diff --git a/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/futures/RouteToEBServiceFuturesHandlerTest.java b/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/futures/RouteToEBServiceFuturesHandlerTest.java index 9ee137d62b..420ae61a66 100644 --- a/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/futures/RouteToEBServiceFuturesHandlerTest.java +++ b/vertx-web-api-service/src/test/java/io/vertx/ext/web/api/service/futures/RouteToEBServiceFuturesHandlerTest.java @@ -17,7 +17,10 @@ import org.junit.jupiter.api.extension.ExtendWith; import static io.vertx.ext.web.validation.builder.Parameters.param; -import static io.vertx.ext.web.validation.testutils.TestRequest.*; +import static io.vertx.ext.web.validation.testutils.TestRequest.jsonBodyResponse; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusCode; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusMessage; +import static io.vertx.ext.web.validation.testutils.TestRequest.testRequest; import static io.vertx.json.schema.draft7.dsl.Schemas.intSchema; @SuppressWarnings("unchecked") @@ -42,7 +45,7 @@ public void serviceProxyTypedTestWithRequestParameter(final Vertx vertx, final V router .post("/testFutureWithRequestParameter/:param") .handler(BodyHandler.create()) - .handler(ValidationHandler.builder(parser).pathParameter(param("param", intSchema())).build()) + .handler(ValidationHandler.builder(schemaRepo).pathParameter(param("param", intSchema())).build()) .handler( RouteToEBServiceHandler.build(vertx.eventBus(), "someAddress", "testFutureWithRequestParameter")); @@ -63,7 +66,7 @@ public void serviceProxyTypedTestWithIntParameter(final Vertx vertx, final Vertx router .post("/testFutureWithIntParameter/:param") .handler(BodyHandler.create()) - .handler(ValidationHandler.builder(parser).pathParameter(param("param", intSchema())).build()) + .handler(ValidationHandler.builder(schemaRepo).pathParameter(param("param", intSchema())).build()) .handler( RouteToEBServiceHandler.build(vertx.eventBus(), "someAddress", "testFutureWithIntParameter")); @@ -84,7 +87,7 @@ public void serviceProxyTypedTest(final Vertx vertx, final VertxTestContext test router .post("/testFuture") .handler(BodyHandler.create()) - .handler(ValidationHandler.builder(parser).build()) + .handler(ValidationHandler.builder(schemaRepo).build()) .handler( RouteToEBServiceHandler.build(vertx.eventBus(), "someAddress", "testFuture")); diff --git a/vertx-web-validation/src/main/asciidoc/index.adoc b/vertx-web-validation/src/main/asciidoc/index.adoc index eb027f19b8..d156e17894 100644 --- a/vertx-web-validation/src/main/asciidoc/index.adoc +++ b/vertx-web-validation/src/main/asciidoc/index.adoc @@ -57,22 +57,21 @@ Vert.x Web Validation provides an easy to use API to build an handler that perfo == Creating the `ValidationHandler` This module provides an easy to use builder API to create your {@link io.vertx.ext.web.validation.ValidationHandler}, the {@link io.vertx.core.Handler} that performs the parsing and validation of the request. -To create this builder use {@link io.vertx.ext.web.validation.builder.ValidationHandlerBuilder#create(SchemaParser)}. -The provided {@link io.vertx.json.schema.SchemaParser} will be used to parse all schemas created with https://vertx.io/docs/vertx-json-schema/$lang/[Vert.x Json Schema DSL] +To create this builder use {@link io.vertx.ext.web.validation.builder.ValidationHandlerBuilder#create(SchemaRepository)}. === Defining parameters You can define parameters located in four different locations of your request: query, cookie, header, path. -Every parameter is represented by a {@link io.vertx.ext.web.validation.impl.parameter.ParameterProcessor}, -that you can easily create with methods provided in {@link io.vertx.ext.web.validation.builder.Parameters}: +Every parameter is represented by a {@link io.vertx.ext.web.validation.impl.parameter.ParameterProcessor}, that you can easily create with methods provided in {@link io.vertx.ext.web.validation.builder.Parameters}: [source,$lang] ---- {@link examples.WebValidationExamples#parameters} ---- -Note that all these methods requires a schema that validator can use to perform the validation. The schema is also used to infer the correct parser +Note that all these methods requires a schema that validator can use to perform the validation. +The schema is also used to infer the correct parser While header and path parameters allows only simple parameters, query and cookie allows complex parameters like exploded and deep object: @@ -85,8 +84,7 @@ For more info on all available parameters, look at {@link io.vertx.ext.web.valid === Defining request bodies -Every body type is represented by a {@link io.vertx.ext.web.validation.impl.parameter.ParameterProcessor} -and matches with request body using `Content-type` header. +Every body type is represented by a {@link io.vertx.ext.web.validation.impl.parameter.ParameterProcessor} and matches with request body using `Content-type` header. You can define one or multiple bodies that the `ValidationHandler` should manage. If no matching body processor is found, the validation **won't** fail unless you specified the body required predicate explained below @@ -98,8 +96,8 @@ You can easily create these processor with methods provided in {@link io.vertx.e ---- In this example the `ValidationHandler` will be able to manage two different body types that consistently parse and validate. -In particular the form body will be converted to a json object. When you retrieve the parsed result, you don't need to care -if the request body was a form or a json +In particular the form body will be converted to a json object. +When you retrieve the parsed result, you don't need to care if the request body was a form or a json For more info on all available body processors, look at {@link io.vertx.ext.web.validation.builder.Bodies} documentation. @@ -133,8 +131,7 @@ The `ValidationHandler` will place the parsed values into {@link io.vertx.ext.we == Manage the failures -Every time a `ValidationHandler` encounters both a parsing or a validation failure, it fails the `RoutingContext` with 400 status code and -an instance of a subclass of {@link io.vertx.ext.web.validation.BadRequestException} as cause. +Every time a `ValidationHandler` encounters both a parsing or a validation failure, it fails the `RoutingContext` with 400 status code and an instance of a subclass of {@link io.vertx.ext.web.validation.BadRequestException} as cause. To learn how to manage failures, look at https://vertx.io/docs/vertx-web/java/#_error_handling[Vert.x Web doc] and {@link io.vertx.ext.web.Router#errorHandler(int,Handler)} method. The possible subclasses of {@link io.vertx.ext.web.validation.BadRequestException} are: diff --git a/vertx-web-validation/src/main/java/examples/WebValidationExamples.java b/vertx-web-validation/src/main/java/examples/WebValidationExamples.java index 06cd454866..efc47054c8 100644 --- a/vertx-web-validation/src/main/java/examples/WebValidationExamples.java +++ b/vertx-web-validation/src/main/java/examples/WebValidationExamples.java @@ -4,15 +4,24 @@ import io.vertx.core.json.JsonObject; import io.vertx.docgen.Source; import io.vertx.ext.web.Router; -import io.vertx.ext.web.validation.*; +import io.vertx.ext.web.validation.BadRequestException; +import io.vertx.ext.web.validation.BodyProcessorException; +import io.vertx.ext.web.validation.ParameterProcessorException; +import io.vertx.ext.web.validation.RequestParameters; +import io.vertx.ext.web.validation.RequestPredicate; +import io.vertx.ext.web.validation.RequestPredicateException; +import io.vertx.ext.web.validation.ValidationHandler; import io.vertx.ext.web.validation.builder.Bodies; import io.vertx.ext.web.validation.builder.Parameters; import io.vertx.ext.web.validation.builder.ValidationHandlerBuilder; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; import static io.vertx.ext.web.validation.builder.Parameters.param; -import static io.vertx.json.schema.common.dsl.Schemas.*; +import static io.vertx.json.schema.common.dsl.Schemas.arraySchema; +import static io.vertx.json.schema.common.dsl.Schemas.intSchema; +import static io.vertx.json.schema.common.dsl.Schemas.objectSchema; +import static io.vertx.json.schema.common.dsl.Schemas.stringSchema; import static io.vertx.json.schema.draft7.dsl.Keywords.maximum; @Source @@ -47,12 +56,12 @@ public void withoutWebValidation(Router router) { }); } - public void withWebValidation(Router router, SchemaParser schemaParser) { + public void withWebValidation(Router router, SchemaRepository schemaRepository) { router .get("/user") .handler( ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .queryParameter(param( "aParam", intSchema().with(maximum(100)) @@ -60,33 +69,34 @@ public void withWebValidation(Router router, SchemaParser schemaParser) { .build() ) .handler(routingContext -> { - RequestParameters parameters = routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY); + RequestParameters parameters = + routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY); int aParam = parameters.queryParameter("aParam").getInteger(); // Business logic to process the request }); } - public void parameters(SchemaParser schemaParser) { + public void parameters(SchemaRepository schemaRepository) { ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .pathParameter(Parameters.param("myPathParam", stringSchema())) .queryParameter(Parameters.optionalParam("myQueryParam", intSchema())); } - public void bodies(SchemaParser schemaParser) { + public void bodies(SchemaRepository schemaRepository) { ObjectSchemaBuilder bodySchemaBuilder = objectSchema() .property("username", stringSchema()) .property("password", stringSchema()); ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .body(Bodies.json(bodySchemaBuilder)) .body(Bodies.formUrlEncoded(bodySchemaBuilder)); } - public void parametersComplex(SchemaParser schemaParser) { + public void parametersComplex(SchemaRepository schemaRepository) { ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .queryParameter(Parameters.explodedParam( "myArray", arraySchema().items(stringSchema()) @@ -98,29 +108,30 @@ public void parametersComplex(SchemaParser schemaParser) { )); // Accepts myDeepObject[name]=francesco } - public void requestBodyRequired(SchemaParser schemaParser) { + public void requestBodyRequired(SchemaRepository schemaRepository) { ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .predicate(RequestPredicate.BODY_REQUIRED); } - public void buildAndMount(Router router, SchemaParser schemaParser) { + public void buildAndMount(Router router, SchemaRepository schemaRepository) { router .get("/user") .handler( ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .build() ); } - public void useParameters(Router router, SchemaParser schemaParser, ObjectSchemaBuilder objectBodySchemaBuilder) { + public void useParameters(Router router, SchemaRepository schemaRepository, + ObjectSchemaBuilder objectBodySchemaBuilder) { router .get("/user") .handler( ValidationHandlerBuilder - .create(schemaParser) + .create(schemaRepository) .queryParameter(Parameters.explodedParam( "myArray", arraySchema().items(stringSchema()) @@ -129,7 +140,8 @@ public void useParameters(Router router, SchemaParser schemaParser, ObjectSchema .body(Bodies.formUrlEncoded(objectBodySchemaBuilder)) .build() ).handler(routingContext -> { - RequestParameters parameters = routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY); + RequestParameters parameters = + routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY); JsonArray myArray = parameters.queryParameter("myArray").getJsonArray(); JsonObject body = parameters.body().getJsonObject(); }); @@ -146,7 +158,7 @@ public void manageFailure(Router router) { // A request predicate is unsatisfied } } - }); + }); } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/ValidationHandler.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/ValidationHandler.java index f8f2022dd8..dbfaca9b49 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/ValidationHandler.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/ValidationHandler.java @@ -6,12 +6,15 @@ import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.validation.builder.ValidationHandlerBuilder; import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; /** - * This is the entry point of this module. Provides the parsing, validation and puts the parsed objects into {@link RoutingContext}.
- * - * You can easily build a new validation handler using a {@link ValidationHandlerBuilder}, that you can create with {@link this#builder(SchemaParser)}.
- * + * This is the entry point of this module. Provides the parsing, validation and puts the parsed objects into + * {@link RoutingContext}.
+ *

+ * You can easily build a new validation handler using a {@link ValidationHandlerBuilder}, that you can create with + * {@link ValidationHandlerBuilder#create(SchemaRepository)}.
+ *

* For more info read the doc.
* * @author Francesco Guardiani @slinkydeveloper @@ -22,15 +25,14 @@ public interface ValidationHandler extends Handler { String REQUEST_CONTEXT_KEY = "requestParameters"; /** - * @deprecated This method duplicates the behavior of {@link ValidationHandlerBuilder#create(SchemaParser)}. - * - * @param parser a SchemaParser + * @param schemaParser a SchemaParser * @return an instance of {@link ValidationHandlerBuilder}. + * @deprecated {@link SchemaParser} is deprecated. Please use + * {@link ValidationHandlerBuilder#create(io.vertx.json.schema.SchemaRepository)}. */ @Deprecated @GenIgnore(GenIgnore.PERMITTED_TYPE) - static ValidationHandlerBuilder builder(SchemaParser parser) { - return ValidationHandlerBuilder.create(parser); + static ValidationHandlerBuilder builder(SchemaParser schemaParser) { + return ValidationHandlerBuilder.create(schemaParser); } - } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Bodies.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Bodies.java index bc1c0b5644..8cd3ec2a7f 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Bodies.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Bodies.java @@ -2,20 +2,21 @@ import io.vertx.codegen.annotations.GenIgnore; import io.vertx.codegen.annotations.VertxGen; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.impl.ValueParserInferenceUtils; import io.vertx.ext.web.validation.impl.body.FormBodyProcessorImpl; import io.vertx.ext.web.validation.impl.body.JsonBodyProcessorImpl; import io.vertx.ext.web.validation.impl.body.TextPlainBodyProcessorImpl; -import io.vertx.ext.web.validation.impl.validator.SchemaValidator; -import io.vertx.json.schema.Schema; import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; import io.vertx.json.schema.common.dsl.SchemaBuilder; import io.vertx.json.schema.common.dsl.StringSchemaBuilder; /** - * In this interface you can find all available {@link BodyProcessorFactory} to use in {@link ValidationHandlerBuilder}.
- * - * To create new schemas using {@link SchemaBuilder}, look at the docs of vertx-json-schema + * In this interface you can find all available {@link BodyProcessorFactory} to use in + * {@link ValidationHandlerBuilder}.
+ *

+ * To create new schemas using {@link SchemaBuilder}, look at the + * docs of vertx-json-schema */ @VertxGen public interface Bodies { @@ -28,7 +29,7 @@ public interface Bodies { */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static BodyProcessorFactory json(SchemaBuilder schemaBuilder) { - return parser -> new JsonBodyProcessorImpl(new SchemaValidator(schemaBuilder.build(parser))); + return schemaRepository -> new JsonBodyProcessorImpl(schemaRepository, schemaBuilder.toJson()); } /** @@ -39,7 +40,7 @@ static BodyProcessorFactory json(SchemaBuilder schemaBuilder) { */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static BodyProcessorFactory textPlain(StringSchemaBuilder schemaBuilder) { - return parser -> new TextPlainBodyProcessorImpl(new SchemaValidator(schemaBuilder.build(parser))); + return schemaRepository -> new TextPlainBodyProcessorImpl(schemaRepository, schemaBuilder.toJson()); } /** @@ -50,15 +51,15 @@ static BodyProcessorFactory textPlain(StringSchemaBuilder schemaBuilder) { */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static BodyProcessorFactory formUrlEncoded(ObjectSchemaBuilder schemaBuilder) { - return parser -> { - Schema s = schemaBuilder.build(parser); - Object jsonSchema = s.getJson(); + return schemaRepository -> { + JsonObject jsonSchema = schemaBuilder.toJson(); return new FormBodyProcessorImpl( ValueParserInferenceUtils.infeerPropertiesFormValueParserForObjectSchema(jsonSchema), ValueParserInferenceUtils.infeerPatternPropertiesFormValueParserForObjectSchema(jsonSchema), ValueParserInferenceUtils.infeerAdditionalPropertiesFormValueParserForObjectSchema(jsonSchema), "application/x-www-form-urlencoded", - new SchemaValidator(s) + schemaRepository, + jsonSchema ); }; } @@ -71,15 +72,15 @@ static BodyProcessorFactory formUrlEncoded(ObjectSchemaBuilder schemaBuilder) { */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static BodyProcessorFactory multipartFormData(ObjectSchemaBuilder schemaBuilder) { - return parser -> { - Schema s = schemaBuilder.build(parser); - Object jsonSchema = s.getJson(); + return schemaRepository -> { + JsonObject jsonSchema = schemaBuilder.toJson(); return new FormBodyProcessorImpl( ValueParserInferenceUtils.infeerPropertiesFormValueParserForObjectSchema(jsonSchema), ValueParserInferenceUtils.infeerPatternPropertiesFormValueParserForObjectSchema(jsonSchema), ValueParserInferenceUtils.infeerAdditionalPropertiesFormValueParserForObjectSchema(jsonSchema), "multipart/form-data", - new SchemaValidator(s) + schemaRepository, + jsonSchema ); }; } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/BodyProcessorFactory.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/BodyProcessorFactory.java index 90a35d4ea9..164c4ab9cf 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/BodyProcessorFactory.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/BodyProcessorFactory.java @@ -3,17 +3,17 @@ import io.vertx.codegen.annotations.GenIgnore; import io.vertx.codegen.annotations.VertxGen; import io.vertx.ext.web.validation.impl.body.BodyProcessor; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; /** * This interface is used to build body processors.
- * + *

* Look at {@link Bodies} for all available factories. */ @VertxGen public interface BodyProcessorFactory { @GenIgnore(GenIgnore.PERMITTED_TYPE) - BodyProcessor create(SchemaParser parser); + BodyProcessor create(SchemaRepository schemaRepository); } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ParameterProcessorFactory.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ParameterProcessorFactory.java index 634cbdbeb6..30c0cbf067 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ParameterProcessorFactory.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ParameterProcessorFactory.java @@ -4,12 +4,12 @@ import io.vertx.codegen.annotations.VertxGen; import io.vertx.ext.web.validation.impl.ParameterLocation; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; /** * This interface is used to build parameter processors supported on every {@link ParameterLocation}. * You can use in query and cookie more complex parameters with {@link StyledParameterProcessorFactory}.
- * + *

* Look at {@link Parameters} for all available factories */ @VertxGen @@ -17,6 +17,6 @@ public interface ParameterProcessorFactory { @GenIgnore(GenIgnore.PERMITTED_TYPE) - ParameterProcessor create(ParameterLocation location, SchemaParser jsonSchemaParser); + ParameterProcessor create(ParameterLocation location, SchemaRepository schemaRepo); } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Parameters.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Parameters.java index d84e79548c..19be23121b 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Parameters.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/Parameters.java @@ -6,19 +6,27 @@ import io.vertx.ext.web.validation.impl.parameter.ParameterProcessorImpl; import io.vertx.ext.web.validation.impl.parameter.SingleValueParameterParser; import io.vertx.ext.web.validation.impl.parser.ValueParser; -import io.vertx.ext.web.validation.impl.validator.SchemaValidator; -import io.vertx.json.schema.common.dsl.*; +import io.vertx.json.schema.common.dsl.ArraySchemaBuilder; +import io.vertx.json.schema.common.dsl.BooleanSchemaBuilder; +import io.vertx.json.schema.common.dsl.NumberSchemaBuilder; +import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; +import io.vertx.json.schema.common.dsl.SchemaBuilder; +import io.vertx.json.schema.common.dsl.StringSchemaBuilder; +import io.vertx.json.schema.common.dsl.TupleSchemaBuilder; /** - * In this interface you can find all available {@link ParameterProcessorFactory} to use in {@link ValidationHandlerBuilder}.
- * - * To create new schemas using {@link SchemaBuilder}, look at the docs of vertx-json-schema + * In this interface you can find all available {@link ParameterProcessorFactory} to use in + * {@link ValidationHandlerBuilder}.
+ *

+ * To create new schemas using {@link SchemaBuilder}, look at the + * docs of vertx-json-schema */ @VertxGen public interface Parameters { /** - * Creates a new required number parameter. Depending on the type provided in {@code schemaBuilder}, the parser will parse the number as {@link Long} or {@link Double} + * Creates a new required number parameter. Depending on the type provided in {@code schemaBuilder}, the parser + * will parse the number as {@link Long} or {@link Double} * * @param parameterName * @param schemaBuilder @@ -26,7 +34,7 @@ public interface Parameters { */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory param(String parameterName, NumberSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, false, @@ -34,12 +42,14 @@ static ParameterProcessorFactory param(String parameterName, NumberSchemaBuilder location.lowerCaseIfNeeded(parameterName), schemaBuilder.isIntegerSchema() ? ValueParser.LONG_PARSER : ValueParser.DOUBLE_PARSER ), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } /** - * Creates a new optional number parameter. Depending on the type provided in {@code schemaBuilder}, the parser will parse the number as {@link Long} or {@link Double} + * Creates a new optional number parameter. Depending on the type provided in {@code schemaBuilder}, the parser + * will parse the number as {@link Long} or {@link Double} * * @param parameterName * @param schemaBuilder @@ -47,7 +57,7 @@ static ParameterProcessorFactory param(String parameterName, NumberSchemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory optionalParam(String parameterName, NumberSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, true, @@ -55,7 +65,8 @@ static ParameterProcessorFactory optionalParam(String parameterName, NumberSchem location.lowerCaseIfNeeded(parameterName), schemaBuilder.isIntegerSchema() ? ValueParser.LONG_PARSER : ValueParser.DOUBLE_PARSER ), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -68,12 +79,13 @@ static ParameterProcessorFactory optionalParam(String parameterName, NumberSchem */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory param(String parameterName, StringSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, false, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.NOOP_PARSER), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -86,12 +98,13 @@ static ParameterProcessorFactory param(String parameterName, StringSchemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory optionalParam(String parameterName, StringSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, true, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.NOOP_PARSER), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -104,12 +117,13 @@ static ParameterProcessorFactory optionalParam(String parameterName, StringSchem */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory param(String parameterName, BooleanSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, false, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.BOOLEAN_PARSER), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -122,12 +136,13 @@ static ParameterProcessorFactory param(String parameterName, BooleanSchemaBuilde */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static ParameterProcessorFactory optionalParam(String parameterName, BooleanSchemaBuilder schemaBuilder) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, true, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.BOOLEAN_PARSER), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -242,13 +257,15 @@ static ParameterProcessorFactory optionalParam(String parameterName, ObjectSchem * @return */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static ParameterProcessorFactory param(String parameterName, SchemaBuilder schemaBuilder, ValueParser valueParser) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + static ParameterProcessorFactory param(String parameterName, SchemaBuilder schemaBuilder, + ValueParser valueParser) { + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, false, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), valueParser), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -261,13 +278,15 @@ static ParameterProcessorFactory param(String parameterName, SchemaBuilder schem * @return */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static ParameterProcessorFactory optionalParam(String parameterName, SchemaBuilder schemaBuilder, ValueParser valueParser) { - return (location, jsonSchemaParser) -> new ParameterProcessorImpl( + static ParameterProcessorFactory optionalParam(String parameterName, SchemaBuilder schemaBuilder, + ValueParser valueParser) { + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, true, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), valueParser), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaBuilder.toJson() ); } @@ -280,12 +299,13 @@ static ParameterProcessorFactory optionalParam(String parameterName, SchemaBuild */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static StyledParameterProcessorFactory jsonParam(String parameterName, SchemaBuilder builder) { - return (location, parser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, false, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.JSON_PARSER), - new SchemaValidator(builder.build(parser)) + schemaRepository, + builder.toJson() ); } @@ -298,89 +318,107 @@ static StyledParameterProcessorFactory jsonParam(String parameterName, SchemaBui */ @GenIgnore(GenIgnore.PERMITTED_TYPE) static StyledParameterProcessorFactory optionalJsonParam(String parameterName, SchemaBuilder builder) { - return (location, parser) -> new ParameterProcessorImpl( + return (location, schemaRepository) -> new ParameterProcessorImpl( parameterName, location, true, new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), ValueParser.JSON_PARSER), - new SchemaValidator(builder.build(parser)) + schemaRepository, + builder.toJson() ); } /** - * Creates a required array parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates a required array parameter deserializable using the provided parser factory. Look at {@link Parsers} for + * available parser factories * * @param parameterName * @param arrayParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory serializedParam(String parameterName, ArrayParserFactory arrayParserFactory, ArraySchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory serializedParam(String parameterName, ArrayParserFactory arrayParserFactory, + ArraySchemaBuilder schemaBuilder) { return ValidationDSLUtils.createArrayParamFactory(parameterName, arrayParserFactory, schemaBuilder, false)::apply; } /** - * Creates an optional array parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates an optional array parameter deserializable using the provided parser factory. Look at {@link Parsers} + * for available parser factories * * @param parameterName * @param arrayParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, ArrayParserFactory arrayParserFactory, ArraySchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, + ArrayParserFactory arrayParserFactory, + ArraySchemaBuilder schemaBuilder) { return ValidationDSLUtils.createArrayParamFactory(parameterName, arrayParserFactory, schemaBuilder, true)::apply; } /** - * Creates a required tuple parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates a required tuple parameter deserializable using the provided parser factory. Look at {@link Parsers} for + * available parser factories * * @param parameterName * @param tupleParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory serializedParam(String parameterName, TupleParserFactory tupleParserFactory, TupleSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory serializedParam(String parameterName, TupleParserFactory tupleParserFactory, + TupleSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createTupleParamFactory(parameterName, tupleParserFactory, schemaBuilder, false)::apply; } /** - * Creates an optional tuple parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates an optional tuple parameter deserializable using the provided parser factory. Look at {@link Parsers} + * for available parser factories * * @param parameterName * @param tupleParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, TupleParserFactory tupleParserFactory, TupleSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, + TupleParserFactory tupleParserFactory, + TupleSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createTupleParamFactory(parameterName, tupleParserFactory, schemaBuilder, true)::apply; } /** - * Creates a required object parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates a required object parameter deserializable using the provided parser factory. Look at {@link Parsers} + * for available parser factories * * @param parameterName * @param objectParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory serializedParam(String parameterName, ObjectParserFactory objectParserFactory, ObjectSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory serializedParam(String parameterName, + ObjectParserFactory objectParserFactory, + ObjectSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createObjectParamFactory(parameterName, objectParserFactory, schemaBuilder, false)::apply; } /** - * Creates an optional object parameter deserializable using the provided parser factory. Look at {@link Parsers} for available parser factories + * Creates an optional object parameter deserializable using the provided parser factory. Look at {@link Parsers} + * for available parser factories * * @param parameterName * @param objectParserFactory * @param schemaBuilder */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, ObjectParserFactory objectParserFactory, ObjectSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory optionalSerializedParam(String parameterName, + ObjectParserFactory objectParserFactory, + ObjectSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createObjectParamFactory(parameterName, objectParserFactory, schemaBuilder, true)::apply; } /** - * Creates a required exploded array parameter. Exploded parameters looks like {@code parameterName=item1¶meterName=item2} + * Creates a required exploded array parameter. Exploded parameters looks like {@code parameterName=item1 + * ¶meterName=item2} * * @param parameterName * @param schemaBuilder @@ -392,7 +430,8 @@ static StyledParameterProcessorFactory explodedParam(String parameterName, Array } /** - * Creates an optional exploded array parameter. Exploded parameters looks like {@code parameterName=item1¶meterName=item2} + * Creates an optional exploded array parameter. Exploded parameters looks like {@code parameterName=item1 + * ¶meterName=item2} * * @param parameterName * @param schemaBuilder @@ -404,7 +443,8 @@ static StyledParameterProcessorFactory optionalExplodedParam(String parameterNam } /** - * Creates a required exploded tuple parameter. Exploded parameters looks like {@code parameterName=item1¶meterName=item2} + * Creates a required exploded tuple parameter. Exploded parameters looks like {@code parameterName=item1 + * ¶meterName=item2} * * @param parameterName * @param schemaBuilder @@ -416,7 +456,8 @@ static StyledParameterProcessorFactory explodedParam(String parameterName, Tuple } /** - * Creates an optional exploded tuple parameter. Exploded parameters looks like {@code parameterName=item1¶meterName=item2} + * Creates an optional exploded tuple parameter. Exploded parameters looks like {@code parameterName=item1 + * ¶meterName=item2} * * @param parameterName * @param schemaBuilder @@ -447,12 +488,14 @@ static StyledParameterProcessorFactory explodedParam(String parameterName, Objec * @return */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory optionalExplodedParam(String parameterName, ObjectSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory optionalExplodedParam(String parameterName, + ObjectSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createExplodedObjectParamFactory(parameterName, schemaBuilder, true); } /** - * Creates a required deep object parameter. Deep object parameters looks like {@code parameterName[key1]=value1¶meterName[key2]=value2} + * Creates a required deep object parameter. Deep object parameters looks like {@code parameterName[key1]=value1 + * ¶meterName[key2]=value2} * * @param parameterName * @param schemaBuilder @@ -464,14 +507,16 @@ static StyledParameterProcessorFactory deepObjectParam(String parameterName, Obj } /** - * Creates an optional deep object parameter. Deep object parameters looks like {@code parameterName[key1]=value1¶meterName[key2]=value2} + * Creates an optional deep object parameter. Deep object parameters looks like {@code parameterName[key1]=value1 + * ¶meterName[key2]=value2} * * @param parameterName * @param schemaBuilder * @return */ @GenIgnore(GenIgnore.PERMITTED_TYPE) - static StyledParameterProcessorFactory optionalDeepObjectParam(String parameterName, ObjectSchemaBuilder schemaBuilder) { + static StyledParameterProcessorFactory optionalDeepObjectParam(String parameterName, + ObjectSchemaBuilder schemaBuilder) { return ValidationDSLUtils.createDeepObjectParamFactory(parameterName, schemaBuilder, true); } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/StyledParameterProcessorFactory.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/StyledParameterProcessorFactory.java index 8ed58edaf7..bb8bc99f80 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/StyledParameterProcessorFactory.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/StyledParameterProcessorFactory.java @@ -4,11 +4,11 @@ import io.vertx.codegen.annotations.VertxGen; import io.vertx.ext.web.validation.impl.ParameterLocation; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; /** * This interface is used to build complex parameter processors supported only in cookie & query.
- * + *

* Look at {@link Parameters} for all available factories */ @VertxGen @@ -16,6 +16,6 @@ public interface StyledParameterProcessorFactory { @GenIgnore(GenIgnore.PERMITTED_TYPE) - ParameterProcessor create(ParameterLocation location, SchemaParser parser); + ParameterProcessor create(ParameterLocation location, SchemaRepository repository); } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ValidationHandlerBuilder.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ValidationHandlerBuilder.java index 79a9e2c817..70b244b374 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ValidationHandlerBuilder.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/ValidationHandlerBuilder.java @@ -3,17 +3,29 @@ import io.vertx.codegen.annotations.Fluent; import io.vertx.codegen.annotations.GenIgnore; import io.vertx.codegen.annotations.VertxGen; +import io.vertx.core.Vertx; +import io.vertx.core.file.FileSystem; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.RequestPredicate; import io.vertx.ext.web.validation.ValidationHandler; import io.vertx.ext.web.validation.builder.impl.ValidationHandlerBuilderImpl; import io.vertx.ext.web.validation.impl.ParameterLocation; import io.vertx.ext.web.validation.impl.body.BodyProcessor; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.JsonSchemaOptions; import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; +import io.vertx.json.schema.draft201909.Draft201909SchemaParser; +import io.vertx.json.schema.draft7.Draft7SchemaParser; +import io.vertx.json.schema.openapi3.OpenAPI3SchemaParser; + +import static io.vertx.json.schema.Draft.DRAFT201909; +import static io.vertx.json.schema.Draft.DRAFT7; /** * Builder for a {@link ValidationHandler}.
- * + *

* For more info look the docs */ @VertxGen @@ -66,8 +78,35 @@ public interface ValidationHandlerBuilder { @GenIgnore(GenIgnore.PERMITTED_TYPE) ValidationHandler build(); - static ValidationHandlerBuilder create(SchemaParser parser) { - return new ValidationHandlerBuilderImpl(parser); + static ValidationHandlerBuilder create(SchemaRepository repo) { + return new ValidationHandlerBuilderImpl(repo); } + /** + * @deprecated {@link SchemaParser} is deprecated. Please use + * {@link ValidationHandlerBuilder#create(io.vertx.json.schema.SchemaRepository)}. + */ + @Deprecated + static ValidationHandlerBuilder create(SchemaParser parser) { + FileSystem fs = Vertx.currentContext().owner().fileSystem(); + + if (parser instanceof Draft7SchemaParser) { + // Draft7SchemaParser was using Draft7 + return create(SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7)).preloadMetaSchema(fs)); + } else if (parser instanceof Draft201909SchemaParser) { + // Draft201909SchemaParser was using draft201909 + return create(SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT201909)).preloadMetaSchema(fs)); + } else if (parser instanceof OpenAPI3SchemaParser) { + // OpenAPI3SchemaParser was using Draft7 And Supported only OpenAPI 3.0 + // The baseUri is irrelevant, as it was also not possible before to pass it + SchemaRepository repo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7)).preloadMetaSchema(fs); + // Load the OpenAPI Spec + String ref = "https://spec.openapis.org/oas/3.0/schema/2021-09-28"; + JsonObject raw = new JsonObject(fs.readFileBlocking(ref.substring("https://".length()))); + repo.dereference(ref, JsonSchema.of(raw)); + return create(repo); + } else { + throw new IllegalArgumentException("Passed SchemaParser is not supported"); + } + } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationDSLUtils.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationDSLUtils.java index 9933b84d9f..6ae75a5f0b 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationDSLUtils.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationDSLUtils.java @@ -1,16 +1,22 @@ package io.vertx.ext.web.validation.builder.impl; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.builder.ArrayParserFactory; import io.vertx.ext.web.validation.builder.ObjectParserFactory; import io.vertx.ext.web.validation.builder.StyledParameterProcessorFactory; import io.vertx.ext.web.validation.builder.TupleParserFactory; import io.vertx.ext.web.validation.impl.ParameterLocation; import io.vertx.ext.web.validation.impl.ValueParserInferenceUtils; -import io.vertx.ext.web.validation.impl.parameter.*; +import io.vertx.ext.web.validation.impl.parameter.DeepObjectValueParameterParser; +import io.vertx.ext.web.validation.impl.parameter.ExplodedArrayValueParameterParser; +import io.vertx.ext.web.validation.impl.parameter.ExplodedObjectValueParameterParser; +import io.vertx.ext.web.validation.impl.parameter.ExplodedTupleValueParameterParser; +import io.vertx.ext.web.validation.impl.parameter.ParameterParser; +import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; +import io.vertx.ext.web.validation.impl.parameter.ParameterProcessorImpl; +import io.vertx.ext.web.validation.impl.parameter.SingleValueParameterParser; import io.vertx.ext.web.validation.impl.parser.ValueParser; -import io.vertx.ext.web.validation.impl.validator.SchemaValidator; -import io.vertx.json.schema.Schema; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.common.dsl.ArraySchemaBuilder; import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; import io.vertx.json.schema.common.dsl.TupleSchemaBuilder; @@ -19,125 +25,134 @@ public class ValidationDSLUtils { - public static BiFunction createArrayParamFactory(String parameterName, ArrayParserFactory arrayParserFactory, ArraySchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); - ValueParser parser = arrayParserFactory.newArrayParser( - ValueParserInferenceUtils.infeerItemsParserForArraySchema(s.getJson()) - ); - return new ParameterProcessorImpl( - parameterName, - location, - isOptional, - new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) - ); - }; + public static BiFunction createArrayParamFactory(String parameterName, ArrayParserFactory arrayParserFactory, ArraySchemaBuilder schemaBuilder, boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + ValueParser parser = arrayParserFactory.newArrayParser( + ValueParserInferenceUtils.infeerItemsParserForArraySchema(schemaJson) + ); + return (location, schemaRepository) -> new ParameterProcessorImpl( + parameterName, + location, + isOptional, + new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), + schemaRepository, + schemaJson + ); } - public static BiFunction createTupleParamFactory(String parameterName, TupleParserFactory tupleParserFactory, TupleSchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); - ValueParser parser = tupleParserFactory.newTupleParser( - ValueParserInferenceUtils.infeerTupleParsersForArraySchema(s.getJson()), - ValueParserInferenceUtils.infeerAdditionalItemsParserForArraySchema(s.getJson()) - ); - return new ParameterProcessorImpl( - parameterName, - location, - isOptional, - new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) - ); - }; + public static BiFunction createTupleParamFactory(String parameterName, TupleParserFactory tupleParserFactory, TupleSchemaBuilder schemaBuilder, boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + ValueParser parser = tupleParserFactory.newTupleParser( + ValueParserInferenceUtils.infeerTupleParsersForArraySchema(schemaJson), + ValueParserInferenceUtils.infeerAdditionalItemsParserForArraySchema(schemaJson) + ); + return (location, schemaRepository) -> new ParameterProcessorImpl( + parameterName, + location, + isOptional, + new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), + schemaRepository, + schemaJson + ); } - public static BiFunction createObjectParamFactory(String parameterName, ObjectParserFactory objectParserFactory, ObjectSchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); - ValueParser parser = - objectParserFactory.newObjectParser( - ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(s.getJson()), - ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(s.getJson()), - ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(s.getJson()) - ); - return new ParameterProcessorImpl( - parameterName, - location, - isOptional, - new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + public static BiFunction createObjectParamFactory(String parameterName, ObjectParserFactory objectParserFactory, ObjectSchemaBuilder schemaBuilder, boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + ValueParser parser = + objectParserFactory.newObjectParser( + ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(schemaJson), + ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(schemaJson), + ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(schemaJson) ); - }; + return (location, schemaRepository) -> new ParameterProcessorImpl( + parameterName, + location, + isOptional, + new SingleValueParameterParser(location.lowerCaseIfNeeded(parameterName), parser), + schemaRepository, + schemaJson + ); } - public static StyledParameterProcessorFactory createExplodedArrayParamFactory(String parameterName, ArraySchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); + public static StyledParameterProcessorFactory createExplodedArrayParamFactory(String parameterName, + ArraySchemaBuilder schemaBuilder, + boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + return (location, schemaRepository) -> { ParameterParser parser = new ExplodedArrayValueParameterParser( location.lowerCaseIfNeeded(parameterName), - ValueParserInferenceUtils.infeerItemsParserForArraySchema(s.getJson()) + ValueParserInferenceUtils.infeerItemsParserForArraySchema(schemaJson) ); return new ParameterProcessorImpl( parameterName, location, isOptional, parser, - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaJson ); }; } - public static StyledParameterProcessorFactory createExplodedTupleParamFactory(String parameterName, TupleSchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); + public static StyledParameterProcessorFactory createExplodedTupleParamFactory(String parameterName, + TupleSchemaBuilder schemaBuilder, + boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + return (location, schemaRepository) -> { ParameterParser parser = new ExplodedTupleValueParameterParser( location.lowerCaseIfNeeded(parameterName), - ValueParserInferenceUtils.infeerTupleParsersForArraySchema(s.getJson()), - ValueParserInferenceUtils.infeerAdditionalItemsParserForArraySchema(s.getJson()) + ValueParserInferenceUtils.infeerTupleParsersForArraySchema(schemaJson), + ValueParserInferenceUtils.infeerAdditionalItemsParserForArraySchema(schemaJson) ); return new ParameterProcessorImpl( parameterName, location, isOptional, parser, - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + schemaRepository, + schemaJson ); }; } - public static StyledParameterProcessorFactory createExplodedObjectParamFactory(String parameterName, ObjectSchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); - return new ParameterProcessorImpl( + public static StyledParameterProcessorFactory createExplodedObjectParamFactory(String parameterName, + ObjectSchemaBuilder schemaBuilder, + boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + return (location, schemaRepository) -> { + ParameterParser parser = new ExplodedObjectValueParameterParser( parameterName, - location, - isOptional, - new ExplodedObjectValueParameterParser( - parameterName, - ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(s.getJson(), location::lowerCaseIfNeeded), - ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(s.getJson()), - ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(s.getJson()) - ), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(schemaJson, location::lowerCaseIfNeeded), + ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(schemaJson), + ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(schemaJson) ); - }; - } - - public static StyledParameterProcessorFactory createDeepObjectParamFactory(String parameterName, ObjectSchemaBuilder schemaBuilder, boolean isOptional) { - return (location, jsonSchemaParser) -> { - Schema s = schemaBuilder.build(jsonSchemaParser); return new ParameterProcessorImpl( parameterName, location, isOptional, - new DeepObjectValueParameterParser( - parameterName, ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(s.getJson()), - ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(s.getJson()), - ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(s.getJson()) - ), - new SchemaValidator(schemaBuilder.build(jsonSchemaParser)) + parser, + schemaRepository, + schemaJson ); }; } + + public static StyledParameterProcessorFactory createDeepObjectParamFactory(String parameterName, + ObjectSchemaBuilder schemaBuilder, + boolean isOptional) { + JsonObject schemaJson = schemaBuilder.toJson(); + ParameterParser parser = new DeepObjectValueParameterParser( + parameterName, ValueParserInferenceUtils.infeerPropertiesParsersForObjectSchema(schemaJson), + ValueParserInferenceUtils.infeerPatternPropertiesParsersForObjectSchema(schemaJson), + ValueParserInferenceUtils.infeerAdditionalPropertiesParserForObjectSchema(schemaJson) + ); + return (location, schemaRepository) -> new ParameterProcessorImpl( + parameterName, + location, + isOptional, + parser, + schemaRepository, + schemaJson + ); + } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationHandlerBuilderImpl.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationHandlerBuilderImpl.java index 7eb1a05133..05d5dc9cb5 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationHandlerBuilderImpl.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/builder/impl/ValidationHandlerBuilderImpl.java @@ -12,7 +12,7 @@ import io.vertx.ext.web.validation.impl.ValidationHandlerImpl; import io.vertx.ext.web.validation.impl.body.BodyProcessor; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; import java.util.ArrayList; import java.util.HashMap; @@ -22,14 +22,14 @@ public class ValidationHandlerBuilderImpl implements ValidationHandlerBuilder { - SchemaParser jsonSchemaParser; + SchemaRepository schemaRepository; Map> parameterProcessors = new HashMap<>(); List bodyProcessors = new ArrayList<>(); List> predicates = new ArrayList<>(); - public ValidationHandlerBuilderImpl(SchemaParser jsonSchemaParser) { - this.jsonSchemaParser = jsonSchemaParser; + public ValidationHandlerBuilderImpl(SchemaRepository schemaRepository) { + this.schemaRepository = schemaRepository; } @Override @@ -40,37 +40,37 @@ public ValidationHandlerBuilder parameter(ParameterLocation location, ParameterP @Override public ValidationHandlerBuilder queryParameter(StyledParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.QUERY, parameterProcessor.create(ParameterLocation.QUERY, jsonSchemaParser)); + return parameter(ParameterLocation.QUERY, parameterProcessor.create(ParameterLocation.QUERY, schemaRepository)); } @Override public ValidationHandlerBuilder queryParameter(ParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.QUERY, parameterProcessor.create(ParameterLocation.QUERY, jsonSchemaParser)); + return parameter(ParameterLocation.QUERY, parameterProcessor.create(ParameterLocation.QUERY, schemaRepository)); } @Override public ValidationHandlerBuilder pathParameter(ParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.PATH, parameterProcessor.create(ParameterLocation.PATH, jsonSchemaParser)); + return parameter(ParameterLocation.PATH, parameterProcessor.create(ParameterLocation.PATH, schemaRepository)); } @Override public ValidationHandlerBuilder cookieParameter(StyledParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.COOKIE, parameterProcessor.create(ParameterLocation.COOKIE, jsonSchemaParser)); + return parameter(ParameterLocation.COOKIE, parameterProcessor.create(ParameterLocation.COOKIE, schemaRepository)); } @Override public ValidationHandlerBuilder cookieParameter(ParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.COOKIE, parameterProcessor.create(ParameterLocation.COOKIE, jsonSchemaParser)); + return parameter(ParameterLocation.COOKIE, parameterProcessor.create(ParameterLocation.COOKIE, schemaRepository)); } @Override public ValidationHandlerBuilder headerParameter(ParameterProcessorFactory parameterProcessor) { - return parameter(ParameterLocation.HEADER, parameterProcessor.create(ParameterLocation.HEADER, jsonSchemaParser)); + return parameter(ParameterLocation.HEADER, parameterProcessor.create(ParameterLocation.HEADER, schemaRepository)); } @Override public ValidationHandlerBuilder body(BodyProcessorFactory bodyProcessor) { - bodyProcessors.add(bodyProcessor.create(jsonSchemaParser)); + bodyProcessors.add(bodyProcessor.create(schemaRepository)); return this; } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/FormBodyProcessorImpl.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/FormBodyProcessorImpl.java index 90415c6857..c2d5139673 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/FormBodyProcessorImpl.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/FormBodyProcessorImpl.java @@ -11,7 +11,9 @@ import io.vertx.ext.web.validation.RequestParameter; import io.vertx.ext.web.validation.impl.parser.ObjectParser; import io.vertx.ext.web.validation.impl.parser.ValueParser; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.OutputUnit; +import io.vertx.json.schema.SchemaRepository; import java.util.List; import java.util.Map; @@ -20,12 +22,16 @@ public class FormBodyProcessorImpl extends ObjectParser> implements BodyProcessor { private final String contentType; - private final ValueValidator valueValidator; + private final SchemaRepository repo; + private final JsonObject schema; - public FormBodyProcessorImpl(Map>> propertiesParsers, Map>> patternPropertiesParsers, ValueParser> additionalPropertiesParsers, String contentType, ValueValidator valueValidator) { + public FormBodyProcessorImpl(Map>> propertiesParsers, Map>> patternPropertiesParsers, ValueParser> additionalPropertiesParsers, + String contentType, SchemaRepository repo, JsonObject schema) { super(propertiesParsers, patternPropertiesParsers, additionalPropertiesParsers); this.contentType = contentType; - this.valueValidator = valueValidator; + this.repo = repo; + this.schema = schema; } @Override @@ -43,7 +49,14 @@ public Future process(RoutingContext requestContext) { Map.Entry parsed = parseField(key, serialized); if (parsed != null) object.put(parsed.getKey(), parsed.getValue()); } - return valueValidator.validate(object).recover(err -> Future.failedFuture( + return Future.future(p -> { + OutputUnit result = repo.validator(JsonSchema.of(schema)).validate(object); + if (result.getValid()) { + p.complete(RequestParameter.create(object)); + } else { + p.fail(result.toException("")); + } + }).recover(err -> Future.failedFuture( BodyProcessorException.createValidationError(requestContext.parsedHeaders().contentType().value(), err) )); } catch (MalformedValueException e) { diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/JsonBodyProcessorImpl.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/JsonBodyProcessorImpl.java index 26dc8387cc..0864935030 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/JsonBodyProcessorImpl.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/JsonBodyProcessorImpl.java @@ -5,19 +5,24 @@ import io.vertx.core.http.HttpHeaders; import io.vertx.core.json.DecodeException; import io.vertx.core.json.Json; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.impl.Utils; import io.vertx.ext.web.validation.BodyProcessorException; import io.vertx.ext.web.validation.MalformedValueException; import io.vertx.ext.web.validation.RequestParameter; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.OutputUnit; +import io.vertx.json.schema.SchemaRepository; public class JsonBodyProcessorImpl implements BodyProcessor { - private ValueValidator valueValidator; + private final SchemaRepository repo; + private final JsonSchema schema; - public JsonBodyProcessorImpl(ValueValidator valueValidator) { - this.valueValidator = valueValidator; + public JsonBodyProcessorImpl(SchemaRepository repo, JsonObject schema) { + this.schema = JsonSchema.of(schema); + this.repo = repo.dereference(this.schema); } @Override @@ -36,7 +41,14 @@ public Future process(RoutingContext requestContext) { ); } Object json = Json.decodeValue(body); - return valueValidator.validate(json).recover(err -> Future.failedFuture( + return Future.future(p -> { + OutputUnit result = repo.validator(schema).validate(json); + if (result.getValid()) { + p.complete(RequestParameter.create(json)); + } else { + p.fail(result.toException("")); + } + }).recover(err -> Future.failedFuture( BodyProcessorException.createValidationError(requestContext.request().getHeader(HttpHeaders.CONTENT_TYPE), err) )); } catch (DecodeException e) { diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/TextPlainBodyProcessorImpl.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/TextPlainBodyProcessorImpl.java index d9bd679f45..56035d4b6f 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/TextPlainBodyProcessorImpl.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/body/TextPlainBodyProcessorImpl.java @@ -2,18 +2,23 @@ import io.vertx.core.Future; import io.vertx.core.http.HttpHeaders; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.validation.BodyProcessorException; import io.vertx.ext.web.validation.MalformedValueException; import io.vertx.ext.web.validation.RequestParameter; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.OutputUnit; +import io.vertx.json.schema.SchemaRepository; public class TextPlainBodyProcessorImpl implements BodyProcessor { - ValueValidator valueValidator; + private final SchemaRepository repo; + private final JsonObject schema; - public TextPlainBodyProcessorImpl(ValueValidator valueValidator) { - this.valueValidator = valueValidator; + public TextPlainBodyProcessorImpl(SchemaRepository repo, JsonObject schema) { + this.repo = repo; + this.schema = schema; } @Override @@ -30,6 +35,13 @@ public Future process(RoutingContext requestContext) { new MalformedValueException("Null body") ); } - return valueValidator.validate(body); + return Future.future(p -> { + OutputUnit result = repo.validator(JsonSchema.of(schema)).validate(body); + if (result.getValid()) { + p.complete(RequestParameter.create(body)); + } else { + p.fail(result.toException("")); + } + }); } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessor.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessor.java index bed5290bec..5ae9dc953f 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessor.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessor.java @@ -1,9 +1,10 @@ package io.vertx.ext.web.validation.impl.parameter; import io.vertx.core.Future; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.RequestParameter; import io.vertx.ext.web.validation.impl.ParameterLocation; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.SchemaRepository; import java.util.List; import java.util.Map; @@ -23,13 +24,15 @@ public interface ParameterProcessor { * Create a new request parameter processor * * @param parameterName Name of the parameter - * @param location Location of the parameter - * @param isOptional true if is optional - * @param parser parser for the parameter - * @param validator validator for the parameter + * @param location Location of the parameter + * @param isOptional true if is optional + * @param parser parser for the parameter + * @param repo schema repository for the parameter + * @param schema schema for the parameter * @return */ - static ParameterProcessor create(String parameterName, ParameterLocation location, boolean isOptional, ParameterParser parser, ValueValidator validator) { - return new ParameterProcessorImpl(parameterName, location, isOptional, parser, validator); + static ParameterProcessor create(String parameterName, ParameterLocation location, boolean isOptional, + ParameterParser parser, SchemaRepository repo, JsonObject schema) { + return new ParameterProcessorImpl(parameterName, location, isOptional, parser, repo, schema); } } diff --git a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessorImpl.java b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessorImpl.java index addde1b813..4bdd5c9041 100644 --- a/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessorImpl.java +++ b/vertx-web-validation/src/main/java/io/vertx/ext/web/validation/impl/parameter/ParameterProcessorImpl.java @@ -1,15 +1,21 @@ package io.vertx.ext.web.validation.impl.parameter; import io.vertx.core.Future; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.MalformedValueException; import io.vertx.ext.web.validation.RequestParameter; import io.vertx.ext.web.validation.impl.ParameterLocation; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.OutputUnit; +import io.vertx.json.schema.SchemaRepository; import java.util.List; import java.util.Map; +import java.util.Optional; -import static io.vertx.ext.web.validation.ParameterProcessorException.*; +import static io.vertx.ext.web.validation.ParameterProcessorException.createMissingParameterWhenRequired; +import static io.vertx.ext.web.validation.ParameterProcessorException.createParsingError; +import static io.vertx.ext.web.validation.ParameterProcessorException.createValidationError; public class ParameterProcessorImpl implements ParameterProcessor, Comparable { @@ -17,14 +23,17 @@ public class ParameterProcessorImpl implements ParameterProcessor, Comparable process(Map> params) { throw createParsingError(parameterName, location, e); } if (json != null) - return validator.validate(json).recover(t -> Future.failedFuture(createValidationError(parameterName, location, t))); + return Future.future(p -> { + OutputUnit result = repo.validator(JsonSchema.of(schema)).validate(json); + if (result.getValid()) { + p.complete(RequestParameter.create(json)); + } else { + p.fail(result.toException("")); + } + }).recover(t -> Future.failedFuture(createValidationError(parameterName, location, t))); else if (!isOptional) throw createMissingParameterWhenRequired(parameterName, location); else { - return validator.getDefault().map(defaultValue -> null != defaultValue ? RequestParameter.create(defaultValue) : null); + RequestParameter defaultValue = + Optional.ofNullable(schema.getValue("default")).map(RequestParameter::create).orElse(null); + return Future.succeededFuture(defaultValue); } } diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/BaseValidationHandlerTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/BaseValidationHandlerTest.java index 6653d2452f..f7bb9b6268 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/BaseValidationHandlerTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/BaseValidationHandlerTest.java @@ -6,10 +6,11 @@ import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.client.WebClientOptions; import io.vertx.ext.web.validation.testutils.ValidationTestUtils; -import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.Draft; +import io.vertx.json.schema.JsonSchemaOptions; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.SchemaRouter; import io.vertx.json.schema.SchemaRouterOptions; -import io.vertx.json.schema.draft7.Draft7SchemaParser; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.AfterEach; @@ -20,7 +21,7 @@ public abstract class BaseValidationHandlerTest { public SchemaRouter schemaRouter; - public SchemaParser parser; + public SchemaRepository schemaRepo; public Router router; public HttpServer server; public WebClient client; @@ -31,7 +32,7 @@ public void setUp(Vertx vertx, VertxTestContext testContext) { ValidationTestUtils.mountRouterFailureHandler(router); schemaRouter = SchemaRouter.create(vertx, new SchemaRouterOptions()); - parser = Draft7SchemaParser.create(schemaRouter); + schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(Draft.DRAFT7).setBaseUri("app://")); client = WebClient.create(vertx, new WebClientOptions().setDefaultPort(9000).setDefaultHost("localhost")); server = vertx diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerPredicatesIntegrationTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerPredicatesIntegrationTest.java index 5a11bc9c74..e2d5d75413 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerPredicatesIntegrationTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerPredicatesIntegrationTest.java @@ -4,6 +4,7 @@ import io.vertx.core.json.JsonObject; import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.multipart.MultipartForm; +import io.vertx.ext.web.validation.builder.ValidationHandlerBuilder; import io.vertx.junit5.Checkpoint; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; @@ -23,14 +24,13 @@ */ @SuppressWarnings("unchecked") @ExtendWith(VertxExtension.class) -public class ValidationHandlerPredicatesIntegrationTest extends BaseValidationHandlerTest{ +public class ValidationHandlerPredicatesIntegrationTest extends BaseValidationHandlerTest { @Test public void testRequiredBodyPredicate(VertxTestContext testContext, @TempDir Path tempDir) { Checkpoint checkpoint = testContext.checkpoint(3); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .predicate(RequestPredicate.BODY_REQUIRED) .build(); @@ -61,8 +61,7 @@ public void testRequiredBodyPredicate(VertxTestContext testContext, @TempDir Pat public void testFileUploadExists(VertxTestContext testContext, @TempDir Path tempDir) { Checkpoint checkpoint = testContext.checkpoint(4); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .predicate(RequestPredicate.multipartFileUploadExists( "myfile", Pattern.quote("text/plain") @@ -93,7 +92,8 @@ public void testFileUploadExists(VertxTestContext testContext, @TempDir Path tem testRequest(client, HttpMethod.POST, "/testFileUpload") .expect(statusCode(200)) - .sendMultipartForm(MultipartForm.create().textFileUpload("myfile", "myfile.txt", "src/test/resources/myfile.txt", "text/plain"), testContext, checkpoint); + .sendMultipartForm(MultipartForm.create().textFileUpload("myfile", "myfile.txt", "src/test/resources/myfile" + + ".txt", "text/plain"), testContext, checkpoint); } } diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerProcessorsIntegrationTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerProcessorsIntegrationTest.java index 4f74eaf1cf..b770eee179 100755 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerProcessorsIntegrationTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/ValidationHandlerProcessorsIntegrationTest.java @@ -14,7 +14,9 @@ import io.vertx.ext.web.validation.builder.ValidationHandlerBuilder; import io.vertx.ext.web.validation.impl.ParameterLocation; import io.vertx.ext.web.validation.impl.parser.ValueParser; +import io.vertx.json.schema.common.dsl.GenericSchemaBuilder; import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; +import io.vertx.json.schema.common.dsl.SchemaBuilder; import io.vertx.junit5.Checkpoint; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; @@ -26,12 +28,28 @@ import java.nio.file.Path; import java.util.stream.Collectors; -import static io.vertx.ext.web.validation.builder.Parameters.*; -import static io.vertx.ext.web.validation.testutils.TestRequest.*; +import static io.vertx.ext.web.validation.builder.Parameters.explodedParam; +import static io.vertx.ext.web.validation.builder.Parameters.optionalExplodedParam; +import static io.vertx.ext.web.validation.builder.Parameters.optionalParam; +import static io.vertx.ext.web.validation.builder.Parameters.param; +import static io.vertx.ext.web.validation.builder.Parameters.serializedParam; +import static io.vertx.ext.web.validation.testutils.TestRequest.cookie; +import static io.vertx.ext.web.validation.testutils.TestRequest.jsonBodyResponse; +import static io.vertx.ext.web.validation.testutils.TestRequest.requestHeader; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusCode; +import static io.vertx.ext.web.validation.testutils.TestRequest.statusMessage; +import static io.vertx.ext.web.validation.testutils.TestRequest.testRequest; +import static io.vertx.ext.web.validation.testutils.TestRequest.urlEncode; import static io.vertx.ext.web.validation.testutils.ValidationTestUtils.badBodyResponse; import static io.vertx.ext.web.validation.testutils.ValidationTestUtils.badParameterResponse; +import static io.vertx.json.schema.common.dsl.Schemas.intSchema; import static io.vertx.json.schema.draft7.dsl.Keywords.multipleOf; -import static io.vertx.json.schema.draft7.dsl.Schemas.*; +import static io.vertx.json.schema.draft7.dsl.Schemas.arraySchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.booleanSchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.numberSchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.objectSchema; +import static io.vertx.json.schema.draft7.dsl.Schemas.ref; +import static io.vertx.json.schema.draft7.dsl.Schemas.stringSchema; /** * @author Francesco Guardiani @slinkydeveloper @@ -45,7 +63,7 @@ public void testPathParamsSimpleTypes(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .pathParameter(param("a", stringSchema())) .pathParameter(param("b", booleanSchema())) .pathParameter(param("c", intSchema())) @@ -53,13 +71,13 @@ public void testPathParamsSimpleTypes(VertxTestContext testContext) { router.get("/testPathParams/:a/:b/:c") .handler(validationHandler) .handler(routingContext -> { - RequestParameters params = routingContext.get("parsedParameters"); - routingContext - .response() - .setStatusMessage( - params.pathParameter("a").getString() + params.pathParameter("b").getBoolean() + params.pathParameter("c").getInteger() - ).end(); - }); + RequestParameters params = routingContext.get("parsedParameters"); + routingContext + .response() + .setStatusMessage( + params.pathParameter("a").getString() + params.pathParameter("b").getBoolean() + params.pathParameter("c").getInteger() + ).end(); + }); String a = "hello"; String b = "true"; String c = "10"; @@ -83,7 +101,7 @@ public void testQueryParamsSimpleTypes(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(param("param1", booleanSchema())) .queryParameter(param("param2", intSchema())) .build(); @@ -91,11 +109,11 @@ public void testQueryParamsSimpleTypes(VertxTestContext testContext) { .get("/testQueryParams") .handler(validationHandler) .handler(routingContext -> { - RequestParameters params = routingContext.get("parsedParameters"); - routingContext.response().setStatusMessage( - params.queryParameter("param1").getBoolean().toString() + params.queryParameter("param2").getInteger().toString() - ).end(); - }); + RequestParameters params = routingContext.get("parsedParameters"); + routingContext.response().setStatusMessage( + params.queryParameter("param1").getBoolean().toString() + params.queryParameter("param2").getInteger().toString() + ).end(); + }); testRequest(client, HttpMethod.GET, "/testQueryParams?param1=true¶m2=10") .expect(statusCode(200), statusMessage("true10")) .send(testContext, checkpoint); @@ -115,7 +133,7 @@ public void testQueryJsonObjectAsyncParam(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(Parameters.jsonParam("myTree", ref(JsonPointer.fromURI(URI.create("tree_schema.json"))))) .build(); router @@ -157,9 +175,10 @@ public void testQueryParamsAsyncValidation(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(4); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(param("param1", booleanSchema())) - .queryParameter(param("param2", ref(JsonPointer.fromURI(URI.create("int_schema.json"))), ValueParser.LONG_PARSER)) + .queryParameter(param("param2", intSchema().withKeyword("maximum", 10).withKeyword("minimum", 0), + ValueParser.LONG_PARSER)) .build(); router .get("/test") @@ -207,7 +226,7 @@ public void testQueryParamOptional(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(3); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(param("param1", booleanSchema())) .queryParameter(optionalParam("param2", intSchema())) .build(); @@ -244,7 +263,7 @@ public void testQueryParamArrayExploded(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(3); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(explodedParam("parameter", arraySchema().items(intSchema().with(multipleOf(2))) )) @@ -287,7 +306,7 @@ public void testQueryParamArrayCommaSeparated(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(3); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(serializedParam( "parameter", Parsers.commaSeparatedArrayParser(), @@ -333,7 +352,7 @@ public void testQueryParamDefault(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(3); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .queryParameter(optionalParam("param1", intSchema().defaultValue(10))) .queryParameter(param("param2", intSchema())) .build(); @@ -371,7 +390,7 @@ public void testQueryArrayParamsArrayAndPathParam(VertxTestContext testContext) Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .pathParameter(param("pathParam", booleanSchema())) .queryParameter(explodedParam("awesomeArray", arraySchema().items(intSchema()))) .queryParameter(param("anotherParam", numberSchema())) @@ -388,11 +407,13 @@ public void testQueryArrayParamsArrayAndPathParam(VertxTestContext testContext) ).end(); }); - testRequest(client, HttpMethod.GET, "/testQueryParams/true?awesomeArray=1&awesomeArray=2&awesomeArray=3&anotherParam=5.2") + testRequest(client, HttpMethod.GET, "/testQueryParams/true?awesomeArray=1&awesomeArray=2&awesomeArray=3" + + "&anotherParam=5.2") .expect(statusCode(200), statusMessage("true" + new JsonArray().add(1).add(2).add(3).toString() + "5.2")) .send(testContext, checkpoint); - testRequest(client, HttpMethod.GET, "/testQueryParams/true?awesomeArray=1&awesomeArray=bla&awesomeArray=3&anotherParam=5.2") + testRequest(client, HttpMethod.GET, "/testQueryParams/true?awesomeArray=1&awesomeArray=bla&awesomeArray=3" + + "&anotherParam=5.2") .expect(statusCode(400)) .expect(badParameterResponse( ParameterProcessorException.ParameterProcessorErrorType.PARSING_ERROR, @@ -407,7 +428,7 @@ public void testHeaderParamsSimpleTypes(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .headerParameter(param("x-a", stringSchema())) .headerParameter(param("x-b", booleanSchema())) .headerParameter(param("x-c", intSchema())) @@ -419,7 +440,8 @@ public void testHeaderParamsSimpleTypes(VertxTestContext testContext) { routingContext .response() .setStatusMessage(String - .format("%s%s%s", params.headerParameter("x-a"), params.headerParameter("x-b"), params.headerParameter("x-c")) + .format("%s%s%s", params.headerParameter("x-a"), params.headerParameter("x-b"), params.headerParameter("x" + + "-c")) ).end(); }); String a = "hello"; @@ -446,10 +468,11 @@ public void testHeaderParamsAsync(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(4); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .headerParameter(param("x-a", stringSchema())) .headerParameter(param("x-b", booleanSchema())) - .headerParameter(param("x-c", ref(JsonPointer.fromURI(URI.create("int_schema.json"))), ValueParser.LONG_PARSER)) + .headerParameter(param("x-c", intSchema().withKeyword("maximum", 10).withKeyword("minimum", 0), + ValueParser.LONG_PARSER)) .build(); router.get("/test") .handler(validationHandler) @@ -458,7 +481,8 @@ public void testHeaderParamsAsync(VertxTestContext testContext) { routingContext .response() .setStatusMessage(String - .format("%s%s%s", params.headerParameter("x-a"), params.headerParameter("x-b"), params.headerParameter("x-c")) + .format("%s%s%s", params.headerParameter("x-a"), params.headerParameter("x-b"), params.headerParameter("x" + + "-c")) ).end(); }); String a = "hello"; @@ -503,7 +527,7 @@ public void testCookieParamsSimpleTypes(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(2); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .cookieParameter(param("param1", booleanSchema())) .cookieParameter(param("param2", intSchema())) .build(); @@ -549,9 +573,10 @@ public void testCookieParamsAsync(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(3); ValidationHandler validationHandler = ValidationHandlerBuilder - .create(parser) + .create(schemaRepo) .cookieParameter(param("param1", booleanSchema())) - .cookieParameter(param("param2", ref(JsonPointer.fromURI(URI.create("int_schema.json"))), ValueParser.LONG_PARSER)) + .cookieParameter(param("param2", intSchema().withKeyword("maximum", 10).withKeyword("minimum", 0), + ValueParser.LONG_PARSER)) .build(); router .get("/test") @@ -605,11 +630,8 @@ public void testCookieParamsAsync(VertxTestContext testContext) { public void testFormURLEncoded(VertxTestContext testContext, @TempDir Path tempDir) throws Exception { Checkpoint checkpoint = testContext.checkpoint(2); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) - .body( - Bodies.formUrlEncoded(objectSchema().requiredProperty("parameter", intSchema())) - ) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) + .body(Bodies.formUrlEncoded(objectSchema().requiredProperty("parameter", intSchema()))) .build(); router.route().handler(BodyHandler.create(tempDir.toAbsolutePath().toString())); @@ -617,12 +639,12 @@ public void testFormURLEncoded(VertxTestContext testContext, @TempDir Path tempD .post("/testFormParam") .handler(validationHandler) .handler(routingContext -> { - RequestParameters params = routingContext.get("parsedParameters"); - routingContext - .response() - .setStatusMessage(params.body().getJsonObject().getInteger("parameter").toString()) - .end(); - }); + RequestParameters params = routingContext.get("parsedParameters"); + routingContext + .response() + .setStatusMessage(params.body().getJsonObject().getInteger("parameter").toString()) + .end(); + }); testRequest(client, HttpMethod.POST, "/testFormParam") .expect(statusCode(200), statusMessage("5")) @@ -640,11 +662,8 @@ public void testFormURLEncoded(VertxTestContext testContext, @TempDir Path tempD public void testMultipartForm(VertxTestContext testContext, @TempDir Path tempDir) throws Exception { Checkpoint checkpoint = testContext.checkpoint(2); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) - .body( - Bodies.multipartFormData(objectSchema().requiredProperty("parameter", intSchema())) - ) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) + .body(Bodies.multipartFormData(objectSchema().requiredProperty("parameter", intSchema()))) .build(); router.route().handler(BodyHandler.create(tempDir.toAbsolutePath().toString())); @@ -677,8 +696,7 @@ public void testBothFormTypes(VertxTestContext testContext, @TempDir Path tempDi ObjectSchemaBuilder bodySchema = objectSchema().requiredProperty("parameter", intSchema()); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .body(Bodies.multipartFormData(bodySchema)) .body(Bodies.formUrlEncoded(bodySchema)) .build(); @@ -750,8 +768,7 @@ public void testSameResultWithDifferentBodyTypes(VertxTestContext testContext, @ .requiredProperty("string", stringSchema()) .property("array", arraySchema().items(numberSchema())); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .body(Bodies.json(bodySchema)) .body(Bodies.multipartFormData(bodySchema)) .body(Bodies.formUrlEncoded(bodySchema)) @@ -801,20 +818,18 @@ public void testSameResultWithDifferentBodyTypes(VertxTestContext testContext, @ testRequest(client, HttpMethod.POST, "/testFormParam") .expect(statusCode(200)) - .sendJson(expectedResult , testContext, checkpoint); + .sendJson(expectedResult, testContext, checkpoint); } @Test public void testValidationHandlerChaining(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(1); - ValidationHandler validationHandler1 = ValidationHandler - .builder(parser) + ValidationHandler validationHandler1 = ValidationHandlerBuilder.create(schemaRepo) .queryParameter(param("param1", intSchema())) .build(); - ValidationHandler validationHandler2 = ValidationHandler - .builder(parser) + ValidationHandler validationHandler2 = ValidationHandlerBuilder.create(schemaRepo) .queryParameter(param("param2", booleanSchema())) .build(); @@ -830,7 +845,7 @@ public void testValidationHandlerChaining(VertxTestContext testContext) { params.queryParameter("param2").toString() ) .end(); - }); + }); testRequest(client, HttpMethod.GET, "/testHandlersChaining?param1=10¶m2=true") .expect(statusCode(200), statusMessage("10true")) @@ -841,8 +856,7 @@ public void testValidationHandlerChaining(VertxTestContext testContext) { public void testJsonBody(VertxTestContext testContext, @TempDir Path tempDir) { Checkpoint checkpoint = testContext.checkpoint(2); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .body(Bodies.json(objectSchema())) .build(); @@ -873,9 +887,11 @@ public void testJsonBody(VertxTestContext testContext, @TempDir Path tempDir) { public void testJsonBodyAsyncCircular(VertxTestContext testContext, @TempDir Path tempDir) { Checkpoint checkpoint = testContext.checkpoint(2); - ValidationHandler validationHandler1 = ValidationHandler - .builder(parser) - .body(Bodies.json(ref(JsonPointer.fromURI(URI.create("tree_schema.json"))))) + SchemaBuilder childs = arraySchema().items(new GenericSchemaBuilder().withKeyword("$ref", "#")); + SchemaBuilder treeSchema = objectSchema().requiredProperty("value", stringSchema()).property("childs", childs); + + ValidationHandler validationHandler1 = ValidationHandlerBuilder.create(schemaRepo) + .body(Bodies.json(treeSchema)) .build(); JsonObject testObj = new JsonObject() @@ -909,8 +925,7 @@ public void testJsonBodyAsyncCircular(VertxTestContext testContext, @TempDir Pat public void testQueryExpandedObjectAdditionalPropertiesAndDefault(VertxTestContext testContext) { Checkpoint checkpoint = testContext.checkpoint(4); - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .queryParameter(optionalExplodedParam("explodedObject", objectSchema() .property("wellKnownProperty", intSchema()) @@ -953,8 +968,7 @@ public void testQueryExpandedObjectAdditionalPropertiesAndDefault(VertxTestConte @Test public void testSimpleHeaderCaseInsensitivity(VertxTestContext testContext) { - ValidationHandler validationHandler = ValidationHandler - .builder(parser) + ValidationHandler validationHandler = ValidationHandlerBuilder.create(schemaRepo) .headerParameter(param("AnHeader", intSchema())) .build(); diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/FormBodyProcessorImplTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/FormBodyProcessorImplTest.java index 15723d1b95..8ec9ae340a 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/FormBodyProcessorImplTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/FormBodyProcessorImplTest.java @@ -12,11 +12,10 @@ import io.vertx.ext.web.validation.builder.Bodies; import io.vertx.ext.web.validation.impl.body.BodyProcessor; import io.vertx.ext.web.validation.testutils.TestSchemas; -import io.vertx.json.schema.SchemaParser; -import io.vertx.json.schema.SchemaRouter; -import io.vertx.json.schema.SchemaRouterOptions; +import io.vertx.json.schema.Draft; +import io.vertx.json.schema.JsonSchemaOptions; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.common.dsl.ObjectSchemaBuilder; -import io.vertx.json.schema.draft7.Draft7SchemaParser; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.BeforeEach; @@ -32,16 +31,16 @@ @ExtendWith(MockitoExtension.class) class FormBodyProcessorImplTest { - SchemaRouter router; - SchemaParser parser; + private SchemaRepository repository; - @Mock RoutingContext mockedContext; - @Mock HttpServerRequest mockedServerRequest; + @Mock + RoutingContext mockedContext; + @Mock + HttpServerRequest mockedServerRequest; @BeforeEach public void setUp(Vertx vertx) { - router = SchemaRouter.create(vertx, new SchemaRouterOptions()); - parser = Draft7SchemaParser.create(router); + repository = SchemaRepository.create(new JsonSchemaOptions().setDraft(Draft.DRAFT7).setBaseUri("app://")); } @Test @@ -60,7 +59,7 @@ public void testFormBodyProcessor(VertxTestContext testContext) { when(mockedServerRequest.formAttributes()).thenReturn(map); when(mockedContext.request()).thenReturn(mockedServerRequest); - BodyProcessor processor = Bodies.formUrlEncoded(schemaBuilder).create(parser); + BodyProcessor processor = Bodies.formUrlEncoded(schemaBuilder).create(repository); assertThat(processor.canProcess("application/x-www-form-urlencoded")).isTrue(); @@ -100,7 +99,7 @@ public void testFormBodyProcessorParsingFailure(VertxTestContext testContext) { when(mockedServerRequest.formAttributes()).thenReturn(map); when(mockedContext.request()).thenReturn(mockedServerRequest); - BodyProcessor processor = Bodies.formUrlEncoded(schemaBuilder).create(parser); + BodyProcessor processor = Bodies.formUrlEncoded(schemaBuilder).create(repository); assertThat(processor.canProcess("application/x-www-form-urlencoded")).isTrue(); diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/JsonBodyProcessorImplTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/JsonBodyProcessorImplTest.java index cb367cb35f..4710465037 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/JsonBodyProcessorImplTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/JsonBodyProcessorImplTest.java @@ -12,11 +12,10 @@ import io.vertx.ext.web.validation.builder.Bodies; import io.vertx.ext.web.validation.impl.body.BodyProcessor; import io.vertx.ext.web.validation.testutils.TestSchemas; -import io.vertx.json.schema.SchemaParser; -import io.vertx.json.schema.SchemaRouter; -import io.vertx.json.schema.SchemaRouterOptions; +import io.vertx.json.schema.Draft; +import io.vertx.json.schema.JsonSchemaOptions; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.ValidationException; -import io.vertx.json.schema.draft7.Draft7SchemaParser; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.BeforeEach; @@ -33,23 +32,23 @@ @ExtendWith(VertxExtension.class) @ExtendWith(MockitoExtension.class) class JsonBodyProcessorImplTest { + private SchemaRepository repository; - SchemaRouter router; - SchemaParser parser; - - @Mock RoutingContext mockedContext; - @Mock HttpServerRequest mockerServerRequest; - @Mock RequestBody mockerRequestBody; + @Mock + RoutingContext mockedContext; + @Mock + HttpServerRequest mockerServerRequest; + @Mock + RequestBody mockerRequestBody; @BeforeEach public void setUp(Vertx vertx) { - router = SchemaRouter.create(vertx, new SchemaRouterOptions()); - parser = Draft7SchemaParser.create(router); + repository = SchemaRepository.create(new JsonSchemaOptions().setDraft(Draft.DRAFT7).setBaseUri("app://")); } @Test public void testContentTypeCheck() { - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(repository); assertThat(processor.canProcess("application/json")).isTrue(); assertThat(processor.canProcess("application/json; charset=utf-8")).isTrue(); assertThat(processor.canProcess("application/superapplication+json")).isTrue(); @@ -60,7 +59,7 @@ public void testJsonObject(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(TestSchemas.VALID_OBJECT.toBuffer()); - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(repository); processor.process(mockedContext).onComplete(testContext.succeeding(rp -> { testContext.verify(() -> { @@ -81,7 +80,7 @@ public void testInvalidJsonObject(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(TestSchemas.INVALID_OBJECT.toBuffer()); - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER).create(repository); processor.process(mockedContext).onComplete(testContext.failing(err -> { testContext.verify(() -> { @@ -99,7 +98,7 @@ public void testJsonArray(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(TestSchemas.VALID_ARRAY.toBuffer()); - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(repository); processor.process(mockedContext).onComplete(testContext.succeeding(rp -> { testContext.verify(() -> { @@ -120,7 +119,7 @@ public void testInvalidJsonArray(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(TestSchemas.INVALID_ARRAY.toBuffer()); - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(repository); processor.process(mockedContext).onComplete(testContext.failing(err -> { testContext.verify(() -> { @@ -140,7 +139,7 @@ public void testMalformedJson() { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(Buffer.buffer("{\"a")); - BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.json(TestSchemas.SAMPLE_ARRAY_SCHEMA_BUILDER).create(repository); assertThatCode(() -> processor.process(mockedContext)) .isInstanceOf(BodyProcessorException.class) @@ -153,7 +152,7 @@ public void testNull(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(Buffer.buffer("null")); - BodyProcessor processor = Bodies.json(schema().withKeyword("type", "null")).create(parser); + BodyProcessor processor = Bodies.json(schema().withKeyword("type", "null")).create(repository); processor.process(mockedContext).onComplete(testContext.succeeding(rp -> { testContext.verify(() -> { @@ -170,7 +169,7 @@ public void testNullBody() { when(mockedContext.body()).thenReturn(mockerRequestBody); when(mockerRequestBody.buffer()).thenReturn(null); - BodyProcessor processor = Bodies.json(schema().withKeyword("type", "null")).create(parser); + BodyProcessor processor = Bodies.json(schema().withKeyword("type", "null")).create(repository); assertThatCode(() -> processor.process(mockedContext)) .isInstanceOf(BodyProcessorException.class) diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorIntegrationTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorIntegrationTest.java index 19ed089cb0..413d80c54a 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorIntegrationTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorIntegrationTest.java @@ -5,11 +5,10 @@ import io.vertx.ext.web.validation.builder.Parameters; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; import io.vertx.ext.web.validation.testutils.TestSchemas; -import io.vertx.json.schema.SchemaParser; -import io.vertx.json.schema.SchemaRouter; -import io.vertx.json.schema.SchemaRouterOptions; +import io.vertx.json.schema.Draft; +import io.vertx.json.schema.JsonSchemaOptions; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.ValidationException; -import io.vertx.json.schema.draft7.Draft7SchemaParser; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.BeforeEach; @@ -28,20 +27,19 @@ @ExtendWith(MockitoExtension.class) public class ParameterProcessorIntegrationTest { - SchemaRouter router; - SchemaParser parser; + private SchemaRepository repository; + ; @BeforeEach public void setUp(Vertx vertx) { - router = SchemaRouter.create(vertx, new SchemaRouterOptions()); - parser = Draft7SchemaParser.create(router); + repository = SchemaRepository.create(new JsonSchemaOptions().setDraft(Draft.DRAFT7).setBaseUri("app://")); } @Test public void testJsonParam(VertxTestContext testContext) { ParameterProcessor processor = Parameters .jsonParam("myParam", TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER) - .create(ParameterLocation.QUERY, parser); + .create(ParameterLocation.QUERY, repository); Map> map = new HashMap<>(); map.put("myParam", Collections.singletonList(TestSchemas.VALID_OBJECT.encode())); @@ -62,7 +60,7 @@ public void testJsonParam(VertxTestContext testContext) { public void testInvalidJsonParam(VertxTestContext testContext) { ParameterProcessor processor = Parameters .jsonParam("myParam", TestSchemas.SAMPLE_OBJECT_SCHEMA_BUILDER) - .create(ParameterLocation.QUERY, parser); + .create(ParameterLocation.QUERY, repository); Map> map = new HashMap<>(); map.put("myParam", Collections.singletonList(TestSchemas.INVALID_OBJECT.encode())); @@ -71,7 +69,8 @@ public void testInvalidJsonParam(VertxTestContext testContext) { testContext.verify(() -> { assertThat(throwable) .isInstanceOf(ParameterProcessorException.class) - .hasFieldOrPropertyWithValue("errorType", ParameterProcessorException.ParameterProcessorErrorType.VALIDATION_ERROR) + .hasFieldOrPropertyWithValue("errorType", + ParameterProcessorException.ParameterProcessorErrorType.VALIDATION_ERROR) .hasFieldOrPropertyWithValue("location", ParameterLocation.QUERY) .hasFieldOrPropertyWithValue("parameterName", "myParam") .hasCauseInstanceOf(ValidationException.class); diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorUnitTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorUnitTest.java index e60eb92190..ee43f6d2d2 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorUnitTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/ParameterProcessorUnitTest.java @@ -1,18 +1,19 @@ package io.vertx.ext.web.validation.impl; -import io.vertx.core.Future; import io.vertx.core.Vertx; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.validation.MalformedValueException; import io.vertx.ext.web.validation.ParameterProcessorException; -import io.vertx.ext.web.validation.RequestParameter; import io.vertx.ext.web.validation.impl.parameter.ParameterParser; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessor; import io.vertx.ext.web.validation.impl.parameter.ParameterProcessorImpl; -import io.vertx.ext.web.validation.impl.validator.ValueValidator; +import io.vertx.json.schema.JsonSchema; +import io.vertx.json.schema.OutputUnit; import io.vertx.json.schema.SchemaParser; +import io.vertx.json.schema.SchemaRepository; import io.vertx.json.schema.SchemaRouter; import io.vertx.json.schema.SchemaRouterOptions; -import io.vertx.json.schema.ValidationException; +import io.vertx.json.schema.Validator; import io.vertx.json.schema.draft7.Draft7SchemaParser; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; @@ -39,7 +40,11 @@ public class ParameterProcessorUnitTest { @Mock ParameterParser mockedParser; @Mock - ValueValidator mockedValidator; + SchemaRepository mockedSchemaRepository; + @Mock + OutputUnit mockedOutputUnit; + @Mock + Validator mockedValidator; @BeforeEach public void setUp(Vertx vertx) { @@ -54,13 +59,15 @@ public void testRequiredParam() { ParameterLocation.QUERY, false, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject() ); when(mockedParser.parseParameter(any())).thenReturn(null); assertThatCode(() -> processor.process(new HashMap<>())) .isInstanceOf(ParameterProcessorException.class) - .hasFieldOrPropertyWithValue("errorType", ParameterProcessorException.ParameterProcessorErrorType.MISSING_PARAMETER_WHEN_REQUIRED_ERROR) + .hasFieldOrPropertyWithValue("errorType", + ParameterProcessorException.ParameterProcessorErrorType.MISSING_PARAMETER_WHEN_REQUIRED_ERROR) .hasFieldOrPropertyWithValue("location", ParameterLocation.QUERY) .hasFieldOrPropertyWithValue("parameterName", "myParam") .hasNoCause(); @@ -73,11 +80,11 @@ public void testOptionalParam(VertxTestContext testContext) { ParameterLocation.QUERY, true, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject() ); when(mockedParser.parseParameter(any())).thenReturn(null); - when(mockedValidator.getDefault()).thenReturn(Future.succeededFuture()); processor.process(new HashMap<>()).onComplete(testContext.succeeding(value -> { testContext.verify(() -> @@ -95,11 +102,11 @@ public void testOptionalParamWithDefault(VertxTestContext testContext) { ParameterLocation.QUERY, true, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject().put("default", "bla") ); when(mockedParser.parseParameter(any())).thenReturn(null); - when(mockedValidator.getDefault()).thenReturn(Future.succeededFuture("bla")); processor.process(new HashMap<>()).onComplete(testContext.succeeding(value -> { testContext.verify(() -> @@ -116,7 +123,8 @@ public void testParsingFailure() { ParameterLocation.QUERY, false, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject() ); when(mockedParser.parseParameter(any())).thenThrow(new MalformedValueException("bla")); @@ -136,11 +144,15 @@ public void testValidation(VertxTestContext testContext) { ParameterLocation.QUERY, true, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject() ); when(mockedParser.parseParameter(any())).thenReturn("aaa"); - when(mockedValidator.validate(any())).thenReturn(Future.succeededFuture(RequestParameter.create("aaa"))); + + when(mockedSchemaRepository.validator(any(JsonSchema.class))).thenReturn(mockedValidator); + when(mockedValidator.validate(any())).thenReturn(mockedOutputUnit); + when(mockedOutputUnit.getValid()).thenReturn(true); processor.process(new HashMap<>()).onComplete(testContext.succeeding(rp -> { testContext.verify(() -> { @@ -158,20 +170,24 @@ public void testValidationFailure(VertxTestContext testContext) { ParameterLocation.QUERY, true, mockedParser, - mockedValidator + mockedSchemaRepository, + new JsonObject() ); when(mockedParser.parseParameter(any())).thenReturn("aaa"); - when(mockedValidator.validate(any())).thenReturn(Future.failedFuture(ValidationException.createException("aaa", "aaa", "aaa"))); + + when(mockedSchemaRepository.validator(any(JsonSchema.class))).thenReturn(mockedValidator); + when(mockedValidator.validate(any())).thenReturn(mockedOutputUnit); + when(mockedOutputUnit.getValid()).thenReturn(false); processor.process(new HashMap<>()).onComplete(testContext.failing(throwable -> { testContext.verify(() -> { assertThat(throwable) .isInstanceOf(ParameterProcessorException.class) - .hasFieldOrPropertyWithValue("errorType", ParameterProcessorException.ParameterProcessorErrorType.VALIDATION_ERROR) + .hasFieldOrPropertyWithValue("errorType", + ParameterProcessorException.ParameterProcessorErrorType.VALIDATION_ERROR) .hasFieldOrPropertyWithValue("location", ParameterLocation.QUERY) - .hasFieldOrPropertyWithValue("parameterName", "myParam") - .hasCauseInstanceOf(ValidationException.class); + .hasFieldOrPropertyWithValue("parameterName", "myParam"); }); testContext.completeNow(); })); diff --git a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/TextPlainBodyProcessorTest.java b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/TextPlainBodyProcessorTest.java index d57c430730..ee03af6729 100644 --- a/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/TextPlainBodyProcessorTest.java +++ b/vertx-web-validation/src/test/java/io/vertx/ext/web/validation/impl/TextPlainBodyProcessorTest.java @@ -10,10 +10,9 @@ import io.vertx.ext.web.validation.builder.Bodies; import io.vertx.ext.web.validation.impl.body.BodyProcessor; import io.vertx.ext.web.validation.testutils.TestSchemas; -import io.vertx.json.schema.SchemaParser; -import io.vertx.json.schema.SchemaRouter; -import io.vertx.json.schema.SchemaRouterOptions; -import io.vertx.json.schema.draft7.Draft7SchemaParser; +import io.vertx.json.schema.Draft; +import io.vertx.json.schema.JsonSchemaOptions; +import io.vertx.json.schema.SchemaRepository; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.BeforeEach; @@ -30,8 +29,7 @@ @ExtendWith(MockitoExtension.class) public class TextPlainBodyProcessorTest { - SchemaRouter router; - SchemaParser parser; + private SchemaRepository repository; @Mock RoutingContext mockedContext; @@ -42,8 +40,7 @@ public class TextPlainBodyProcessorTest { @BeforeEach public void setUp(Vertx vertx) { - router = SchemaRouter.create(vertx, new SchemaRouterOptions()); - parser = Draft7SchemaParser.create(router); + repository = SchemaRepository.create(new JsonSchemaOptions().setDraft(Draft.DRAFT7).setBaseUri("app://")); } @Test @@ -51,7 +48,7 @@ public void testString(VertxTestContext testContext) { when(mockedContext.body()).thenReturn(mockedRequestBody); when(mockedRequestBody.asString()).thenReturn(TestSchemas.VALID_STRING); - BodyProcessor processor = Bodies.textPlain(TestSchemas.SAMPLE_STRING_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.textPlain(TestSchemas.SAMPLE_STRING_SCHEMA_BUILDER).create(repository); processor.process(mockedContext).onComplete(testContext.succeeding(rp -> { testContext.verify(() -> { @@ -71,7 +68,7 @@ public void testNullBody() { when(mockedContext.request()).thenReturn(mockerServerRequest); when(mockedContext.body()).thenReturn(mockedRequestBody); - BodyProcessor processor = Bodies.textPlain(TestSchemas.SAMPLE_STRING_SCHEMA_BUILDER).create(parser); + BodyProcessor processor = Bodies.textPlain(TestSchemas.SAMPLE_STRING_SCHEMA_BUILDER).create(repository); assertThatCode(() -> processor.process(mockedContext)) .isInstanceOf(BodyProcessorException.class) diff --git a/vertx-web-validation/src/test/resources/int_schema.json b/vertx-web-validation/src/test/resources/int_schema.json deleted file mode 100644 index e7a43cde3f..0000000000 --- a/vertx-web-validation/src/test/resources/int_schema.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "integer", - "maximum": 10, - "minimum": 0 -}