This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit d892902327a4a27b8fef9b1f35c597357b6ad16b Author: Rene Cordier <rcord...@linagora.com> AuthorDate: Tue Jun 3 13:17:39 2025 +0700 JAMES-4135 Make CriterionConverter into an interface --- .../opensearch/query/CriterionConverter.java | 592 +-------------------- ...nverter.java => DefaultCriterionConverter.java} | 356 ++++++------- .../opensearch/OpenSearchIntegrationTest.java | 6 +- .../OpenSearchNoIndexBodyIntegrationTest.java | 4 +- .../opensearch/OpenSearchQueryStringTest.java | 4 +- .../OpenSearchListeningMessageSearchIndexTest.java | 4 +- .../search/OpenSearchSearchHighlighterTest.java | 4 +- .../opensearch/search/OpenSearchSearcherTest.java | 4 +- .../elasticsearch/host/OpenSearchHostSystem.java | 4 +- .../mailbox/OpenSearchMailboxMappingModule.java | 5 + .../DistributedThreadGetMethodTest.java | 4 +- .../james/webadmin/routes/MailboxesRoutesTest.java | 4 +- .../webadmin/routes/UserMailboxesRoutesTest.java | 4 +- 13 files changed, 204 insertions(+), 791 deletions(-) diff --git a/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java b/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java index 3753da0e32..3457acb1f7 100644 --- a/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java +++ b/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java @@ -19,597 +19,9 @@ package org.apache.james.mailbox.opensearch.query; -import static org.apache.james.backends.opensearch.IndexCreationFactory.RAW; -import static org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration.DEFAULT_TEXT_FUZZINESS_SEARCH; - -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Stream; - -import jakarta.inject.Inject; -import jakarta.mail.Flags; - -import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.model.SearchQuery.Criterion; -import org.apache.james.mailbox.model.SearchQuery.HeaderOperator; -import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; -import org.apache.james.mailbox.opensearch.json.JsonMessageConstants; -import org.apache.james.mailbox.store.search.mime.HeaderCollection; -import org.opensearch.client.json.JsonData; -import org.opensearch.client.opensearch._types.FieldValue; -import org.opensearch.client.opensearch._types.query_dsl.BoolQuery; -import org.opensearch.client.opensearch._types.query_dsl.ChildScoreMode; -import org.opensearch.client.opensearch._types.query_dsl.MatchAllQuery; -import org.opensearch.client.opensearch._types.query_dsl.MatchQuery; -import org.opensearch.client.opensearch._types.query_dsl.NestedQuery; -import org.opensearch.client.opensearch._types.query_dsl.Operator; import org.opensearch.client.opensearch._types.query_dsl.Query; -import org.opensearch.client.opensearch._types.query_dsl.QueryStringQuery; -import org.opensearch.client.opensearch._types.query_dsl.RangeQuery; -import org.opensearch.client.opensearch._types.query_dsl.SimpleQueryStringQuery; -import org.opensearch.client.opensearch._types.query_dsl.TermQuery; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.CharMatcher; -import com.google.common.collect.ImmutableList; - -public class CriterionConverter { - - public static final CharMatcher QUERY_STRING_CONTROL_CHAR = CharMatcher.anyOf("()\"~-|*"); - private final Map<Class<?>, Function<Criterion, Query>> criterionConverterMap; - private final Map<Class<?>, BiFunction<String, HeaderOperator, Query>> headerOperatorConverterMap; - private final String textFuzzinessSearchValue; - private final boolean useQueryStringQuery; - - @Inject - public CriterionConverter(OpenSearchMailboxConfiguration openSearchMailboxConfiguration) { - this.criterionConverterMap = new HashMap<>(); - this.headerOperatorConverterMap = new HashMap<>(); - this.textFuzzinessSearchValue = evaluateFuzzinessValue(openSearchMailboxConfiguration.textFuzzinessSearchEnable()); - this.useQueryStringQuery = openSearchMailboxConfiguration.isUseQueryStringQuery(); - - registerCriterionConverters(); - registerHeaderOperatorConverters(); - } - - @VisibleForTesting - public CriterionConverter() { - this.criterionConverterMap = new HashMap<>(); - this.headerOperatorConverterMap = new HashMap<>(); - this.textFuzzinessSearchValue = evaluateFuzzinessValue(DEFAULT_TEXT_FUZZINESS_SEARCH); - this.useQueryStringQuery = false; - - registerCriterionConverters(); - registerHeaderOperatorConverters(); - } - - private String evaluateFuzzinessValue(boolean textFuzzinessSearchEnable) { - if (textFuzzinessSearchEnable) { - return "AUTO"; - } - return "0"; - } - - private void registerCriterionConverters() { - registerCriterionConverter(SearchQuery.FlagCriterion.class, this::convertFlag); - registerCriterionConverter(SearchQuery.UidCriterion.class, this::convertUid); - registerCriterionConverter(SearchQuery.MessageIdCriterion.class, this::convertMessageId); - registerCriterionConverter(SearchQuery.ConjunctionCriterion.class, this::convertConjunction); - registerCriterionConverter(SearchQuery.HeaderCriterion.class, this::convertHeader); - registerCriterionConverter(SearchQuery.SubjectCriterion.class, this::convertSubject); - registerCriterionConverter(SearchQuery.TextCriterion.class, this::convertTextCriterion); - registerCriterionConverter(SearchQuery.CustomFlagCriterion.class, this::convertCustomFlagCriterion); - - registerCriterionConverter(SearchQuery.AllCriterion.class, - criterion -> new MatchAllQuery.Builder().build().toQuery()); - - registerCriterionConverter(SearchQuery.ModSeqCriterion.class, - criterion -> createNumericFilter(JsonMessageConstants.MODSEQ, criterion.getOperator())); - - registerCriterionConverter(SearchQuery.SizeCriterion.class, - criterion -> createNumericFilter(JsonMessageConstants.SIZE, criterion.getOperator())); - - registerCriterionConverter(SearchQuery.InternalDateCriterion.class, - criterion -> dateRangeFilter(JsonMessageConstants.DATE, criterion.getOperator())); - - registerCriterionConverter(SearchQuery.SaveDateCriterion.class, - criterion -> dateRangeFilter(JsonMessageConstants.SAVE_DATE, criterion.getOperator())); - - registerCriterionConverter(SearchQuery.AttachmentCriterion.class, this::convertAttachmentCriterion); - registerCriterionConverter(SearchQuery.MimeMessageIDCriterion.class, this::convertMimeMessageIDCriterion); - registerCriterionConverter(SearchQuery.ThreadIdCriterion.class, this::convertThreadIdCriterion); - } - - @SuppressWarnings("unchecked") - private <T extends Criterion> void registerCriterionConverter(Class<T> type, Function<T, Query> f) { - criterionConverterMap.put(type, (Function<Criterion, Query>) f); - } - - private void registerHeaderOperatorConverters() { - registerHeaderOperatorConverter( - SearchQuery.ExistsOperator.class, - (headerName, operator) -> new NestedQuery.Builder() - .path(JsonMessageConstants.HEADERS) - .query(new TermQuery.Builder() - .field(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.NAME) - .value(new FieldValue.Builder().stringValue(headerName).build()) - .build() - .toQuery()) - .scoreMode(ChildScoreMode.Avg) - .build() - .toQuery()); - - registerHeaderOperatorConverter( - SearchQuery.AddressOperator.class, - (headerName, operator) -> manageAddressFields(headerName, operator.getAddress())); - - registerHeaderOperatorConverter( - SearchQuery.DateOperator.class, - (headerName, operator) -> dateRangeFilter(JsonMessageConstants.SENT_DATE, operator)); - - registerHeaderOperatorConverter( - SearchQuery.ContainsOperator.class, - (headerName, operator) -> new NestedQuery.Builder() - .path(JsonMessageConstants.HEADERS) - .query(new BoolQuery.Builder() - .must(new TermQuery.Builder() - .field(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.NAME) - .value(new FieldValue.Builder().stringValue(headerName).build()) - .build() - .toQuery()) - .must(new MatchQuery.Builder() - .field(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.VALUE) - .query(new FieldValue.Builder().stringValue(operator.getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery()) - .scoreMode(ChildScoreMode.Avg) - .build() - .toQuery()); - } - - @SuppressWarnings("unchecked") - private <T extends HeaderOperator> void registerHeaderOperatorConverter(Class<T> type, BiFunction<String, T, Query> f) { - headerOperatorConverterMap.put(type, (BiFunction<String, HeaderOperator, Query>) f); - } - - public Query convertCriterion(Criterion criterion) { - return criterionConverterMap.get(criterion.getClass()).apply(criterion); - } - - private Query convertAttachmentCriterion(SearchQuery.AttachmentCriterion criterion) { - return new TermQuery.Builder() - .field(JsonMessageConstants.HAS_ATTACHMENT) - .value(new FieldValue.Builder().booleanValue(criterion.getOperator().isSet()).build()) - .build() - .toQuery(); - } - - private Query convertMimeMessageIDCriterion(SearchQuery.MimeMessageIDCriterion criterion) { - return new TermQuery.Builder() - .field(JsonMessageConstants.MIME_MESSAGE_ID) - .value(new FieldValue.Builder().stringValue(criterion.getMessageID()).build()) - .build() - .toQuery(); - } - - private Query convertThreadIdCriterion(SearchQuery.ThreadIdCriterion criterion) { - return new TermQuery.Builder() - .field(JsonMessageConstants.THREAD_ID) - .value(new FieldValue.Builder().stringValue(criterion.getThreadId().serialize()).build()) - .build() - .toQuery(); - } - - private Query convertCustomFlagCriterion(SearchQuery.CustomFlagCriterion criterion) { - Query termQuery = new TermQuery.Builder() - .field(JsonMessageConstants.USER_FLAGS) - .value(new FieldValue.Builder().stringValue(criterion.getFlag()).build()) - .build() - .toQuery(); - if (criterion.getOperator().isSet()) { - return termQuery; - } else { - return new BoolQuery.Builder() - .mustNot(termQuery) - .build() - .toQuery(); - } - } - - private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) { - switch (textCriterion.getType()) { - case BODY: - if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { - return new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY)) - .query(textCriterion.getOperator().getValue()) - .build().toQuery(); - } else { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.TEXT_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.HTML_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .build() - .toQuery(); - } - case FULL: - if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { - return new BoolQuery.Builder() - .should(new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY, JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) - .query(textCriterion.getOperator().getValue()) - .build().toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } else { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.TEXT_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.HTML_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - case ATTACHMENTS: - if (useQueryStringQuery) { - return new BoolQuery.Builder() - .should(new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) - .query(textCriterion.getOperator().getValue()) - .build().toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } else { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - case ATTACHMENT_FILE_NAME: - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILENAME) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - default: - throw new RuntimeException("Unknown SCOPE for text criterion"); - } - } - - private Query dateRangeFilter(String field, SearchQuery.DateOperator dateOperator) { - return new BoolQuery.Builder() - .filter(convertDateOperator(field, - dateOperator.getType(), - DateTimeFormatter.ISO_OFFSET_DATE_TIME.format( - DateResolutionFormatter.computeLowerDate( - DateResolutionFormatter.convertDateToZonedDateTime(dateOperator.getDate()), - dateOperator.getDateResultion())), - DateTimeFormatter.ISO_OFFSET_DATE_TIME.format( - DateResolutionFormatter.computeUpperDate( - DateResolutionFormatter.convertDateToZonedDateTime(dateOperator.getDate()), - dateOperator.getDateResultion())))) - .build() - .toQuery(); - } - - private Query convertConjunction(SearchQuery.ConjunctionCriterion criterion) { - return convertToBoolQuery(criterion.getCriteria().stream().map(this::convertCriterion), - convertConjunctionType(criterion.getType())); - } - - private BiFunction<BoolQuery.Builder, Query, BoolQuery.Builder> convertConjunctionType(SearchQuery.Conjunction type) { - switch (type) { - case AND: - return BoolQuery.Builder::must; - case OR: - return BoolQuery.Builder::should; - case NOR: - return BoolQuery.Builder::mustNot; - default: - throw new RuntimeException("Unexpected conjunction criteria " + type); - } - } - - @SuppressWarnings("ReturnValueIgnored") - private Query convertToBoolQuery(Stream<Query> stream, BiFunction<BoolQuery.Builder, Query, BoolQuery.Builder> addCriterionToBoolQuery) { - BoolQuery.Builder builder = new BoolQuery.Builder(); - stream.forEach(query -> addCriterionToBoolQuery.apply(builder, query)); - return builder.build().toQuery(); - } - - private Query convertFlag(SearchQuery.FlagCriterion flagCriterion) { - SearchQuery.BooleanOperator operator = flagCriterion.getOperator(); - Flags.Flag flag = flagCriterion.getFlag(); - if (flag.equals(Flags.Flag.DELETED)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_DELETED) - .value(new FieldValue.Builder().booleanValue(operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - if (flag.equals(Flags.Flag.ANSWERED)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_ANSWERED) - .value(new FieldValue.Builder().booleanValue(operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - if (flag.equals(Flags.Flag.DRAFT)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_DRAFT) - .value(new FieldValue.Builder().booleanValue(operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - if (flag.equals(Flags.Flag.SEEN)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_UNREAD) - .value(new FieldValue.Builder().booleanValue(!operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - if (flag.equals(Flags.Flag.RECENT)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_RECENT) - .value(new FieldValue.Builder().booleanValue(operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - if (flag.equals(Flags.Flag.FLAGGED)) { - return new BoolQuery.Builder() - .filter(new TermQuery.Builder() - .field(JsonMessageConstants.IS_FLAGGED) - .value(new FieldValue.Builder().booleanValue(operator.isSet()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - throw new RuntimeException("Unknown flag used in Flag search criterion"); - } - - private Query createNumericFilter(String fieldName, SearchQuery.NumericOperator operator) { - switch (operator.getType()) { - case EQUALS: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .gte(JsonData.of(operator.getValue())) - .lte(JsonData.of(operator.getValue())) - .build() - .toQuery()) - .build() - .toQuery(); - case GREATER_THAN: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .gt(JsonData.of(operator.getValue())) - .build() - .toQuery()) - .build() - .toQuery(); - case LESS_THAN: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .lt(JsonData.of(operator.getValue())) - .build() - .toQuery()) - .build() - .toQuery(); - default: - throw new RuntimeException("A non existing numeric operator was triggered"); - } - } - - private Query convertUid(SearchQuery.UidCriterion uidCriterion) { - if (uidCriterion.getOperator().getRange().length == 0) { - return new BoolQuery.Builder().build().toQuery(); - } - return new BoolQuery.Builder() - .filter(convertToBoolQuery( - Arrays.stream(uidCriterion.getOperator().getRange()) - .map(this::uidRangeFilter), BoolQuery.Builder::should)) - .build() - .toQuery(); - } - - private Query convertMessageId(SearchQuery.MessageIdCriterion messageIdCriterion) { - return new TermQuery.Builder() - .field(JsonMessageConstants.MESSAGE_ID) - .value(new FieldValue.Builder().stringValue(messageIdCriterion.getMessageId().serialize()).build()) - .build() - .toQuery(); - } - - private Query uidRangeFilter(SearchQuery.UidRange numericRange) { - return new RangeQuery.Builder() - .field(JsonMessageConstants.UID) - .lte(JsonData.of(numericRange.getHighValue().asLong())) - .gte(JsonData.of(numericRange.getLowValue().asLong())) - .build() - .toQuery(); - } - - private Query convertHeader(SearchQuery.HeaderCriterion headerCriterion) { - return headerOperatorConverterMap.get(headerCriterion.getOperator().getClass()) - .apply( - headerCriterion.getHeaderName().toLowerCase(Locale.US), - headerCriterion.getOperator()); - } - - private Query convertSubject(SearchQuery.SubjectCriterion headerCriterion) { - if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(headerCriterion.getSubject())) { - return new QueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.SUBJECT)) - .query(headerCriterion.getSubject()) - .fuzziness(textFuzzinessSearchValue) - .build().toQuery(); - } else { - return new MatchQuery.Builder() - .field(JsonMessageConstants.SUBJECT) - .query(new FieldValue.Builder() - .stringValue(headerCriterion.getSubject()) - .build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery(); - } - } - - private Query manageAddressFields(String headerName, String value) { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.NAME) - .query(new FieldValue.Builder().stringValue(value).build()) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.ADDRESS) - .query(new FieldValue.Builder().stringValue(value).build()) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.DOMAIN) - .query(new FieldValue.Builder().stringValue(value).build()) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.ADDRESS + "." + RAW) - .query(new FieldValue.Builder().stringValue(value).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } - - private String getFieldNameFromHeaderName(String headerName) { - switch (headerName.toLowerCase(Locale.US)) { - case HeaderCollection.TO: - return JsonMessageConstants.TO; - case HeaderCollection.CC: - return JsonMessageConstants.CC; - case HeaderCollection.BCC: - return JsonMessageConstants.BCC; - case HeaderCollection.FROM: - return JsonMessageConstants.FROM; - default: - throw new RuntimeException("Header not recognized as Addess Header : " + headerName); - } - } - - private Query convertDateOperator(String field, SearchQuery.DateComparator dateComparator, String lowDateString, String upDateString) { - switch (dateComparator) { - case BEFORE: - return new RangeQuery.Builder() - .field(field) - .lt(JsonData.of(lowDateString)) - .build() - .toQuery(); - case AFTER: - return new RangeQuery.Builder() - .field(field) - .gte(JsonData.of(upDateString)) - .build() - .toQuery(); - case ON: - return new RangeQuery.Builder() - .field(field) - .lt(JsonData.of(upDateString)) - .gte(JsonData.of(lowDateString)) - .build() - .toQuery(); - default: - throw new RuntimeException("Unknown date operator"); - } - } +public interface CriterionConverter { + Query convertCriterion(Criterion criterion); } diff --git a/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java b/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/DefaultCriterionConverter.java similarity index 69% copy from mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java copy to mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/DefaultCriterionConverter.java index 3753da0e32..f572aa04ff 100644 --- a/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java +++ b/mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/DefaultCriterionConverter.java @@ -35,8 +35,6 @@ import jakarta.inject.Inject; import jakarta.mail.Flags; import org.apache.james.mailbox.model.SearchQuery; -import org.apache.james.mailbox.model.SearchQuery.Criterion; -import org.apache.james.mailbox.model.SearchQuery.HeaderOperator; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.json.JsonMessageConstants; import org.apache.james.mailbox.store.search.mime.HeaderCollection; @@ -58,27 +56,26 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableList; -public class CriterionConverter { - +public class DefaultCriterionConverter implements CriterionConverter { public static final CharMatcher QUERY_STRING_CONTROL_CHAR = CharMatcher.anyOf("()\"~-|*"); - private final Map<Class<?>, Function<Criterion, Query>> criterionConverterMap; - private final Map<Class<?>, BiFunction<String, HeaderOperator, Query>> headerOperatorConverterMap; + private final Map<Class<?>, Function<SearchQuery.Criterion, Query>> criterionConverterMap; + private final Map<Class<?>, BiFunction<String, SearchQuery.HeaderOperator, Query>> headerOperatorConverterMap; private final String textFuzzinessSearchValue; private final boolean useQueryStringQuery; @Inject - public CriterionConverter(OpenSearchMailboxConfiguration openSearchMailboxConfiguration) { + public DefaultCriterionConverter(OpenSearchMailboxConfiguration openSearchMailboxConfiguration) { this.criterionConverterMap = new HashMap<>(); this.headerOperatorConverterMap = new HashMap<>(); this.textFuzzinessSearchValue = evaluateFuzzinessValue(openSearchMailboxConfiguration.textFuzzinessSearchEnable()); this.useQueryStringQuery = openSearchMailboxConfiguration.isUseQueryStringQuery(); - + registerCriterionConverters(); registerHeaderOperatorConverters(); } @VisibleForTesting - public CriterionConverter() { + public DefaultCriterionConverter() { this.criterionConverterMap = new HashMap<>(); this.headerOperatorConverterMap = new HashMap<>(); this.textFuzzinessSearchValue = evaluateFuzzinessValue(DEFAULT_TEXT_FUZZINESS_SEARCH); @@ -104,13 +101,13 @@ public class CriterionConverter { registerCriterionConverter(SearchQuery.SubjectCriterion.class, this::convertSubject); registerCriterionConverter(SearchQuery.TextCriterion.class, this::convertTextCriterion); registerCriterionConverter(SearchQuery.CustomFlagCriterion.class, this::convertCustomFlagCriterion); - + registerCriterionConverter(SearchQuery.AllCriterion.class, criterion -> new MatchAllQuery.Builder().build().toQuery()); - + registerCriterionConverter(SearchQuery.ModSeqCriterion.class, criterion -> createNumericFilter(JsonMessageConstants.MODSEQ, criterion.getOperator())); - + registerCriterionConverter(SearchQuery.SizeCriterion.class, criterion -> createNumericFilter(JsonMessageConstants.SIZE, criterion.getOperator())); @@ -124,12 +121,12 @@ public class CriterionConverter { registerCriterionConverter(SearchQuery.MimeMessageIDCriterion.class, this::convertMimeMessageIDCriterion); registerCriterionConverter(SearchQuery.ThreadIdCriterion.class, this::convertThreadIdCriterion); } - + @SuppressWarnings("unchecked") - private <T extends Criterion> void registerCriterionConverter(Class<T> type, Function<T, Query> f) { - criterionConverterMap.put(type, (Function<Criterion, Query>) f); + private <T extends SearchQuery.Criterion> void registerCriterionConverter(Class<T> type, Function<T, Query> f) { + criterionConverterMap.put(type, (Function<SearchQuery.Criterion, Query>) f); } - + private void registerHeaderOperatorConverters() { registerHeaderOperatorConverter( SearchQuery.ExistsOperator.class, @@ -143,15 +140,15 @@ public class CriterionConverter { .scoreMode(ChildScoreMode.Avg) .build() .toQuery()); - + registerHeaderOperatorConverter( SearchQuery.AddressOperator.class, (headerName, operator) -> manageAddressFields(headerName, operator.getAddress())); - + registerHeaderOperatorConverter( SearchQuery.DateOperator.class, (headerName, operator) -> dateRangeFilter(JsonMessageConstants.SENT_DATE, operator)); - + registerHeaderOperatorConverter( SearchQuery.ContainsOperator.class, (headerName, operator) -> new NestedQuery.Builder() @@ -175,11 +172,11 @@ public class CriterionConverter { } @SuppressWarnings("unchecked") - private <T extends HeaderOperator> void registerHeaderOperatorConverter(Class<T> type, BiFunction<String, T, Query> f) { - headerOperatorConverterMap.put(type, (BiFunction<String, HeaderOperator, Query>) f); + private <T extends SearchQuery.HeaderOperator> void registerHeaderOperatorConverter(Class<T> type, BiFunction<String, T, Query> f) { + headerOperatorConverterMap.put(type, (BiFunction<String, SearchQuery.HeaderOperator, Query>) f); } - public Query convertCriterion(Criterion criterion) { + public Query convertCriterion(SearchQuery.Criterion criterion) { return criterionConverterMap.get(criterion.getClass()).apply(criterion); } @@ -225,94 +222,111 @@ public class CriterionConverter { private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) { switch (textCriterion.getType()) { - case BODY: - if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { - return new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY)) - .query(textCriterion.getOperator().getValue()) - .build().toQuery(); - } else { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.TEXT_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.HTML_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .build() - .toQuery(); - } - case FULL: - if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { - return new BoolQuery.Builder() - .should(new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY, JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) + case BODY: + if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { + return new SimpleQueryStringQuery.Builder() + .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY)) .query(textCriterion.getOperator().getValue()) - .build().toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .build().toQuery(); + } else { + return new BoolQuery.Builder() + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.TEXT_BODY) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.HTML_BODY) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) .build() - .toQuery()) - .build() - .toQuery(); - } else { - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.TEXT_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) + .toQuery(); + } + case FULL: + if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) { + return new BoolQuery.Builder() + .should(new SimpleQueryStringQuery.Builder() + .fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY, JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) + .query(textCriterion.getOperator().getValue()) + .build().toQuery()) + .should(new TermQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) + .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .build() + .toQuery()) .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.HTML_BODY) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) + .toQuery(); + } else { + return new BoolQuery.Builder() + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.TEXT_BODY) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.HTML_BODY) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) + .should(new TermQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) + .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .build() + .toQuery()) .build() - .toQuery()) - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) + .toQuery(); + } + case ATTACHMENTS: + if (useQueryStringQuery) { + return new BoolQuery.Builder() + .should(new SimpleQueryStringQuery.Builder() + .fields(ImmutableList.of(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) + .query(textCriterion.getOperator().getValue()) + .build().toQuery()) + .should(new TermQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) + .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .build() + .toQuery()) .build() - .toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .toQuery(); + } else { + return new BoolQuery.Builder() + .should(new MatchQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) + .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .fuzziness(textFuzzinessSearchValue) + .operator(Operator.And) + .build() + .toQuery()) + .should(new TermQuery.Builder() + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) + .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) + .build() + .toQuery()) .build() - .toQuery()) - .build() - .toQuery(); - } - case ATTACHMENTS: - if (useQueryStringQuery) { - return new BoolQuery.Builder() - .should(new SimpleQueryStringQuery.Builder() - .fields(ImmutableList.of(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT)) - .query(textCriterion.getOperator().getValue()) - .build().toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - } else { + .toQuery(); + } + case ATTACHMENT_FILE_NAME: return new BoolQuery.Builder() .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT) + .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILENAME) .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) .fuzziness(textFuzzinessSearchValue) .operator(Operator.And) @@ -325,25 +339,8 @@ public class CriterionConverter { .toQuery()) .build() .toQuery(); - } - case ATTACHMENT_FILE_NAME: - return new BoolQuery.Builder() - .should(new MatchQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILENAME) - .query(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .fuzziness(textFuzzinessSearchValue) - .operator(Operator.And) - .build() - .toQuery()) - .should(new TermQuery.Builder() - .field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION) - .value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build()) - .build() - .toQuery()) - .build() - .toQuery(); - default: - throw new RuntimeException("Unknown SCOPE for text criterion"); + default: + throw new RuntimeException("Unknown SCOPE for text criterion"); } } @@ -456,36 +453,36 @@ public class CriterionConverter { private Query createNumericFilter(String fieldName, SearchQuery.NumericOperator operator) { switch (operator.getType()) { - case EQUALS: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .gte(JsonData.of(operator.getValue())) - .lte(JsonData.of(operator.getValue())) + case EQUALS: + return new BoolQuery.Builder() + .filter(new RangeQuery.Builder() + .field(fieldName) + .gte(JsonData.of(operator.getValue())) + .lte(JsonData.of(operator.getValue())) + .build() + .toQuery()) .build() - .toQuery()) - .build() - .toQuery(); - case GREATER_THAN: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .gt(JsonData.of(operator.getValue())) + .toQuery(); + case GREATER_THAN: + return new BoolQuery.Builder() + .filter(new RangeQuery.Builder() + .field(fieldName) + .gt(JsonData.of(operator.getValue())) + .build() + .toQuery()) .build() - .toQuery()) - .build() - .toQuery(); - case LESS_THAN: - return new BoolQuery.Builder() - .filter(new RangeQuery.Builder() - .field(fieldName) - .lt(JsonData.of(operator.getValue())) + .toQuery(); + case LESS_THAN: + return new BoolQuery.Builder() + .filter(new RangeQuery.Builder() + .field(fieldName) + .lt(JsonData.of(operator.getValue())) + .build() + .toQuery()) .build() - .toQuery()) - .build() - .toQuery(); - default: - throw new RuntimeException("A non existing numeric operator was triggered"); + .toQuery(); + default: + throw new RuntimeException("A non existing numeric operator was triggered"); } } @@ -573,43 +570,42 @@ public class CriterionConverter { private String getFieldNameFromHeaderName(String headerName) { switch (headerName.toLowerCase(Locale.US)) { - case HeaderCollection.TO: - return JsonMessageConstants.TO; - case HeaderCollection.CC: - return JsonMessageConstants.CC; - case HeaderCollection.BCC: - return JsonMessageConstants.BCC; - case HeaderCollection.FROM: - return JsonMessageConstants.FROM; - default: - throw new RuntimeException("Header not recognized as Addess Header : " + headerName); + case HeaderCollection.TO: + return JsonMessageConstants.TO; + case HeaderCollection.CC: + return JsonMessageConstants.CC; + case HeaderCollection.BCC: + return JsonMessageConstants.BCC; + case HeaderCollection.FROM: + return JsonMessageConstants.FROM; + default: + throw new RuntimeException("Header not recognized as Addess Header : " + headerName); } } private Query convertDateOperator(String field, SearchQuery.DateComparator dateComparator, String lowDateString, String upDateString) { switch (dateComparator) { - case BEFORE: - return new RangeQuery.Builder() - .field(field) - .lt(JsonData.of(lowDateString)) - .build() - .toQuery(); - case AFTER: - return new RangeQuery.Builder() - .field(field) - .gte(JsonData.of(upDateString)) - .build() - .toQuery(); - case ON: - return new RangeQuery.Builder() - .field(field) - .lt(JsonData.of(upDateString)) - .gte(JsonData.of(lowDateString)) - .build() - .toQuery(); - default: - throw new RuntimeException("Unknown date operator"); + case BEFORE: + return new RangeQuery.Builder() + .field(field) + .lt(JsonData.of(lowDateString)) + .build() + .toQuery(); + case AFTER: + return new RangeQuery.Builder() + .field(field) + .gte(JsonData.of(upDateString)) + .build() + .toQuery(); + case ON: + return new RangeQuery.Builder() + .field(field) + .lt(JsonData.of(upDateString)) + .gte(JsonData.of(lowDateString)) + .build() + .toQuery(); + default: + throw new RuntimeException("Unknown date operator"); } } - } diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchIntegrationTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchIntegrationTest.java index 88e35dbbc5..d44a2b8ba6 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchIntegrationTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchIntegrationTest.java @@ -50,7 +50,7 @@ import org.apache.james.mailbox.model.MultimailboxesSearchQuery; import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest; @@ -92,7 +92,7 @@ class OpenSearchIntegrationTest extends AbstractMessageSearchIndexTest { .and().pollDelay(ONE_HUNDRED_MILLISECONDS) .await(); static final int SEARCH_SIZE = 1; - private final QueryConverter queryConverter = new QueryConverter(new CriterionConverter()); + private final QueryConverter queryConverter = new QueryConverter(new DefaultCriterionConverter(openSearchMailboxConfiguration())); @RegisterExtension static TikaExtension tika = new TikaExtension(); @@ -159,7 +159,7 @@ class OpenSearchIntegrationTest extends AbstractMessageSearchIndexTest { ImmutableSet.of(), new OpenSearchIndexer(client, writeAliasName), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter(openSearchMailboxConfiguration())), SEARCH_SIZE, + new OpenSearchSearcher(client, queryConverter, SEARCH_SIZE, readAliasName, routingKeyFactory), new MessageToOpenSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchNoIndexBodyIntegrationTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchNoIndexBodyIntegrationTest.java index e2db6f76bd..2e07e7282c 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchNoIndexBodyIntegrationTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchNoIndexBodyIntegrationTest.java @@ -45,7 +45,7 @@ import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.StoreMessageManager; @@ -123,7 +123,7 @@ class OpenSearchNoIndexBodyIntegrationTest { preInstanciationStage.getMapperFactory(), ImmutableSet.of(), new OpenSearchIndexer(client, writeAliasName), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, readAliasName, routingKeyFactory), + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter()), SEARCH_SIZE, readAliasName, routingKeyFactory), new MessageToOpenSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES, IndexBody.NO), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, OpenSearchMailboxConfiguration.builder().indexBody(IndexBody.NO).build(), new RecordingMetricFactory(), diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchQueryStringTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchQueryStringTest.java index 7ca9e8bb82..e73cc4fc8d 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchQueryStringTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchQueryStringTest.java @@ -45,7 +45,7 @@ import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.StoreMessageManager; @@ -127,7 +127,7 @@ class OpenSearchQueryStringTest { preInstanciationStage.getMapperFactory(), ImmutableSet.of(), new OpenSearchIndexer(client, writeAliasName), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter(openSearchMailboxConfiguration)), SEARCH_SIZE, readAliasName, routingKeyFactory), + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter(openSearchMailboxConfiguration)), SEARCH_SIZE, readAliasName, routingKeyFactory), new MessageToOpenSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES, IndexBody.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, openSearchMailboxConfiguration, new RecordingMetricFactory(), diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java index 8cb36cff17..1a7f4ad3b3 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/events/OpenSearchListeningMessageSearchIndexTest.java @@ -77,7 +77,7 @@ import org.apache.james.mailbox.opensearch.MailboxIndexCreationUtil; import org.apache.james.mailbox.opensearch.MailboxOpenSearchConstants; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.FakeAuthenticator; @@ -219,7 +219,7 @@ class OpenSearchListeningMessageSearchIndexTest { openSearch.getDockerOpenSearch().configuration()); openSearchSearcher = new OpenSearchSearcher(client, - new QueryConverter(new CriterionConverter()), + new QueryConverter(new DefaultCriterionConverter()), OpenSearchSearcher.DEFAULT_SEARCH_SIZE, MailboxOpenSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, new MailboxIdRoutingKeyFactory()); diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearchHighlighterTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearchHighlighterTest.java index 9c81a9bb45..f2646371a5 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearchHighlighterTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearchHighlighterTest.java @@ -52,7 +52,7 @@ import org.apache.james.mailbox.opensearch.MailboxIndexCreationUtil; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.searchhighligt.SearchHighLighterContract; import org.apache.james.mailbox.searchhighligt.SearchHighlighter; @@ -126,7 +126,7 @@ public class OpenSearchSearchHighlighterTest implements SearchHighLighterContrac .build(); final MessageId.Factory messageIdFactory = new InMemoryMessageId.Factory(); - OpenSearchSearcher openSearchSearcher = new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter(openSearchMailboxConfiguration)), SEARCH_SIZE, + OpenSearchSearcher openSearchSearcher = new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter(openSearchMailboxConfiguration)), SEARCH_SIZE, readAliasName, routingKeyFactory); InMemoryIntegrationResources resources = InMemoryIntegrationResources.builder() diff --git a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearcherTest.java b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearcherTest.java index 21cd6fad8b..eb89876a7f 100644 --- a/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearcherTest.java +++ b/mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/search/OpenSearchSearcherTest.java @@ -56,7 +56,7 @@ import org.apache.james.mailbox.opensearch.MailboxIndexCreationUtil; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.tika.TikaConfiguration; import org.apache.james.mailbox.tika.TikaExtension; @@ -130,7 +130,7 @@ class OpenSearchSearcherTest { preInstanciationStage.getMapperFactory(), ImmutableSet.of(), new OpenSearchIndexer(client, writeAliasName), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, readAliasName, routingKeyFactory), + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter()), SEARCH_SIZE, readAliasName, routingKeyFactory), new MessageToOpenSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, OpenSearchMailboxConfiguration.builder().build(), new RecordingMetricFactory(), diff --git a/mpt/impl/imap-mailbox/opensearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/OpenSearchHostSystem.java b/mpt/impl/imap-mailbox/opensearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/OpenSearchHostSystem.java index 2a161caf37..acfaec04c6 100644 --- a/mpt/impl/imap-mailbox/opensearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/OpenSearchHostSystem.java +++ b/mpt/impl/imap-mailbox/opensearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/OpenSearchHostSystem.java @@ -45,7 +45,7 @@ import org.apache.james.mailbox.opensearch.MailboxOpenSearchConstants; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.StoreMailboxManager; @@ -104,7 +104,7 @@ public class OpenSearchHostSystem extends JamesImapHostSystem { ImmutableSet.of(), new OpenSearchIndexer(client, MailboxOpenSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter()), OpenSearchSearcher.DEFAULT_SEARCH_SIZE, + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter()), OpenSearchSearcher.DEFAULT_SEARCH_SIZE, MailboxOpenSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory), new MessageToOpenSearchJson(new DefaultTextExtractor(), ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, diff --git a/server/container/guice/opensearch/src/main/java/org/apache/james/modules/mailbox/OpenSearchMailboxMappingModule.java b/server/container/guice/opensearch/src/main/java/org/apache/james/modules/mailbox/OpenSearchMailboxMappingModule.java index 9c527394a2..aa8d720cb5 100644 --- a/server/container/guice/opensearch/src/main/java/org/apache/james/modules/mailbox/OpenSearchMailboxMappingModule.java +++ b/server/container/guice/opensearch/src/main/java/org/apache/james/modules/mailbox/OpenSearchMailboxMappingModule.java @@ -21,6 +21,8 @@ package org.apache.james.modules.mailbox; import org.apache.james.mailbox.opensearch.DefaultMailboxMappingFactory; import org.apache.james.mailbox.opensearch.MailboxMappingFactory; +import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import com.google.inject.AbstractModule; import com.google.inject.Scopes; @@ -30,5 +32,8 @@ public class OpenSearchMailboxMappingModule extends AbstractModule { protected void configure() { bind(DefaultMailboxMappingFactory.class).in(Scopes.SINGLETON); bind(MailboxMappingFactory.class).to(DefaultMailboxMappingFactory.class); + + bind(DefaultCriterionConverter.class).in(Scopes.SINGLETON); + bind(CriterionConverter.class).to(DefaultCriterionConverter.class); } } diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedThreadGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedThreadGetMethodTest.java index 58e6e1476f..6796723093 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedThreadGetMethodTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedThreadGetMethodTest.java @@ -38,7 +38,7 @@ import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.SearchQuery; import org.apache.james.mailbox.opensearch.MailboxIndexCreationUtil; import org.apache.james.mailbox.opensearch.MailboxOpenSearchConstants; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.modules.AwsS3BlobStoreExtension; import org.apache.james.modules.RabbitMQExtension; @@ -58,7 +58,7 @@ public class DistributedThreadGetMethodTest implements ThreadGetContract { .and().pollDelay(ONE_HUNDRED_MILLISECONDS) .await(); - private final QueryConverter queryConverter = new QueryConverter(new CriterionConverter()); + private final QueryConverter queryConverter = new QueryConverter(new DefaultCriterionConverter()); private ReactorOpenSearchClient client; @RegisterExtension diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java index 6d196d9f77..bfab64537a 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java @@ -74,7 +74,7 @@ import org.apache.james.mailbox.opensearch.MailboxOpenSearchConstants; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.extractor.DefaultTextExtractor; @@ -162,7 +162,7 @@ class MailboxesRoutesTest { ImmutableSet.of(), new OpenSearchIndexer(client, MailboxOpenSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter()), SEARCH_SIZE, MailboxOpenSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory), new MessageToOpenSearchJson(new DefaultTextExtractor(), ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, OpenSearchMailboxConfiguration.builder().build(), new RecordingMetricFactory(), diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java index 591aa330fe..7e5c8595d8 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java @@ -98,7 +98,7 @@ import org.apache.james.mailbox.opensearch.MailboxOpenSearchConstants; import org.apache.james.mailbox.opensearch.OpenSearchMailboxConfiguration; import org.apache.james.mailbox.opensearch.events.OpenSearchListeningMessageSearchIndex; import org.apache.james.mailbox.opensearch.json.MessageToOpenSearchJson; -import org.apache.james.mailbox.opensearch.query.CriterionConverter; +import org.apache.james.mailbox.opensearch.query.DefaultCriterionConverter; import org.apache.james.mailbox.opensearch.query.QueryConverter; import org.apache.james.mailbox.opensearch.search.OpenSearchSearcher; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; @@ -1518,7 +1518,7 @@ class UserMailboxesRoutesTest { ImmutableSet.of(), new OpenSearchIndexer(client, MailboxOpenSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS), - new OpenSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, + new OpenSearchSearcher(client, new QueryConverter(new DefaultCriterionConverter()), SEARCH_SIZE, MailboxOpenSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory), new MessageToOpenSearchJson(new DefaultTextExtractor(), ZoneId.of("Europe/Paris"), IndexAttachments.YES, IndexHeaders.YES), preInstanciationStage.getSessionProvider(), routingKeyFactory, messageIdFactory, OpenSearchMailboxConfiguration.builder().build(), new RecordingMetricFactory(), --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org