'How can I use SwaggerValidator(com.atlassian.oai.validator) to validate a simple JSON without request or response?

I have the following need: Input is a JSON object got from a messaging (or Kafka) queue. My need to is to validate the above JSON message against a Swagger specification. I am not able to find any reliable solution to converting swagger to JSON schema, and so I decided to see if could use the com.atlassian.oai.validator for achieving this.

However, the challenge is that in just using the core validator, we are forced to formulate a request/response in the strict sense, but all I want is a JSON schema like validation (primarily the JSON structure, data contents, etc.). How can I achieve this using this validator?

Sample code is as below:

private static final String SWAGGER_JSON_URL = "http://petstore.swagger.io/v2/swagger.json";
String inputJSON = "{"
                + "  \"id\": 1,"
                + "  \"category\": {"
                + "    \"id\": 0,"
                + "    \"name\": \"string\""
                + "  },"
                + "  \"name\": \"doggie\","
                + "  \"photoUrls\": ["
                + "    \"string\""
                + "  ],"
                + "  \"tags\": ["
                + "    {"
                + "      \"id\": 2,"
                + "      \"name\": \"string\""
                + "    }"
                + "  ],"
                + "  \"status\": \"available\""
                + "}";
OpenApiInteractionValidator validator =
    OpenApiInteractionValidator.createFor(SWAGGER_JSON_URL).build();

How can I call the validator.validate and provide the inputJSON as a parameter?

I tried the following by creating a simpleresponse to see if that would help, but again I did not find a way to call the validateResponse method as it was insisting on many parameters that I do not have:

final Response response = SimpleResponse.Builder.ok()
                .withContentType("application/json")
                .withBody(inputJSON)
                .build();
ValidationReport report = validator.validateResponse(response);

Am I using the wrong thing to achieve my want? Is there another solution for achieving this?



Solution 1:[1]

I am not sure there's a way to avoid having to formulate an validator.model.* Request objects out of your http request inputs, since OpenApi can only create a proper validation report from validaor.model objects. You can however create validator.model objects in a filter and then register the filter to intercept any request hitting your endpoint.

@Provider
public class RequestValidationFilter implements Filter {

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    //Create validator from openapi spec
    final OpenApiInteractionValidator validator = OpenApiInteractionValidator
            .createForSpecificationUrl("./openapi.json")
            .build();
    HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;

    //create openapi validator object from incoming request
    SimpleRequest.Builder builder = new SimpleRequest.Builder(httpRequest.getMethod(), httpRequest.getRequestURI(), false);
    if (Objects.nonNull(httpRequest.getInputStream())) {
        String jsonRequest = IOUtils.toString(httpRequest.getInputStream(), Charsets.UTF_8);
        builder.withBody(jsonRequest);
    }

    //build validation report
    final ValidationReport report = validator.validateRequest(builder.build());

    // return error message back if report shows error, else continue processing request
    if (report.hasErrors()) {
        String msg = JsonValidationReportFormat.getInstance().apply(report);
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        httpServletResponse.reset();
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON);
        httpServletResponse.setStatus(Response.Status.BAD_REQUEST.getStatusCode());
        httpServletResponse.getOutputStream().write(msg.getBytes(StandardCharsets.UTF_8));
        httpServletResponse.getOutputStream().flush();
    } else {
        filterChain.doFilter(servletRequest, servletResponse);
    }
}}

The imports:

import com.atlassian.oai.validator.OpenApiInteractionValidator;
import com.atlassian.oai.validator.model.SimpleRequest;
import com.atlassian.oai.validator.report.JsonValidationReportFormat;
import com.atlassian.oai.validator.report.ValidationReport;
import javax.servlet.*;
import javax.ws.rs.ext.Provider;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1