Additional Schema Files are always checked against the OpenAPI Schema
Closed this issue · 3 comments
Version
4.5.9
Context
I tried to split my OpenAPI document across multiple files by extracting some larger schema definitions to their separate files. To allow loading these files, I added them as additionalContractFiles in the call to OpenAPIContract.from. This fails because the additional files are validated against the full OpenAPI 3.1.0 specification, while they contain a simple JSON Schema.
In my opinion, the parser should offer the opportunity to reference arbitrary files, as long as the resulting schema is aligned with the OpenAPI specification.
Steps to reproduce
Here's a minimal schema to reproduce this:
openapi/openapi.yaml
openapi: 3.1.0
info:
title: My Service
version: 1.0.0
tags: []
paths:
/v1/post:
post:
summary: Some POST request
operationId: postBody
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RequestBody'
responses:
200:
description: Success
default:
description: An unexpected error occurred
components:
schemas:
RequestBody:
type: object
properties:
name:
description: The unique name of the object
$ref: 'schemas/Name.yaml'openapi/schemas/Name.yaml
$schema: https://spec.openapis.org/oas/3.1/dialect/base
description: A case-insensitive string of 1-255 characters, serving as a name (unique identifier)
type: string
minLength: 1
maxLength: 255Parsing the Contract
Map<String, String> additional = new HashMap<>();
additional.put("schemas/Name.yaml", "openapi/schemas/Name.yaml");
Future<OpenAPIContract> contract = OpenAPIContract.from(vertx, "openapi/openapi.yaml", additional).onFailure(t -> t.printStackTrace());results in
Exception in thread "main" io.vertx.openapi.contract.OpenAPIContractException: The passed OpenAPI contract is invalid: Found issue in specification for reference: schemas/Name.yaml
at io.vertx.openapi.contract.OpenAPIContractException.createInvalidContract(OpenAPIContractException.java:34)
at io.vertx.openapi.contract.OpenAPIContract.lambda$null$4(OpenAPIContract.java:123)
at io.vertx.core.impl.future.Mapping.onSuccess(Mapping.java:35)
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:60)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "maxLength" does not match unevaluated properties schema
at [#/unevaluatedProperties].<#/maxLength>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "minLength" does not match unevaluated properties schema
at [#/unevaluatedProperties].<#/minLength>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "type" does not match unevaluated properties schema
at [#/unevaluatedProperties].<#/type>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "description" does not match unevaluated properties schema
at [#/unevaluatedProperties].<#/description>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "$schema" does not match unevaluated properties schema
at [#/unevaluatedProperties].<#/$schema>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "info"
at [#/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "openapi"
... 1 more
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "webhooks"
at [#/anyOf/2/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/2/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "components"
at [#/anyOf/1/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/1/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "paths"
at [#/anyOf/0/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/0/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not match any subschemas
at [#/anyOf].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf)
Thanks @Traderjoe95 for this issue. I think it is related to #16 which @pk-work did some work on. His branch 4_x_issue_16 had the changes. I'll check later today/this week if this solves your issue too (or feel free to checkout the branch yourself and test locally, it may just be out of date with the latest).
@Traderjoe95 I've rebased and made a few additional changes. I've created a unit test using your reproducer (1). It is passing now, but there is 1 thing with your spec that you may have to change:
From:
$ref: 'schemas/Name.yaml'To:
$ref: 'https://schemas/Name.yaml'and when creating the contract:
From:
Map<String, String> additional = new HashMap<>();
additional.put("schemas/Name.yaml", "name.yaml");To:
Map<String, String> additional = new HashMap<>();
additional.put("https://schemas/Name.yaml", "name.yaml");This is just a small quark in the underlying json schema. If no URL schema (https://) is provided a basic one (app:///) is prepended.
Fixed in #78