@Override public boolean matches(final Message message, final ApiOperation operation, final Request request) { if (operation == null || operation.getOperation().getRequestBody() == null) { return false; } final RequestBody apiRequestBody = operation.getOperation().getRequestBody(); // TODO: This should really respect the content-type of the response to filter schemas return apiRequestBody.getContent().values().stream() .map(MediaType::getSchema) .filter(Objects::nonNull) .map(Schema::get$ref) .filter(Objects::nonNull) .anyMatch($ref -> $ref.endsWith("/" + entityName)); }
@Nonnull private ValidationReport validatePathParameter(final ApiOperation apiOperation, final String paramName, final Optional<String> paramValue) { return defaultIfNull(apiOperation.getOperation().getParameters(), Collections.<Parameter>emptyList()) .stream() .filter(RequestValidator::isPathParam) .filter(p -> p.getName().equalsIgnoreCase(paramName)) .findFirst() .map(p -> parameterValidator.validate(paramValue.orElse(null), p)) .orElse(empty()); }
@Nonnull private Collection<String> getProduces(final ApiOperation apiOperation) { return apiOperation.getOperation() .getResponses() .values() .stream() .filter(apiResponse -> apiResponse.getContent() != null) .flatMap(apiResponse -> apiResponse.getContent().keySet().stream()) .collect(Collectors.toSet()); }
@Nullable private ApiResponse getApiResponse(final Response response, final ApiOperation apiOperation) { final ApiResponse apiResponse = apiOperation.getOperation().getResponses().get(Integer.toString(response.getStatus())); if (apiResponse == null) { return apiOperation.getOperation().getResponses().getDefault(); } return apiResponse; } }
@Nonnull private Collection<String> getConsumes(final ApiOperation apiOperation) { if (apiOperation.getOperation().getRequestBody() == null) { return emptyList(); } return defaultIfNull(apiOperation.getOperation().getRequestBody().getContent().keySet(), emptySet()); }
@Override public boolean matches(final Message message, final ApiOperation operation, final Response response) { if (operation == null || operation.getOperation().getResponses() == null) { return false; } final ApiResponse apiResponse = getApiResponse(response, operation); if (apiResponse == null) { return false; } // TODO: This should really respect the content-type of the response to filter schemas return apiResponse.getContent().values().stream() .map(MediaType::getSchema) .filter(Objects::nonNull) .map(Schema::get$ref) .filter(Objects::nonNull) .anyMatch($ref -> $ref.endsWith("/" + entityName)); }
@Nullable private ApiResponse getApiResponse(final Response response, final ApiOperation apiOperation) { final ApiResponse apiResponse = apiOperation.getOperation().getResponses().get(Integer.toString(response.getStatus())); if (apiResponse == null) { return apiOperation.getOperation().getResponses().get("default"); // try the default response } return apiResponse; }
@Nonnull private ValidationReport validateQueryParameters(final Request request, final ApiOperation apiOperation) { return defaultIfNull(apiOperation.getOperation().getParameters(), Collections.<Parameter>emptyList()) .stream() .filter(RequestValidator::isQueryParam) .map(p -> validateParameter( apiOperation, p, request.getQueryParameterValues(p.getName()), "validation.request.parameter.query.missing") ) .reduce(empty(), ValidationReport::merge); }
@Nonnull private ValidationReport validateHeaders(final Request request, final ApiOperation apiOperation) { return defaultIfNull(apiOperation.getOperation().getParameters(), Collections.<Parameter>emptyList()) .stream() .filter(RequestValidator::isHeaderParam) .map(p -> validateParameter( apiOperation, p, request.getHeaderValues(p.getName()), "validation.request.parameter.header.missing") ) .reduce(empty(), ValidationReport::merge); }
@Nonnull public ValidationReport validateSecurity(final Request request, final ApiOperation apiOperation) { final List<SecurityRequirement> securityRequired = apiOperation.getOperation().getSecurity();
/** * Validate the request against the given API operation * * @param request The request to validate * @param apiOperation The operation to validate the request against * * @return A validation report containing validation errors */ @Nonnull public ValidationReport validateRequest(final Request request, final ApiOperation apiOperation) { requireNonNull(request, "A request is required"); requireNonNull(apiOperation, "An API operation is required"); final MessageContext context = MessageContext.create() .in(REQUEST) .withApiOperation(apiOperation) .withRequestPath(apiOperation.getRequestPath().original()) .withRequestMethod(request.getMethod()) .build(); return securityValidator.validateSecurity(request, apiOperation) .merge(validateContentType(request, apiOperation)) .merge(validateAccepts(request, apiOperation)) .merge(validateHeaders(request, apiOperation)) .merge(validatePathParameters(apiOperation)) .merge(requestBodyValidator.validateRequestBody(request, apiOperation.getOperation().getRequestBody())) .merge(validateQueryParameters(request, apiOperation)) .withAdditionalContext(context); }