RepreZen / KaiZen-OpenApi-Parser

High-performance Parser, Validator, and Java Object Model for OpenAPI 3.x
130 stars 31 forks source link

ItemsSchema elaboration #230

Open dc950 opened 5 years ago

dc950 commented 5 years ago

I am having issues with finding out if an itemsSchema exists (e.g. for an implicit array type where only the "items:" exists, which as far as I can tell is valid and no validation issues are raised from it).

When an items schema is retrieved from a schema, it will always return a schema, even if the elaborate parameter is set to true.

I'm unclear on if this is intended or a bug, but this makes it hard to distinguish between actual implicit arrays and other types. It can be especially confusing with "not" which seems to do the same thing.

E.g: The following API is valid

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
paths:
  /path:
    get:
      responses:
        '200':
          description: abc
          content:
            application/json:
              schema:
                items:
                  items:
                    not:
                      items:
                        type: string

And the following code is able to recurse through itemsSchema regardless of what "elaborate" is set to:

package com.avaloq.openapi3.testing;

import com.reprezen.kaizen.oasparser.OpenApi3Parser;
import com.reprezen.kaizen.oasparser.model3.OpenApi3;
import com.reprezen.kaizen.oasparser.model3.Schema;
import java.io.File;

public class Main {

  private static final String RESOURCE_URI = "test.yaml";

  public static void main(String[] args) throws Exception {
    processModel(new File("src/main/resources/" + RESOURCE_URI));
  }

  private static void processModel(File modelFile) throws Exception {
    OpenApi3 model = new OpenApi3Parser().parse(modelFile, true);
    model.getValidationItems().forEach(validationItem ->
      System.out.println(validationItem.getSeverity() + ": " + validationItem.getMsg())
    );
    try {
      model.getPaths(false).values().forEach(path ->
        path.getOperations().values().forEach(operation ->
          operation.getResponses().values().forEach(response ->
            response.getContentMediaTypes().values().forEach(mediaType ->
              checkSchema(mediaType.getSchema())
            )
          )
        )
      );
    } catch (NullPointerException e) {
      System.out.println("Null pointer exception");
    }
  }

  private static void checkSchema(Schema schema) {
    int count = 0;
    while(schema != null && count < 100) {
      System.out.println(++count + ": Schema not null");
      schema = schema.getItemsSchema(true); // acts same if false or true
    }
  }
}

Apologies if I am just misunderstanding something or there's an easier way to see if the itemsSchema actually exists.