@Override
    public ValidationResponse validate(ValidationRequest req) {

        if (req.isEmptyQuery()) {
            return ValidationResponse.ok();
        }

        try {
            final ParsedQuery parsedQuery = luceneQueryParser.parse(req.rawQuery());

            final ValidationContext context = ValidationContext.builder()
                    .request(req)
                    .query(parsedQuery)
                    .availableFields(fields.fieldTypesByStreamIds(req.streams(), req.timerange()))
                    .build();

            final List<ValidationMessage> explanations = validators.stream()
                    .flatMap(val -> val.validate(context).stream())
                    .collect(Collectors.toList());

            return ValidationResponse.withDetectedStatus(explanations);

        } catch (Exception e) {
            return ValidationResponse.error(ValidationErrors.create(e));
        }
    }
@Test
    void validateWithWarning() {
        // validator returns one warning
        final QueryValidator queryValidator = context -> Collections.singletonList(
                ValidationMessage.builder(ValidationStatus.WARNING, ValidationType.INVALID_OPERATOR)
                        .errorMessage("Invalid operator detected")
                        .build());

        final QueryValidationServiceImpl service = new QueryValidationServiceImpl(
                LUCENE_QUERY_PARSER,
                FIELD_TYPES_SERVICE,
                Collections.singleton(queryValidator));

        final ValidationResponse validationResponse = service.validate(req());

        assertThat(validationResponse.status()).isEqualTo(ValidationStatus.WARNING);
        assertThat(validationResponse.explanations())
                .hasOnlyOneElementSatisfying(message -> {
                    assertThat(message.validationType()).isEqualTo(ValidationType.INVALID_OPERATOR);
                    assertThat(message.validationStatus()).isEqualTo(ValidationStatus.WARNING);
                });
    }