com.atlassian.oai.validator.springmvc.OpenApiValidationService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swagger-request-validator-springmvc Show documentation
Show all versions of swagger-request-validator-springmvc Show documentation
OpenAPI / Swagger validation for Spring MVC.
package com.atlassian.oai.validator.springmvc;
import com.atlassian.oai.validator.OpenApiInteractionValidator;
import com.atlassian.oai.validator.model.Request;
import com.atlassian.oai.validator.model.Response;
import com.atlassian.oai.validator.model.SimpleRequest;
import com.atlassian.oai.validator.model.SimpleResponse;
import com.atlassian.oai.validator.report.ValidationReport;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Objects.requireNonNull;
class OpenApiValidationService {
private final OpenApiInteractionValidator validator;
OpenApiValidationService(final EncodedResource specUrlOrPayload) throws IOException {
this(OpenApiInteractionValidator
.createFor(readReader(specUrlOrPayload.getReader(), -1))
.withLevelResolver(SpringMVCLevelResolverFactory.create())
.build());
}
OpenApiValidationService(final OpenApiInteractionValidator validator) {
requireNonNull(validator, "An OpenAPI validator is required.");
this.validator = validator;
}
/**
* @param servletRequest the {@link HttpServletRequest}
*
* @return the build {@link Request} created out of given {@link HttpServletRequest}
*
* @throws IOException if the request body can't be read
*/
Request buildRequest(final HttpServletRequest servletRequest) throws IOException {
requireNonNull(servletRequest, "A request is required.");
final Request.Method method = Request.Method.valueOf(servletRequest.getMethod());
final String path = servletRequest.getServletPath();
final SimpleRequest.Builder builder = new SimpleRequest.Builder(method, path);
final int contentLength = servletRequest.getContentLength();
final String body = readReader(servletRequest.getReader(), contentLength);
// The content length of a request does not need to be set. It might by "-1" and
// there is still a body. Only in conjunction with an empty / unset body it was
// really empty.
if (contentLength >= 0 || StringUtils.isNotEmpty(body)) {
builder.withBody(body);
}
for (final String queryParameterName : getQueryParameterNames(servletRequest)) {
builder.withQueryParam(queryParameterName, servletRequest.getParameterValues(queryParameterName));
}
for (final String headerName : Collections.list(servletRequest.getHeaderNames())) {
builder.withHeader(headerName, Collections.list(servletRequest.getHeaders(headerName)));
}
return builder.build();
}
/**
* @param servletResponse the {@link javax.servlet.http.HttpServletResponse} whose body is cached
*
* @return the build {@link Response} created out of given {@link ContentCachingResponseWrapper}
*
* @throws IOException if the cached response body can't be read
*/
Response buildResponse(final ContentCachingResponseWrapper servletResponse) throws IOException {
final int statusCode = servletResponse.getStatusCode();
final SimpleResponse.Builder builder =
new SimpleResponse.Builder(statusCode)
.withBody(new String(servletResponse.getContentAsByteArray(), servletResponse.getCharacterEncoding()))
.withContentType(servletResponse.getContentType());
for (final String headerName : servletResponse.getHeaderNames()) {
builder.withHeader(headerName, Lists.newArrayList(servletResponse.getHeaders(headerName)));
}
return builder.build();
}
/**
* @param request the {@link Request} to validate against the OpenAPI / Swagger specification
*
* @return the {@link ValidationReport} for the validated {@link Request}
*/
ValidationReport validateRequest(final Request request) {
return validator.validateRequest(request);
}
/**
* @param servletRequest the {@link HttpServletRequest} to examine the api path to validate against
* @param response the {@link Response} to validate against the OpenAPI / Swagger specification
*
* @return the {@link ValidationReport} for the validated {@link Request}
*/
ValidationReport validateResponse(final HttpServletRequest servletRequest,
final Response response) {
final Request.Method method = Request.Method.valueOf(servletRequest.getMethod());
final String path = servletRequest.getServletPath();
return validator.validateResponse(path, method, response);
}
private static String readReader(final Reader reader, final int length) throws IOException {
try (Reader reassignedReader = reader) {
final StringWriter writer = length > 0 ? new StringWriter(length) : new StringWriter();
IOUtils.copy(reassignedReader, writer);
return writer.toString();
}
}
private static Set getQueryParameterNames(final HttpServletRequest servletRequest) {
return Stream.of(StringUtils.split(StringUtils.defaultIfBlank(servletRequest.getQueryString(), ""), "&"))
.map(str -> StringUtils.split(str, "=")[0])
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toSet());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy